Hibernate Annotation with Class...

47
Hibernate Annotation with Class Relationship

Transcript of Hibernate Annotation with Class...

Page 1: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Hibernate Annotationwith

Class Relationship

Page 2: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Entity RelationshipsUnidirectional one-to-one

ex. Person 1--->1 HeartBidirectional one-to-one

ex. Person 1<--->1 PassportUnidirectional one-to-many

ex. Person 1 --->* PhonesBidirectional one-to-many

aka. Bidirectional many-to-oneex. Person 1<--->* Childs

Unidirectional many-to-oneex. Person *--->1 Company

Unidirectional many-to-manyex. Person *--->* Address

Bidirectional many-to-manyex. Person *<--->* Orders

Page 3: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

One to One Uni Direction

เปนความสมพนธซงในทางปฏบตเปนการก าหนดออบเจกตของคลาสหนง ๆ ใหอยในรปของแอททรบวตของอกคลาสหนงทมความสมพนธกน สามารถเรยกใชงานไดจากทก ๆ เมธอดภายในคลาสตามตองการ

Page 4: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Association Relationship

คลาส Person ประกอบไปดวยแอททรบวตในรปตวแปรPassport ออบเจกตสญลกษณลกศรแสดงถงความสมพนธแบบทศทางเดยว ดงนนคลาส Passport ไมทราบขอมลเกยวกบคลาส Person แตอยางใดดงนนคลาส dependent (Person) มการประกาศตวแปร Passport ออบเจกตไวภายในคลาส scope ดงน

public class Person {

private Passport passport;

.........;

public Passport getPassport() {

return passport;

}

}

public class Passport {

private long id;

.........;

public long getId() {

return id;

}

}

Page 5: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Passportpublic class Passport {

private String passport_no;

private Date issueDate;

private String province;

private String country;

public String getPassportNo() { return passport_no; }

public String getCountry() { return country; }

public Passport(){ }

public Passport(String passportNo, Date issueDate, String province, String country) {

this.passport_no = passportNo;

this.issueDate = issueDate;

this.province = province;

this.country = country;

}

}

Page 6: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Personpublic class Person {

private long id;

private String personName;

private char sex;

private Date birthDate;

private Passport passport;

public Person(){ }

public Person(String personName, char sex, Date birthDate) {

this.personName = personName;

this.sex = sex;

this.birthDate = birthDate;

}

public String getPersonName() { return personName; }

public Passport getPassport() {

return passport;

}

public void setPassport(Passport passport) {

this.passport = passport;

}

}

Page 7: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

One to One Uni Direction : FK

ความสมพนธแบบหนงตอหนงแบบทศทางเดยวสามารถน าเสนอไดโดยการก าหนดคอลมนคยนอก (Foreign Key) ลงในตารางหนงเพอใชในการอางองไปยงคอลมนทเปนคยหลกของอกตารางหนงเพอสรางความสมพนธทเกดขนระหวางสองตาราง

Page 8: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

One to One Uni Direction : Annotation

สญลกษณ @OneToOne ใชระบความสมพนธแบบหนงตอหนงสญลกษณ @OneToOne โดยปกตมกใชรวมกบพารามเตอร cascade เพอใหการบนทกขอมลออบเจกตตอเนอง เชน บนทก Person ออบเจกตเดยวแตสงผลตอเนองไปยงการบนทก Passport ออบเจกตโดยอตโนมตเนองจากเปนแบบทศทางเดยว @OneToOne จะถกก าหนดไวทเอนตททเปน Owner เสมอ ในกรณนไดแก Person

@OneToOne(cascade = CascadeType.ALL)

Page 9: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

@JoinColumn@ OneToOne(cascade = CascadeType.ALL)

