Créez un ensemble de beans imbriqués définissant la structure hiérarchique des données à renvoyer. Lorsque vous spécifiez une annotation @JoinPoint dans la propriété d'un bean correspondant à la colonne d'un objet ResultSet, pureQuery Runtime génère l'implémentation adéquate. pureQuery Runtime analyse la structure hiérarchique du bean de niveau supérieur, qui correspond au bean renvoyé après avoir terminé le traitement de l'objet ResultSet et des beans imbriqués. Seuls ces beans ou listes de beans mis à jour par la colonne d'un objet ResultSet et disposant d'une annotation @JoinPoint sont générés et complétés. Tout bean ou liste de beans qui n'est pas complété(e) par la colonne d'un objet ResultSet ou qui ne dispose d'aucune annotation @JoinPoint affiche la valeur null ou une valeur d'initialisation du constructeur de beans.
Voici un exemple montrant deux beans, le bean de niveau supérieur correspond à un bean Department et les beans enfant correspondent à une liste des beans Employee.
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;
}
En fonction de la requête SQL et des beans, pureQuery Runtime génère un code d'implémentation pour les beans.
Les objets Java renvoyés correspondent à un bean Department contenant une liste java.util.list de 11 beans deptEmployees.
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
Lors de la génération et du remplissage d'un ensemble de beans imbriqués, pureQuery Runtime utilise l'annotation @JoinPoint dans la référence au bean figurant dans le parent du bean ou une annotation @Id dans le bean même. Les annotations définissent les colonnes d'identité qui lient les beans enfant au bean parent. Par exemple, pureQuery Runtime utilise des colonnes d'identité pour déterminer le moment auquel une liste de beans doit être générée pour un bean parent.
Par exemple, une table EMPLOYEE peut contenir plusieurs colonnes pouvant être des colonnes d'identité. Les colonnes qui peuvent être définies comme colonne d'identité sont le matricule ou le numéro de sécurité sociale de l'employé. La colonne d'identité peut être la clé principale de la table, mais pas nécessairement une clé de table. Plusieurs colonnes peuvent être combinées dans une clé composée, tout comme une clé composée peut être créée sur une table de base de données. Le nom d'une colonne d'identité de la table EMPLOYEE peut refléter un mauvais choix, étant donné que les employés peuvent porter le même nom.
pureQuery Runtime vérifie que les beans sont renseignés avec l'ensemble de données correctes et dans l'ordre adéquat. Par exemple, les données ResultSet peuvent ne pas être triées pour effectuer un mappage exact vers la structure de beans imbriqués. pureQuery Runtime peut traiter des données ResultSet appartenant aux beans qui ont été créés antérieurement lors du traitement des données ResultSet et renseigner les beans avec les données adéquates dans l'ordre correct.
Vous pouvez créer un ensemble de beans imbriqués renvoyant des résultats issus d'instructions SQL avec des prédicats de jointure complexes en créant une structure d'imbrication plus complexe avec les annotations adéquates. Pour créer un ensemble de beans renvoyant des résultats corrects, les règles suivantes doivent être suivies. La requête SQL ou les beans peuvent exiger des modifications afin de générer un ensemble de beans utiles.
Ce problème peut être résolu en spécifiant des alias dans la requête SQL. Les annotations @Column, @Table ou @JoinColumn peuvent aussi être spécifiées avec le nom de table dans les propriétés des beans disposant de plusieurs colonnes.
Le nom de la propriété de base correspond au nom de la propriété d'un bean sans annotation existante qui modifie son mappage vers l'objet ResultSet. Pour une zone, le nom de la propriété de base correspond au nom de la variable Java. Pour une méthode get, set ou is, il s'agit du nom de la méthode sans le préfixe get, set ou is et le premier caractère défini en minuscules. Dans les exemples suivants, l'étiquette WORKDEPT de la colonne ResultSet n'est pas sensible à la casse.
@Column(name = "WORKDEPT")
public String getWorkDepartment ();
Une annotation @JoinColumn peut être spécifiée dans une annotation @JoinPoint sur un bean ou une liste de beans. Dans ce cas, les éléments name et table spécifiés écrasent le libellé de colonne et le nom de table facultatif définis dans les annotations @Id du bean enfant, y compris toute annotation @Column associée qui est spécifiée.
Un bean enfant peut disposer de plusieurs annotations @Id. Dans ce cas, l'élément requis name de l'annotation @JoinColumn doit correspondre au nom de la propriété de base du bean enfant. Si les noms ne correspondent pas, alors l'élément facultatif propertyName doit être spécifié avec le nom de la propriété de base correspondante du bean enfant.
@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;
Un bean enfant doit être un bean unique ou une liste de beans et doit afficher l'annotation @JoinPoint. Cette dernière doit se trouver dans la propriété du bean parent qui définit le bean enfant ou la liste de beans.
Un exemple de ce type de mappage est une table DEPARTMENT qui dispose d'une colonne DEPTNO correspondant à une clé principale et une table PROJECT qui dispose aussi d'une colonne DEPTNO. La colonne DEPTNO de la table PROJECT est une clé externe de la table DEPARTMENT. La correspondance par défaut entre les colonnes de l'objet ResultSet et les propriétés est le libellé de la colonne. Dans cet exemple, une jointure des tables DEPARTMENT et PROJECT peut générer deux colonnes avec le libellé de colonne DEPTNO. Si la structure du bean parent et enfant exige que ces colonnes affichent des informations différentes, vous pouvez ajouter des annotations aux beans. Ces annotations peuvent utiliser un nom de table afin de rendre les colonnes uniques. Vous pouvez aussi modifier l'instruction SQL en ajoutant un alias pour créer un libellé de colonne unique. Toutefois, il n'est pas rare pour les requêtes SQL disposant d'une jointure de renvoyer uniquement une colonne lorsque plusieurs colonnes contiennent des données identiques. Dans ce cas, elles sont valides pour une colonne pour la mise à jour de plusieurs propriétés.
Avec ce type de méthode intégrée, des avertissements issus de plusieurs propriétés en cours de mise à jour par cette même colonne ResultSet s'affichent. Ces avertissements sont consignés dans le fichier journal pureQuery Runtime s'il existe et le niveau de trace est défini sur java.util.logging.Level.WARNING ou à un emplacement plus précis.
Tous les beans enfant du bean parent d'origine sont traités avant de traiter n'importe quel bean enfant pour déterminer s'ils contiennent des beans enfant.
pureQuery Runtime peut déterminer si une classe du bean enfant est traitée pour la première fois ou s'il existe des références récursives dans les beans. Si l'analyse syntaxique pureQuery Runtime de la structure du bean imbriqué détecte un bean ayant déjà été analysé, elle arrête l'analyse syntaxique de ce bean enfant.
Des références récursives à un bean affectent également la manière dont l'exécution de pureQuery renseigne les propriétés des beans enfant. Seule la première instance du bean est renseignée. Les références ultérieures à ce bean sont ignorées à moins que la référence ne dispose d'une annotation @JoinColumn avec un autre élément columnPrefix défini. Etant donné que l'ordre de traitement des propriétés dans un bean unique n'est pas déterminant, il en est de même pour l'ordre de traitement des beans enfant. Toutefois, les beans enfant sont traités dans l'ordre du niveau d'imbrication. Par exemple, un bean imbriqué directement dans le bean parent est traité avant un bean au prochain niveau d'imbrication.
Pour plus d'informations sur l'élément columnPrefix, reportez-vous à la documentation relative à l'annotation @JoinPoint.