Relation Mapping EJB 3.0 コース 第9回 2006年8月6日 1 ここでの目標 複数のテーブルを組み合わせてデータにア クセスする「Relation Mapping」について理解 する 2 一対一の関係: @OneToOne 3 一対一の関係: 従業員と自宅の住所 EJB_EMPLOYEE 社員テーブル EMP_ID VERSION 社員テーブル L_NAME F_NAME EJB_EMPLOYEE 309 829 丸山 3 冨岡 稚内 ADDR_ID 不二夫 北海道 MANAGER_ID 829 123 097-0012 日本 P_CODE COUNTRY EJB_ADDRESS 住所テーブル ADDRESS_ID STREET CITY PROVINCE 4 住所のIDから住所を得る EMP_ID VERSION L_NAME F_NAME ADDR_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; } } 5 カスケード処理 テーブル間の関連があるときに、処理を伝播さ せる (カスケードさせる) ことが可能 テーブル間の関係が親子関係のときに利用 関連に用いるアノテーション (*To*) とcascade public enum CascadeType{ ALL, PERSIST, MERGE, REMOVE, REFRESH }; @OneToMany(cascade=CascadeType.ALL) public Collection<MailAddress> getMailAddresses(){…} 6 関連インスタンスのロード 関連インスタンスのロードのタイミングを指定できる 即時 (eager) ロード:ソースがロードされると、ターゲットも同時に ロード 遅延 (lazy) ロード:ターゲットがアクセスされたときにロード *To*アノテーションとfetchメンバ OneToOne、 ManyToOneのデフォルトはEAGER OneToMany、ManyToManyのデフォルトはLAZY • *ToManyは、ロードするインスタンスが多数になるため @ManyToOne(fetch=FetchType.EAGER) public Studen getOwner() {…} 7 社員の住所の取得 public Address getAddressForEmployee(Integer employeeId) { Employee employee = em.find(Employee.class, employeeId); return employee.getAddress(); } 8 @ManyToOne 9 多対一の関係: メールアドレスと学生 Student 学生テーブル ID Name 309 丸山不二夫 [email protected] 309 [email protected] 309 [email protected] 309 MailAddress メールアドレステーブル Address Student ID 10 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) {...} } 11 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) {...} } 12 メールアドレスから学生を得る [email protected] 309 309 丸山 不二夫 @ManyToOne(fetch=FetchType.EAGER) @JoinColumn(name=“student_id", referencedColumnName=“id") public Student getOwner() {…} public void setOwner(Student owner) {…} 13 アドレスの情報から持ち主の学生 を得る @Remote public interface MailAddressFacade { void addMailAddress(int student_id, String address); MailAddress findMailAddressByAddress (String address); Student findStudentByAddress(String address); } 14 アドレスの情報から持ち主の学生 を得る (実装) public Student findStudentByAddress (String address) { MailAddress mailAddress = (MailAddress)em .find(MailAddress.class, address); return mailAddress.getOwner(); } 15 一対多の関係: @OneToMany 16 多対一と一対多 Student 学生テーブル ID Name 309 丸山 不二夫 [email protected] 309 [email protected] 309 [email protected] 309 MailAddress メールアドレステーブル Address Student ID 17 多対一と一対多 メールアドレスから学生 →多対一(ManyToOne) 学生からメールアドレス → 一対多(OneToMany) 18 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) {...} // メールアドレスの情報はどこからとる? } 19 学生からメールアドレスの一覧を 得るには? ID Name 309 丸山 不二夫 Address [email protected] [email protected] Student ID 309 309 @OneToMany(cascade=CascadeType.ALL) @JoinColumn(name=“student_id", referencedColumnName=“id") public Collection<MailAddress> getMailAddresses() { return mailAddresses; } 20 学生の情報からメールアドレス一 覧を得る @Remote public interface StudentFacade { void addStudent(int id, String name); Student findStudentById(int id); Collection<MailAddress> findMailAddressesById(int id); } 21 学生の情報からメールアドレス一 覧を得る (実装) public Collection<MailAddress> findMailAddressesById(int id) { Student student = (Student)em.find( Student.class, id ); return student.getMailAddresses(); } 22 多対多の関係: @ManyToMany 23 多対多の例) 学生と履修科目 Student 学生テーブル Course 科目テーブル ID ID Name 301 小泉純子 1 Course Name Java I Teacher Name 302 安倍晋太 2 Java II 植田龍男 303 武部務 3 Java III 佐賀孝博 304 麻生次郎 4 J2EE I 安藤友晴 植田龍男 24 多対多の場合には中間テーブル が必須 Association Table Student ID Course ID 301 1 301 2 302 2 302 3 302 4 303 1 303 3 25 Association Table を介した対応 Student 学生テーブル ID Name joinColumns= @JoinColumn(name=“Student_ID", referencedColumnName="ID"), Association Table Student ID Course ID inverseJoinColumns= @JoinColumn(name=“Course_ID", referencedColumnName="ID") Course 科目テーブル ID Course Name Teacher Name 26 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() {…} 27 学生から履修科目の一覧を取得 public Collection<Course> getCourses() { return courses; } public void setCourses (Collection<Course> courses) { this.courses = courses; } 28
© Copyright 2024 ExpyDoc