返したいデータの階層データ構造を定義する、ネストされた Bean のセットを作成します。 ResultSet オブジェクトの列に適合する Bean プロパティーに対する @JoinPoint アノテーションを指定すると、pureQuery Runtime が適切な実装を生成します。 pureQuery Runtime はトップレベル Bean (ResultSet オブジェクトとネストされた Bean の処理後に返される Bean) の階層構造を分析します。 生成されてデータが追加される Bean/Bean リストは、ResultSet オブジェクトの列によって更新される、@JoinPoint アノテーションを持つ Bean/Bean リストのみです。 ResultSet オブジェクトの列によってデータが追加されない Bean/Bean リストや、@JoinPoint アノテーションを持たない Bean/Bean リストはいずれも、 ヌルになるか、または Bean コンストラクター初期設定値になります。
次の例では、2 つの Bean が示されています。 トップレベル Bean は Department Bean です。 子 Bean は Employee Bean のリストです。
Select D.DEPTNO, D.DEPTNAME, D.MGRNO, D.ADMRDEPT, E.EMPNO, E.FIRSTNME, E.MIDINIT,
E.LASTNAME, E.JOB, E.SEX, E.BIRTHDATE, E.SALARY
from (DEPARTMENT AS D LEFT JOIN EMPLOYEE AS E ON D.DEPTNO=E.WORKDEPT)
WHERE D.DEPTNO=? ORDER BY D.DEPTNO, E.LASTNAME
@Select(sql = "Select D.DEPTNO, D.DEPTNAME, D.MGRNO, D.ADMRDEPT, E.EMPNO,
E.FIRSTNME, E.MIDINIT, E.LASTNAME, E.JOB, E.SEX, E.BIRTHDATE, E.SALARY
from (DEPARTMENT AS D LEFT JOIN EMPLOYEE AS E ON D.DEPTNO=E.WORKDEPT)
WHERE D.DEPTNO=? ORDER BY D.DEPTNO, E.LASTNAME")
public Department joinTest (String deptNo);
@Table(name = "DEPARTMENT")
public class Department
{
@Id
@GeneratedKey
public String deptNo; // this is the ID of the bean and its value is generated by the database
public String deptName;
public String mgrNo;
public String admrDept;
@JoinPoint(@JoinColumn(name = "EMPNO", table = "EMPLOYEE", propertyName = "empNo"))
public List<Employee> deptEmployees;
}
@Table(name = "EMPLOYEE")
public class Employee
{
@Id
@GeneratedKey
public String empNo; // this is the ID of the bean and its value is generated by the database
public String firstNme;
public String midInit;
public String lastName;
public String workDept;
public String job;
public String sex;
public java.sql.Date birthdate;
public String salary;
}
SQL 照会と Bean に基づき、pureQuery Runtime は Bean の実装コードを生成します。
返される Java オブジェクトは、11 個の deptEmployees Bean からなる java.util.list を 含む 1 つの Department Beanです。
dept admr mid
No deptName mgrNo Dept empNo firstNme Init lastName job sex birthdate salary
D11 MANUFACTURING SYSTEMS 000060 D01 000150 BRUCE ADAMSON DESIGNER M 1977-05-17 55280.00
000200 DAVID BROWN DESIGNER M 1971-05-29 57740.00
200220 REBA K JOHN DESIGNER F 1978-03-19 69840.00
000210 WILLIAM T JONES DESIGNER M 2003-02-23 68270.00
000220 JENNIFER K LUTZ DESIGNER F 1978-03-19 49840.00
000160 ELIZABETH R PIANKA DESIGNER F 1980-04-12 62250.00
000180 MARILYN S SCOUTTEN DESIGNER F 1979-02-21 51340.00
000060 IRVING F STERN MANAGER M 1975-07-07 72250.00
000190 JAMES H WALKER DESIGNER M 1982-06-25 50450.00
200170 KIYOSHI YAMAMOTO DESIGNER M 1981-01-05 64680.00
000170 MASATOSHI J YOSHIMURA DESIGNER M 1981-01-05 44680.00
pureQuery Runtime は、ネストされた Bean のセットを生成して、 そのセットにデータを追加するときに、Bean の親に属する Bean に対する参照に含まれる @JoinPoint アノテーションを使用するか、 またはその Bean 自体に含まれる @Id アノテーションを使用します。 このアノテーションは、親 Bean に 子 Bean をリンクする ID 列を定義します。 例えば、pureQuery Runtime は ID 列を使用して、親 Bean の Bean リストをいつ生成するのかを決定します。
例えば、EMPLOYEE 表に、ID 列になることができる列が複数含まれているとします。 ID 列として定義できる列は従業員番号および従業員社会保障番号の列です。 ID 列は表の主キーにできますが、表のキーである必要はありません。 データベース表で複合キーを作成できるように、複数の列を組み合わせて 1 つの複合キーにすることができます。 EMPLOYEE 表の ID 列として名前の列を選択することはお勧めできません。 同じ名前の従業員が複数存在する可能性があるためです。
pureQuery Runtime を使用すれば、正しいデータのセットが正しい順序で Bean に追加されます。 例えば、ResultSet データがソートされていないため、ネストされた Bean の構造に正確にマップされない可能性があります。 pureQuery Runtime は、以前の ResultSet の処理時に作成された Bean に含まれている ResultSet データを処理し、 適切なデータを正しい順序で Bean に追加できます。
複雑な結合述部を持つ SQL ステートメントから結果を返すネストされた Bean のセットを作成するには、適切なアノテーションを使用して、より複雑なネスト構造を作成します。 正しい結果を返す Bean のセットを作成するには、次の規則に従う必要があります。 有用な Bean のセットを生成するには、SQL 照会または Bean を変更しなければならない場合があります。
この問題は、SQL 照会で別名を指定することによって解決できます。 複数の列を持つ Bean 内のプロパティー上の「表名」を使用して、@Column、@Table、または @JoinColumn アノテーションを指定することもできます。
基本プロパティー名 は Bean プロパティーの名前ですが、 この Bean プロパティーでは、ResultSet オブジェクトへのこの Bean プロパティーのマッピングを変更するような既存のアノテーションは使用されません。 フィールドに対しては、基本プロパティー名は Java 変数名です。 get メソッド、set メソッド、または is メソッドに対しては、 基本プロパティー名は、get、set、is のいずれの接頭部も持たない メソッド名です (最初の文字は小文字に設定されます)。 次の例の ResultSet 列ラベル WORKDEPT には大/小文字の区別はありません。
@Column (name = "WORKDEPT")
public String getWorkDepartment ();
@JoinColumn アノテーションは、Bean/Bean リスト上の @JoinPoint アノテーションの内側に指定できます。 その場合、指定された name エレメントと table エレメントは、 子 Bean の @Id アノテーション (および関連 @Column アノテーションが指定されている場合はそのすべての関連 @Column アノテーション) で定義されている 列ラベルとオプションの表名をオーバーライドします。
1 つの子 Bean に複数の @Id アノテーションを指定できます。 その場合、@JoinColumn アノテーション必須エレメント name は、子 Bean における基本プロパティー名と一致しなければなりません。 名前が一致しない場合は、子 Bean において一致する基本プロパティーの名前を使用して オプション・エレメント propertyName を指定する必要があります。
@JoinPoint(@JoinColumn(name = "EMPNO", table = "EMPLOYEE", propertyName = "empNo"))
public List<Employee> deptEmployees;
@JoinPoint(@JoinColumn(name = "EMPNUM", table = "EMPLOYEE", propertyName = "empNo"))
public List<Employee> deptEmployees;
@JoinPoint(@JoinColumn(name = "WORKDEPT", table = "EMPLOYEE", propertyName = "workDept"))
public List<Employee> deptEmployees;
子 Bean は単一 Bean または Bean リストでなければなりません。 また、子 Bean には @JoinPoint アノテーションが必要です。 @JoinPoint アノテーションは、子 Bean/Bean リストを定義する親 Bean プロパティー上になければなりません。
このマッピングの例として、DEPARTMENT 表 (主キーとなる DEPTNO 列がある) と PROJECT 表 (この表にも DEPTNO 列がある) があります。 PROJECT 表の DEPTNO 列は、DEPARTMENT 表の外部キーです。 ResultSet オブジェクトにおける列と、プロパティーとの間でデフォルトで一致するのは、この列ラベルです。 この例では、DEPARTMENT 表と PROJECT 表を結合した結果、DEPTNO という列ラベルを持つ列が 2 つ作成されることになります。 親と子の Bean 構造でこれらの列に別々の情報が必要な場合は、これらの Bean にアノテーションを追加できます。 このアノテーションでは、表名を使用して列を固有にすることができます。 また、別名を追加して固有の列ラベルを作成することで、SQL ステートメントを変更することもできます。 ただし、通常、SQL 照会では、複数の列に同一データが含まれる場合は、結合を使用して列を 1 つのみ返すようにします。 この場合、1 つの列で複数のプロパティーを変更できます。
インライン・メソッド・スタイルでは、同じ ResultSet 列によって複数のプロパティーが更新されているという警告が出力されます。 pureQuery Runtime ログ・ファイルが存在し、トレース・レベルが java.util.logging.Level.WARNING またはより詳細なレベルに設定されている場合、 この警告は pureQuery Runtime ログ・ファイルに記録されます。
元の親 Bean の子 Bean がすべて処理されてから、すべての子 Bean が処理されて、その子 Bean にさらに子 Bean があるかどうかが判別されます。
pureQuery Runtime は、子 Bean クラスが初めて処理されるのか、または Bean に再帰的参照が含まれているのかを判別できます。 ネストされた Bean 構造を pureQuery Runtime が解析したときに、その構造に含まれる Bean が既に解析済みであることが判明すると、pureQuery Runtime は その子 Bean の解析を停止します。
また、Bean に対する再帰的参照は、pureQuery Runtime が子 Bean のプロパティーにデータを追加する方法にも影響します。 データが追加されるのは、Bean の最初のインスタンスのみです。 その Bean に対する後続の参照は、別の columnPrefix エレメントが定義されている @JoinColumn アノテーションがその参照に含まれていない限り 無視されます。 単一 Bean 内のプロパティーの処理順序は決まっていないため、その子 Bean の処理順序も決まっていません。 ただし、子 Bean はネストのレベル順に処理されます。 例えば、親 Bean に直接ネストされている Bean は、次のネスト・レベルにある Bean より前に処理されます。
columnPrefix エレメントについては、@JoinPoint アノテーション資料を参照してください。