@JoinColumn(name=“passport_no")

private Passport passport;

สญลกษณ @JoinColumn ประกอบไปดวยพารามเตอรทใชก าหนดชอคอลมนทตองการอางอง หรอ คอลมนทเปนคยนอก (Foreign Key ) นนเองในกรณทไมมการประกาศ @JoinColumn หรอมแตไมมการระบ name ไวทowner side คา defaults จะถกเรยกใชโดยอตโนมต โดย join คอลมนทเกดขนจะถกสรางขนในตาราง owner โดยใชชอรวมกนระหวางชอความสมพนธของเอนตททมความสมพนธกบ owner side, _ (underscore) และชอคอลมนทเปนคยหลก เชน passport_passprt_no

Page 10: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

One to One Uni Direction : FK

@Entity

@Table(name = "PERSON")

public class Person {

....;

@OneToOne(cascade = CascadeType.ALL)

@JoinColumn(name = "passport_no")

private Passport passport;

....;

}

@Entity

@Table (name = "PASSPORT")

public class Passport {

.....;

}

สราง FK ชอ passport_noเพอลงคไปท Passport

เพอสรางความสมพนธแบบ onetoone

Page 11: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

One-To-One Mapping (Annotations)

public class Person {

int id;...

Passport passport;}

@Entity

@OneToOne

@Id

Passport

…no

Person

passport_noID …

@JoinColumn(name=“passport_no")

@Entity

public class Passport {

int no;

.....;

}

Page 12: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

สญลกษณ @Column

สญลกษณ @Column ใชส าหรบระบชอและรายละเอยดตาง ๆ ของคอลมนทถกแปลงมาจากแอททรบวตทก าหนดไวในคลาส ตวอยางเชน

@Column(name = “person_id")

private int id;

ค าสงดานบนชอแอททรบวตคอ id แตหลงจาก Hibernate แปลงใหอยในรปของตารางแลว คอลมนดงกลาวจะถกก าหนดชอ person_id แทนสวนในกรณทมการก าหนดแอทรบวตในรปออบเจกตจากคลาส Date หรอ Calendar จ าเปนตองระบสญลกษณ @Temporal เพอแปลงคาระหวาง time-stamp และ java util date เพอใหแสดงผลไดอยางถกตอง

Page 13: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Passport@Entity

@Table (name = "PASSPORT")

public class Passport {

@Id

@Column(name = "passport_no")

private String passport_no;

@Temporal(TemporalType.DATE)

@Column(name = "issue_date")

private Date issueDate;

@Column(name = "place_of_birth")

private String province;

@Column(name = "country")

private String country;

public String getPassportNo() { return passport_no; }

public String getCountry() { return country;}

public Passport(){ }

public Passport(String passportNo, Date issueDate, String province, String country) {

this.passport_no = passportNo;

this.issueDate = issueDate;

this.province = province;

this.country = country;

}

}

Page 14: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Person@Entity

@Table(name = "PERSON")

public class Person {

@Id

@GeneratedValue

@Column(name = "person_id") private long id;

@Column(name = "person_name") private String personName;

@Column(name="sex") private char sex;

@Temporal(TemporalType.DATE)

@Column(name = "birthDate") private Date birthDate;

public Person(){ }

public Person(String personName, char sex, Date birthDate) {

this.personName = personName;

this.sex = sex;

this.birthDate = birthDate;

}

@OneToOne(cascade = CascadeType.ALL)

@JoinColumn(name = "passport_no")

private Passport passport;

public Passport getPassport() {

return passport;

}

Page 15: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

hibernate.cfg.xml<session-factory>

<!-- Database connection settings -->

<property name="connection.driver_class">com.mysql.jdbc.Driver</property>

<property name="connection.url">jdbc:mysql://localhost:3306/Person Passport</property>

<property name="connection.username">root</property>

<property name="connection.password">1234</property>

<!-- JDBC connection pool (use the built-in) -->

<property name="connection.pool_size">1</property>

<!-- Echo all executed SQL to stdout -->

<property name="show_sql">true</property>

<!-- Drop and re-create the database schema on startup -->

<property name="hbm2ddl.auto">create</property>

<!-- Mention here all the model classes along with their package name -->

<mapping class="com.itsci.hibernate.Person"/>

<mapping class="com.itsci.hibernate.Passport"/>

</session-factory>

Page 16: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Run Program

Session session = sessionFactory.openSession();

Transaction tx = null;

Person person = new Person("Somchai Jaidee",'M', convertDate("13-08-2540"));

Passport passport = new Passport( 1357473, convertDate("26-01-2557"),

"Chiangmai", "Thailand");

try{

tx = session.beginTransaction();

person.setPassport(passport);

Long id = (Long) session.save(person);

Person per = (Person) session.get(Person.class, id);

System.out.println("Person's Name: " + per.getPersonName());

Passport pass = per.getPassport();

System.out.println("Passport's Number: " + pass.getPassportNo());

System.out.println("Country: " + pass.getCountry());

tx.commit();

}catch (HibernateException e) {

if (tx!=null) tx.rollback();

e.printStackTrace();

}

setPassport ลงใน Person ออบเจกตSave เฉพาะ Person

Page 17: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

One to One Uni Direction : FK

Output

Hibernate: insert into PASSPORT (country, issue_date, passport_no,

place_of_birth) values (?, ?, ?, ?)

Hibernate: insert into PERSON (birthDate, passport_id, person_name, sex) values

(?, ?, ?, ?)

Person's Name: Somchai Jaidee

Passport's Number: 1357473

Country: Thailand

Page 18: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

@JoinColumn without name

ในกรณทไมมการประกาศ @JoinColumn หรอม @JoinColumn แตไมมการระบ name ไวท owner side คา defaults จะถกเรยกใชโดยอตโนมตโดย join คอลมนทเกดขนจะถกสรางขนในตาราง owner โดยใชชอรวมกนระหวางชอความสมพนธของเอนตททมความสมพนธกบ owner side, _ (underscore) และชอคอลมนทเปนคยหลก เชน passport_passport_no

Page 19: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Bidirectional One to One

นยามความสมพนธแบบสองทศทาง (bidirectional) เปนแนวคดทใชในการประยกตความสมพนธระหวางสองออบเจกตทสามารถเขาถงไดทงสองดานความสมพนธทเกดขนขนระหวางคลาส Person และ Passport ทสามารถเขาถง Person ออบเจกตไดจาก Passport ออบเจกต และ Passport ออบเจกตจาก Peson ออบเจกต

Page 20: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Bidirectional One to One

โดยปกตแลวการโปรแกรมเชงวตถทมความสมพนธแบบทศทางเดยวสามารถท างานไดอยางถกตองดงนนในทางปฏบตการโปรแกรมส าหรบความสมพนธแบบสองทศทางสามารถพบไดคอนขางยากแตอยางไรกตามดวยการท างานของ Hibernate เมออยในระดบของฐานขอมล การเขาถงขอมลภายในสามารถท าไดทงสองดานดงนนความสมพนธแบบสองทศทางจงเปนสงทจ าเปนส าหรบการท างานรวมกบ Hibernate

Page 21: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Bidirectional : One to One

@Entity

@Table(name = "PERSON")

public class Person {

....;

@OneToOne .....

@JoinColumn(name = "passport_id")

private Passport passport;

....;

}

@Entity

@Table (name =

"PASSPORT")

public class Passport {

.....;

@OneToOne .......

private Person person;

}

ความสมพนธแบบสองทศทาง ผใชสามารถเขาถงออบเจกตไดทงสองดาน ทงจาก Person => Passport และ Passport => Personดงนนใน Hibernate จงจ าเปนตองก าหนดสญลกษณแสดงความสมพนธ @OneToOne ไวทงสองดาน

Page 22: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

แนวคดเกยวกบ Owner และ Inverse side

เปนแนวคดทมาจากความแตกตางระหวางความสมพนธระหวางคลาสทสามารถมไดทงแบบทศทางเดยวและสองทศทาง สวนในระบบฐานขอมลจะมความสมพนธไดแบบทศทางเดยวเทานนเพอใหเกดความสอดคลองกนในระดบของตารางฐานขอมลจงจ าเปนตองใชแนวคดดงกลาวดานทมคยนอก (foreign key) ในตารางจะถกเรยกวาดานทเปน Ownerและดานตรงกนขามจะเปนดาน Inverse เสมอ ความสมพนธแบบสองทศทางจะประกอบไปดวยดานทเปน Owner และ Inverse ขณะทแบบทศทางเดยวจะมเฉพาะดานทเปน Owner เทานนดานทเปน Owner รบผดชอบเกยวกบ Add, Update และ Delete ทสงผลตอเนองไปยงดานทเปน Inverse โดยอตโนมต

Page 23: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Owning Side Concepts

ในกรณทความสมพนธระหวาง Person และ Passport เปนแบบสองทศทาง ซงสามารถเขาถงไดทงสองทาง ดานทเปน inverse ของความสมพนธจะตองถกก าหนดสญลกษ @OneToOne พรอมระบค าสง mappedBy ไวเสมอค าสง mappedBy จะใชอางองไปยงฟลดของ owning side ของความสมพนธ (Person) ทถกระบไวดวย @JoinColumn เสมอ

Page 24: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Bidirectional One-to-One@Entity

@Table(name = "PERSON")

public class Person {

....;

@OneToOne (cascade = CascadeType.ALL)

@JoinColumn(name = "passport_no")

private Passport passport;

....;

}

@Entity

@Table (name = "PASSPORT")

public class Passport {

.....;

@OneToOne(cascade = CascadeType.ALL ,mappedBy="passport“)

private Person person;

}

Page 25: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Bidirectional One To One Mapping

public class Person {

int id;

@JoinColumn(name=“passport_no”Passport passport;

}

public class Passport {

int id;

Person person;}

PassportID …

Personpassport_noID …

@Entity

@OneToOne

@Id

@Entity

@Id

@OneToOne(mappedBy=“passport”

Page 26: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Bidirectional One-to-One

เพอใหเปนไปตามความสมพนธแบบสองทศทาง จ าเปนตองมการตดตง Person และ Passport ออบเจกตเขาดวยกนทงสองดานดงน

person.setPassport(passport);passport.setPerson(person)

ความแตกตางระหวางความสมพนธแบบทศทางเดยวและสองทศทางคอวธการบนทกขอมลออบเจกตลงในตารางฐานขอมลแบบทศทางเดยวการบนทกขอมลจะเกดขนท Person ออบเจกตเทานนแบบสองทศทางการบนทกขอมลออบเจกตสามารถท าไดทงสองทศทาง

Page 27: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Output

Hibernate: insert into PASSPORT (country, issue_date, passport_no,

place_of_birth) values (?, ?, ?, ?)

Hibernate: insert into PERSON (birthDate, passport_id, person_name, sex)

values (?, ?, ?, ?)

Person's Name: Somchai JaiDee

Passport's Number: 1357473

Country: Thailand

Page 28: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

One-To-One Shared Primary Key

เปนความสมพนธแบบนในระดบของตารางฐานขอมลคอการใชคยหลกของตารางรวมกนวธการนคยหลกของเอนตท product จะถกตงสมมตฐานวาเปนคาคยหลกเดยวกบเอนตท product_detail ดงการน าเสนอในแบบจ าลองความสมพนธตอไปน

Page 29: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

@PrimaryKeyJoinColumn

@PrimaryKeyJoinColumn ใชส าหรบการสรางความสมพนธจากตารางหนงไปยงยงตารางอน โดยปกตแลวการใชสญลกษณดงกลาวจะไมมการสรางคอลมนเพมเตมแตอยางใด ทงนเนองจากทงสองเอนตทมการใชคยหลกเดยวกน คยหลกในตาราง Product ถกใชเปนคาคยหลกในตาราง ProductDetail ตามไปดวย สญลกษณ @Cascade ทมคา CascadeType.ALL เพอการบนทก อพเดทหรอลบขอมลออกจากตาราง Product จะสงผลตอเนองไปยงตาราง ProductDetail โดยอตโนมต

Page 30: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

One-To-One Shared Primary Key : UNI

@Entity

@Table(name = "PRODUCT")

public class Product {

@Id

@GeneratedValue

@Column(name = "PRODUCT_ID")

private long productId;

@OneToOne(cascade=CascadeType.ALL)

@PrimaryKeyJoinColumn

private ProductDetail productDetail;

}@Entity

@Table(name = "PRODUCT_DETAIL")

public class ProductDetail {

@Id

@GeneratedValue

private long productId;

public ProductDetail() { }

}

Page 31: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

สญลกษณ @Column

สญลกษณ @Column ใชส าหรบระบชอและรายละเอยดตาง ๆ ของคอลมนทถกแปลงมาจากแอททรบวตทก าหนดไวในคลาส ผใชสามารถใชสญลกษณดงกลาวรวมกบการระบคาตาง ๆ ดงตอไปน

name ใชระบชอคอลมนทตองการในตารางฐานขอมลlength ใชก าหนดขนาดของคอลมนทใชส าหรบ map คา String หนง ๆnullable ใชระบคา NOT NULL เมอมการสราง schema เชน nullable = false หมายถงคอลมนทถกระบไมสามารถมคาเปน null ไดunique ใชก าหนดคาในคอลมนทถกระบตองมคาไมซ ากน

Page 32: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

One-To-One SPKey : Uni (run)

Session session = sessionFactory.openSession();

Product pro = new Product("Polo", 1412.00);

ProductDetail productDetail = new ProductDetail(1001,"Shirt" , "Sahapat");

Transaction tx = null;

try{

tx = session.beginTransaction();

pro.setProductDetail(productDetail);

session.save(pro);

tx.commit();

}catch (HibernateException e) {

if (tx!=null) tx.rollback();

e.printStackTrace();

}finally {

session.close();

}

Page 33: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

One-To-One Shared Primary Key : Bi

@Entity

@Table(name = "PRODUCT")

public class Product {

@Id

@GeneratedValue

@Column(name = "PRODUCT_ID")

private long productId;

@OneToOne(cascade=CascadeType.ALL)

@PrimaryKeyJoinColumn

private ProductDetail productDetail;

}

@Entity

@Table(name = "PRODUCT_DETAIL")

public class ProductDetail {

@Id

private long productId;

public ProductDetail() { }

@OneToOne(mappedBy = "productDetail")

private Product product;

}

Page 34: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Same Primary Keyกรณทตองการให Hibernate สราง id ของเอนตท ProductDetail ใหมคาเดยวกบ Primary Key ในเอนตท Product สามารถใชค าสงดงน

@Id

@GeneratedValue (generator = "newgen")

@GenericGenerator(strategy = "foreign", name="newgen",

parameters = @Parameter(name = "property", value="product"))

private long productId;

พารามเตอรแรกก าหนดชอง Generator ทตองการไดแก "newGen“พารามเตอรถดมาก าหนดชนดของ strategy ทใชในการสรางคา ID ซงกรณนเปนสรางคาคยนอก ดงนนเลอกใช Generator ทเรยกวา “foreign” สวนสดทายก าหนด property ชอของตารางทสมพนธกน ไดแก product

Page 35: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

One To Many Relationship

เปนความสมพนธทพบไดบอย ๆ ในการโปรแกรมเชงวตถ โดยคลาสหนงมความสมพนธกบคลาสอน ๆ ในรปของหนงตอกลมในระดบการโปรแกรมเปนการประกาศตวแปรแอททรบวตในรปกลมของออบเจกตจากคลาสอน ๆ ไวภายในอกคลาสหนงทมความสมพนธกน

Page 36: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

One Company : Many Employees

public class Employee {

private Long id;

private String employeeName;

public Employee(String employeeName) {

this.employeeName = employeeName;

}

public String getEmployeeName() {

return employeeName;

}

public void setEmployeeName(String

employeeName) {

this.employeeName = employeeName;

}

}

public class Company {

private Long id;

private String companyName;

public Company(String companyName) {

this.companyName = companyName;

}

private Set<Employee> employeeSet;

public Set<Employee> getEmployees() {

return employeeSet;

}

public void setEmployees(Set<Employee>

employees) {

this.employeeSet = employees;

}

}

}

Page 37: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

One To Many Uni

การสรางความสมพนธแบบ One To Many แบบทศทางเดยวเรยกใชสญลกษณ @OneToMany เพอก าหนดความสมพนธแบบหนงตอกลมเรยกใชสญลกษณ @JoinColumn เพอสรางคยนอกเพอใชในการอางองไปยงตารางทมความสมพนธกนเรยกใชสญลกษณ @Cascade (cascade = CascadeType.All) ลงทางดานคลาสทเปน Owner เพอสงผลตอเนองไปยงการบนทกขอมลรวมกบ คลาสทมความสมพนธกนโดยอตโนมต

Page 38: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

One To Many Uni : Structure

@Entity

@Table(name = "COMPANY")

public class Company {

.....;

@OneToMany (cascade=CascadeType.ALL)

@JoinColumn (name = "company_id")

private Set<Employee> employees = new HashSet<Employee>();

// setter & getter;

}

@Entity

@Table (name = "EMPLOYEE")

public class Employee {

....;

}

Page 39: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Run : One To Many Uni

Session session = sessionFactory.openSession();

Transaction tx = null;

Company company = new Company("IndyThaiTester");

Employee employee1 = new Employee("Somchai");

Employee employee2 = new Employee("Somsri");

company.getEmployees().add(employee1);

company.getEmployees().add(employee2);

try{

tx = session.beginTransaction();

session.save(company);

tx.commit();

}catch (HibernateException e) {

if (tx!=null) tx.rollback();

e.printStackTrace();

}

finally {

session.close();

}

Page 40: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Output

Hibernate: insert into COMPANY (company_name) values (?)

Hibernate: insert into EMPLOYEE (employee_name) values (?)

Hibernate: insert into EMPLOYEE (employee_name) values (?)

Hibernate: update EMPLOYEE set company_id=? where employee_id=?

Hibernate: update EMPLOYEE set company_id=? where employee_id=?

Page 41: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

@OneToMany และ @ManyToOne

ความสมพนธแบบหนงตอกลมอาจมองไดเปนสองแบบไดแกหนงตอกลม ใช @OneToManyกลมตอหนง ใช @ManyToOne

สาเหตทตองใชสญลกษณทแตกตางกนเนองมาความจ าเปนทตองแจงให Hibernate ทราบวาคลาสดานใดท าหนาทเปนเจาของความสมพนธและคลาสดานใดอยตรงขามกบเจาของความสมพนธดงกลาว

Page 42: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Many To One Uni : Structure

@Entity

@Table(name = "COMPANY")

public class Company {

.....;

}

@Entity

@Table (name = "EMPLOYEE")

public class Employee {

....;

@ManyToOne (cascade=CascadeType.ALL)

@JoinColumn (name = "company_id")

private Company company;

}

สวนทเปนกลมออบเจกตจากคลาส Set จะถกตดออกไป

เพมตวแปรดานทเปน one มาแทนท

Page 43: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Run : Many To One UniSession session = sessionFactory.openSession();

Transaction tx = null;

Company company = new Company("IndyThaiTester");

Employee employee1 = new Employee("Somchai");

Employee employee2 = new Employee("Somsri");

try{

tx = session.beginTransaction();

employee1.setCompany(company);

employee2.setCompany(company);

session.save(employee1);

session.save(employee2);

tx.commit();

}catch (HibernateException e) {

if (tx!=null) tx.rollback();

e.printStackTrace();

}

finally {

session.close();

}

Page 44: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Bidirectional One To Many

โดยปกตความสมพนธทเกดขนระหวางคลาสทเกดขนเมอคลาสหนงมการอางอางถงคลาสอกกลมหนง ซงในทางปฏบตสามารถเขาถงไดทงสองทางความสมพนธแบบหนงตอกลมสองทศทางสามารถน าเสนอไดดงคลาสไดอาแกรมตอไปน

Page 45: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Owning Side

ความสมพนธแบบหนงตอกลมเกดขนระหวางคลาส Company และคลาส Employees เนองจากเปนความสมพนธแบบสองทศทาง ตองระบทง @OneToMany และ @ManyToOneซงดานทเปน ManyToOne ถอเปน Owner ขณะทดานทเปน OneToMany ถอเปน inverse เสมอดงนนตองระบค าสง mappedBy="company" ไวในคลาส Company ทเปน Inverse เพออางถงตวแปรออบเจกตทถกประกาศไวในคลาส Employee ซงท าหนาทเปน Owner ของความสมพนธเสมอ

Page 46: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Bidirectional One To Many : Structure

@Entity

@Table(name = "COMPANY")

public class Company {

.....;

@OneToMany (cascade=CascadeType.ALL, mappedBy = "company")

private Set<Employee> employeeSet = new HashSet<Employee>();

.....;

}

@Entity

@Table (name = "EMPLOYEE")

public class Employee {

....;

@ManyToOne(cascade=CascadeType.ALL)

@JoinColumn (name = "company_id")

private Company company;

}

Page 47: Hibernate Annotation with Class Relationshipคาสั่งดา้นบนชื่อแอททริบิวต์คือ id แต่หลงัจาก Hibernate แปลงให้อยู่ในรูป

Run : Bidirectional One To ManySession session = sessionFactory.openSession();

Transaction tx = null;

Company company = new Company("IndyThaiTester");

Employee employee1 = new Employee("Somchai Jaidee");

Employee employee2 = new Employee("Somsri Jaipak");

company.getEmployees().add(employee1);

company.getEmployees().add(employee2);

employee1.setCompany(company);

employee2.setCompany(company);

try{

tx = session.beginTransaction();

session.save(employee1);

session.save(employee2);

tx.commit();

}catch (HibernateException e) {

if (tx!=null) tx.rollback();

e.printStackTrace();

}