280 likes | 407 Views
Relation Mapping. EJB 3.0 コース 第 9 回 2006 年 8 月 6 日. ここでの目標. 複数のテーブルを組み合わせてデータにアクセスする「 Relation Mapping 」について理解する. 一対一の関係 : @OneToOne. 一対一の関係 : 従業員と自宅の住所. EJB_EMPLOYEE 社員テーブル. EJB_EMPLOYEE 社員テーブル. EJB_ADDRESS 住所テーブル. 住所の ID から住所を得る. @ Entity @Table(name="EJB_EMPLOYEE")
E N D
Relation Mapping EJB 3.0 コース 第9回 2006年8月6日
ここでの目標 • 複数のテーブルを組み合わせてデータにアクセスする「Relation Mapping」について理解する
一対一の関係:従業員と自宅の住所 EJB_EMPLOYEE 社員テーブル EJB_EMPLOYEE 社員テーブル EJB_ADDRESS 住所テーブル
住所のIDから住所を得る @Entity @Table(name="EJB_EMPLOYEE") public class Employee implements Serializable { @Id @Column(name="EMP_ID") : @OneToOne(cascade=CascadeType.ALL) @JoinColumn(name="ADDR_ID") public Address getAddress() { return address; } }
カスケード処理 • テーブル間の関連があるときに、処理を伝播させる (カスケードさせる) ことが可能 • テーブル間の関係が親子関係のときに利用 • 関連に用いるアノテーション (*To*) とcascade public enum CascadeType{ ALL, PERSIST, MERGE, REMOVE, REFRESH }; @OneToMany(cascade=CascadeType.ALL) public Collection<MailAddress> getMailAddresses(){…}
関連インスタンスのロード • 関連インスタンスのロードのタイミングを指定できる • 即時 (eager) ロード:ソースがロードされると、ターゲットも同時にロード • 遅延 (lazy) ロード:ターゲットがアクセスされたときにロード • *To*アノテーションとfetchメンバ • OneToOne、 ManyToOneのデフォルトはEAGER • OneToMany、ManyToManyのデフォルトはLAZY • *ToManyは、ロードするインスタンスが多数になるため @ManyToOne(fetch=FetchType.EAGER) public Studen getOwner() {…}
社員の住所の取得 public Address getAddressForEmployee(Integer employeeId) { Employee employee = em.find(Employee.class, employeeId); return employee.getAddress(); }
多対一の関係:メールアドレスと学生 Student 学生テーブル MailAddress メールアドレステーブル
Student.java @Entity @Table(name = "student") public class Student { @Id @Column(name="id") public int getId() {...} public void setId(int id) {...} @Column(name="name") public String getName() {...} public void setName(String name) {...} }
MailAddress.java @Entity @Table(name = "mail_address") public class MailAddress { @Id @Column(name="address") public String getAddress() {...} public void setAddress(String address) {...} @ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER) @JoinColumn(name="student_id", referencedColumnName="id") public Student getOwner() {...} public void setOwner(Student owner) {...} }
メールアドレスから学生を得る @ManyToOne(fetch=FetchType.EAGER) @JoinColumn(name=“student_id", referencedColumnName=“id") public Student getOwner() {…} public void setOwner(Student owner) {…}
アドレスの情報から持ち主の学生を得る @Remote public interface MailAddressFacade { void addMailAddress(int student_id, String address); MailAddress findMailAddressByAddress (String address); Student findStudentByAddress(String address); }
アドレスの情報から持ち主の学生を得る (実装) public Student findStudentByAddress (String address) { MailAddress mailAddress = (MailAddress)em .find(MailAddress.class, address); return mailAddress.getOwner(); }
多対一と一対多 Student 学生テーブル MailAddress メールアドレステーブル
多対一と一対多 • メールアドレスから学生 →多対一(ManyToOne) • 学生からメールアドレス → 一対多(OneToMany)
Student.java @Entity @Table(name = "student") public class Student { @Id @Column(name="id") public int getId() {...} public void setId(int id) {...} @Column(name="name") public String getName() {...} public void setName(String name) {...} // メールアドレスの情報はどこからとる? }
学生からメールアドレスの一覧を得るには? @OneToMany(cascade=CascadeType.ALL) @JoinColumn(name=“student_id", referencedColumnName=“id") public Collection<MailAddress> getMailAddresses() { return mailAddresses; }
学生の情報からメールアドレス一覧を得る @Remote public interface StudentFacade { void addStudent(int id, String name); Student findStudentById(int id); Collection<MailAddress> findMailAddressesById(int id); }
学生の情報からメールアドレス一覧を得る (実装) public Collection<MailAddress> findMailAddressesById(int id) { Student student = (Student)em.find( Student.class, id ); return student.getMailAddresses(); }
多対多の例) 学生と履修科目 Student 学生テーブル Course 科目テーブル
多対多の場合には中間テーブルが必須 Association Table
Association Table を介した対応 Student 学生テーブル joinColumns= @JoinColumn(name=“Student_ID", referencedColumnName="ID"), Association Table inverseJoinColumns= @JoinColumn(name=“Course_ID", referencedColumnName="ID") Course 科目テーブル
ManyToManyの記述の例 @ManyToMany(cascade=CascadeType.ALL) @AssociationTable( table=@Table(name=“course_regist"), joinColumns=@JoinColumn( name=“Student_ID", referencedColumnName="ID"), inverseJoinColumns=@JoinColumn( name=“Course_ID", referencedColumnName="ID") ) public Collection<Course> getCourses() {…}
学生から履修科目の一覧を取得 public Collection<Course> getCourses() { return courses; } public void setCourses (Collection<Course> courses) { this.courses = courses; }