Hibernate Annotation with HQL & SQL HQL HQL Hibernate Query - - PowerPoint PPT Presentation
Hibernate Annotation with HQL & SQL HQL HQL Hibernate Query - - PowerPoint PPT Presentation
Hibernate Annotation with HQL & SQL HQL HQL Hibernate Query Language
HQL
HQL ย่อมาจาก Hibernate Query Language เป็นภาษาสอบถามเชิงวัตถุที่ใช้ สําหรับจัดการข้อมูลในฐานข้อมูลที่มีลักษณะคล้ายกับภาษา SQL ข้อแตกต่างระหว่าง SQL และ HQL ที่สําคัญ ๆ สามารถสรุปได้ดังต่อไปนี้ SQL มีพื้นฐานการทํางานมาจากระบบฐานข้อมูลเชิงสัมพันธ์ ในขณะที่ HQL เป็นการทํางานที่อาศัยหลักการเชิงวัตถุร่วมกับแนวคิดของ ฐานข้อมูลเชิงสัมพันธ์ SQL ใช้จัดการข้อมูลที่ถูกบันทึกลงในตารางและมีการแก้ไขผ่าน คอลัมน์และแถว ขณะที่ HQL เป็นการทํางานที่เกี่ยวข้องกับอ็อบเจกต์ และแอททริบิวต์ที่ถูกกําหนดไว้ SQL ใช้การทํางานจากความสัมพันธ์ที่เกิดขึ้นระหว่างตาราง ในขณะที่ HQL จะใช้การทํางานจากความสัมพันธ์ระหว่างอ็อบเจกต์
Hibernate query language : HQL
HQL มีลักษณะเป็น case-insensitive ยกเว้นในกรณีที่มีการอ้างถึงชื่อคลาส และชื่อตัวแปรในจาวา From Clause: มีลักษณะเดียวกับ select clause ใน SQL Join Clause: HQL สนับสนุนการทํางานประเภท Join ได้แก่ inner join, left outer join, right outer join และ full join Aggregate ฟังก์ชั่น : count(*), count(distinct x), min(), max(), avg() และ sum() Expressions: HQL สนับสนุนนิพจน์ทางคณิตศาสตร์ (+, -, *, /) การ เปรียบเทียบ Binay (=, >=, <=, <>, !=, like) เปรียบเทียบลอจิก (and, or, not) HQL สนับสนุนคําสั่ง clauses ประเภท order by และ group by
Query interface
เป็นอ็อบเจกต์ที่ถูกสร้างขึ้นจากการเรียกใช้เมธอด createQuery() จาก Session ประกอบไปด้วยเมธอดหลัก ๆ ดังนี้ public int executeUpdate() ใช้ประมวลผลคิวรี update หรือ delete public List list() คืนค่าผลลัพธ์จากตารางในรูปของ list public Query setFirstResult(int rowno) ระบุจํานวนแถวที่อ่านข้อมูล public Query setMaxResult(int rowno) ระบุจํานวนแถวข้อมูลที่ ต้องการอ่านจากตาราง public Query setParameter(int position, Object value) ใช้สําหรับ กําหนดค่าตําแหน่งพารามิเตอร์ตามรูปแบบการคิวรีข้อมูล public Query setParameter(String name, Object value) ใช้กําหนด ชื่อพารามิเตอร์ร่วมกับการคิวรีข้อมูล
Part of Student Class
@Entity @Table (name="STUDENT") public class Student { @Id @GeneratedValue private int studentId; private String studentName; private String major; private double gpa; public Student() {} public Student( String studentName, String major, double gpa) { this.studentName = studentName; this.major = major; this.gpa = gpa; } public String toString() { return " "+studentId+ " "+studentName + " "+major + " "+ gpa; } }
FROM Clause
เป็นรูปแบบ HQL คิวรีที่ใช้โหลด Persistent อ็อบเจกต์เข้าสู่หน่วยความจํา โดยมีรูปแบบการใช้คําสั่งที่คล้ายกับภาษา SQL ดังนี้ การใช้ HQL ต้องผ่าน Query อ็อบเจกต์ที่ประกอบไปด้วยเมธอดต่าง ๆ ที่ใช้ ในการควบคุมการประมวลผลคิวรีต่าง ๆ ดังตัวอย่างคําสั่งต่อไปนี้
HQL SQL FROM Student Select * from Student
String hql = "FROM Student"; Query query = session.createQuery(hql); List<Student> students = query.list();
list() : HQL
ส่วนเมธอด list() ใช้สําหรับคืนค่าผลลัพธ์จากการคิวรีในรูปกลุ่มข้อมูลที่ถูก จัดเก็บภายใน List ดังตัวอย่างคําสั่งต่อไปนี้
String hql = "FROM Student"; Query query = session.createQuery(hql); List<Student> students = query.list(); System.out.println("Student Details: "); for(Student stu: students) { System.out.println(stu); } 1 Somchai Jaidee Information Technology 2.75 2 Somsri Jaipak Computer Science 3.1 3 Somrak Jaijing Information Technology 2.5 4 Somying Jaimon Computer Science 3.12
list() : SQL
ส่วนเมธอด list() ของ SQL ใช้สําหรับคืนค่าผลลัพธ์จากการคิวรีในรูปกลุ่ม ข้อมูลภายใน Object[] ผู้ใช้ต้องแยกผลลัพธ์จากคําสั่งด้วยตัวเอง ดังตัวอย่าง คําสั่งต่อไปนี้
SQLQuery query = session.createSQLQuery("select * from Student"); List<Object[]> student = query.list(); System.out.println("Student Details: "); for(Object[] row : student){ System.out.print("Student ID: "+ row[0]); System.out.print(" Name: "+ row[1]); System.out.println(" Major: "+row[2]); System.out.println(" and GPA: "+row[3]); }
ข้อมูล row ขึ้นอยู่กับลําดับของ ข้อมูลภายในตารางฐานข้อมูล
WHERE Clause
ใช้ในกรณีที่ต้องการจํากัดผลลัพธ์ของการคิวรีให้แคบลงผู้ใช้สามารถใช้ WHERE clause เพื่อปรับแก้ผลลัพธ์ของอ็อบเจกต์ที่ต้องการคืนค่า โดยมี รูปแบบการใช้งานดังตัวอย่างคําสั่งต่อไปนี้
String hql = "FROM Student where studentId = 3"; Query query = session.createQuery(hql); List<Student> students = query.list(); System.out.println("Student Details: "); for(Student stu: students) { System.out.print(stu); } 3 Somrak Jaijing Information Technology 2.5
SELECT Clause
คําสั่งนี้ช่วยให้การควบคุมผลลัพธ์จากการทํางานทําได้ดีกว่า from clause ในกรณีที่ต้องการอ่านค่า properties ของ objects ภายใน result ให้ใช้select clause ตัวอย่างเช่น ในกรณีที่ต้องการอ่านค่าเฉพาะชื่อของ Student เท่านั้น ผู้ใช้ไม่ จําเป็นต้องอ่านค่าจากอ็อบเจกต์ทั้งหมด ดัง select clause ต่อไปนี้
String hql = "SELECT S.name FROM Student S"; Query query = session.createQuery(hql); List<String> names = query.list(); for(String stu: names) { System.out.println("Student name: "+ stu.toString()); }
Named Parameters
Hibernate สนับสนุนการใช้ชื่อของพารามิเตอร์ในการคิวรีข้อมูล เพื่อเพิ่ม ความสะดวกในการเขียน HQL คิวรีรับข้อมูลอินพุตจากผู้ใช้ เช่นใ นกรณีที่ต้องการคิวรีข้อมูลเฉพาะ Student ที่มีค่า studentId เท่ากับ 1 สามารถใช้คําสั่ง setParameter() เพื่อกําหนดชื่อตัวแปร stu_id แทนได้
String hql = "FROM Student S WHERE S.studentId = :stu_id"; Query query = session.createQuery(hql); query.setParameter("stu_id",(long)1); List <Student> results = query.list(); for(Student stu: results) { System.out.println(stu); }
Paging Through the Result Set
เมธอด setFirstResult() รับค่าตัวเลขที่นําเสนอแถวแรกใน result set โดย เริ่มต้นจากแถวที่ 0 ผู้ใช้สามารถกําหนดจํานวนอ็อบเจกต์ที่ต้องการนําเสนอได้ โดยผ่านการ เรียกใช้เมธอด setMaxResults()
String hql = "FROM Student"; Query query = session.createQuery(hql); query.setFirstResult(1); query.setMaxResults(2); List<Student> results = query.list(); for(Student stu: results) { System.out.println(stu); } 2 Somsri Jaipak Computer Science 3.1 3 Somrak Jaijing Information Technology 2.5
Obtaining a Unique Result
เมธอด uniqueResult() ใช้สําหรับอ่านค่าเพียงอ็อบเจกต์เดียวจาก HQL คิวรี ในกรณีที่ไม่มีผลลัพธ์จะคืนค่า null ส่วนในกรณีที่มีผลลัพธ์มากกว่าหนึ่งค่าเมธอด uniqueResult() จะโยนค่า NonUniqueResultException
String hql = "from Student where gpa > 2.5"; Query query = session.createQuery(hql); query.setMaxResults(1); Student stu = (Student) query.uniqueResult(); System.out.println(stu); 1 Somchai Jaidee Information Technology 2.75
HQL with Aggregate functions
HQL ยังสนับสนุนการทํางานของฟังก์ชั่นที่ใช้อํานวยความสะดวกต่าง ๆ อาทิ avg(), min(), max() เป็นต้น ตัวอย่างเช่น
query = session.createQuery("select sum(salary) from Employee"); double sumSalary = (Double) query.uniqueResult(); System.out.println("Sum of all Salaries= "+sumSalary); query = session.createQuery("select sum(salary) from Employee"); List <Double> sumSalary = query.list(); System.out.println("Sum of all Salaries= "+sumSalary.toString);
HQL with Aggregate functions
max()
Query q=session.createQuery("select max(salary) from Emp");
min()
Query q=session.createQuery("select min(salary) from Emp");
count()
Query q=session.createQuery("select count(id) from Emp");
avg()
Query q=session.createQuery("select avg(salary) from Emp");
Hibernate Object Life Cycle
Object State : Transient
ทุก ๆ อ็อบเจกต์เมื่อถูกสร้างขึ้นจะอยู่ในสถานะ transient เสมอ
Student student = new Student("Somchai Jaidee", "IT", 2.75 );
Hibernate จะยังไม่รับรู้เกี่ยวกับอ็อบเจกต์ student สถานะดังกล่าวนี้ยังไม่มีความเกี่ยวข้องกับฐานข้อมูล – ไม่มีค่าของ studentId เมื่อไม่มีการอ้างอิงจากอ็อบเจกต์ดังกล่าวจะถูกจัดการโดย Garbage collection
Object State : Persistent
Hibernate รับรู้ความมีตัวตนของอ็อบเจกต์ดังกล่าว โดยอ็อบเจกต์มีค่า database ID สถานะนี้เกิดขึ้นเมื่อมีการบันทึกข้อมูลอ็อบเจกต์ลงในฐานข้อมูล อ็อบเจกต์ถูกเปลี่ยนสถานะเป็น persistent ผ่านการเรียกใช้เมธอดร่วมกับ Hibernate session เช่น session.save(obj) หรือ session.update(obj)
Object State : Persistent (Cont.)
Session session = SessionFactory.openSession(); Student student = new Student("Somchai Jaidee", "IT", 2.75 ); session.save(student); // การแก้ไขใด ๆ ที่เกิดขึ้นกับอ็อบเจกต์จะถูกบันทึกโดยอัตโนมัติ // เนื่องจาก Student อ็อบเจกต์อยู่ในสถานะ ‘persistent’ student.setMajor(“CS”); session.getTransaction().commit();
Object State : Removed
เกิดขึ้นเมื่อ persistent อ็อบเจกต์ถูกลบออกไปโดยการเรียกใช้เมธอด delete() หรือ remove() ร่วมกับ Session เช่น session.delete(account); แม้ว่าจะถูกลบออกไปแล้ว แต่จาวาอ็อบเจกต์ยังคงอยู่ แต่Hibernate จะ ignore อ็อบเจกต์ดังกล่าว การเปลี่ยนแปลงที่เกิดขึ้นกับอ็อบเจกต์จะไม่ถูกบันทึกลงในฐานข้อมูล ถูกจัดการโดย garbage collection เมื่ออยู่นอกขอบเขตการใช้งาน Hibernate ไม่มีการ not null-out the in-memory object
Object State : Removed
Session session = SessionFactory.openSession(); // อ่านค่า Student อ็อบเจกต์ที่มีค่า id 1 และอยู่ในสถานะ ‘persistent’ Student student = (Student) session.get(Student.class, 1); session.delete(student); // การแก้ไขไม่ส่งผลใด ๆ เนื่องจากอ็อบเจกต์อยู่ในสถานะ ‘removed’ student.setMajor(“IT”); session.getTransaction().commit(); // หมายเหตุ Student อ็อบเจกต์ยังคงอยู่สถานะ Transient // แม้ว่าจะถูกลบออกจากฐานข้อมูลก็ตาม
Object State : Detached
Persistent อ็อบเจกต์ที่ยังสามารถอ้างอิงได้หลังจากปิด session ไปแล้ว session.close() เปลี่ยนสถานะอ็อบเจกต์จาก persisted เป็น detached ยังถูกนําเสนอในรูปแถวข้อมูลภายในตารางฐานข้อมูล ไม่ถูกจัดการโดย Hibernate อีกต่อไป การเปลี่ยนแปลงที่เกิดขึ้นกับ detached อ็อบเจกต์จะไม่ถูกบันทึกลงใน ฐานข้อมูล ขณะที่อ็อบเจกต์ยังคงอยู่ในสถานะ detached state
Object State : Detached
Session session = SessionFactory.openSession(); // อ่านค่า Student อ็อบเจกต์ที่มีค่า id 1 และอยู่ในสถานะ ‘persistent’ Student student = (Student) session.get(Student.class, 1); // เปลี่ยนสถานะเป็น ‘detached’ เมื่อปิด session session.close(); // การแก้ไขไม่ส่งผลกับอ็อบเจกต์สถานะ ‘detached’ แต่ข้อมูลคงอยู่ในตาราง student.setGpa(3.00); // อ็อบเจกต์สามารถกลับมาอยู่ในสถานะ persistent ได้เมื่อมีการเปิด session // และสามารถบันทึกการเปลี่ยนแปลงลงในฐานข้อมูลได้ Session session1 = sessionFactory.openSession(); session1.beginTransaction(); Session1.update(student); session1.getTransaction().commit();
CRUD Operation
สถานะของอ็อบเจกต์ใน Hibernate จะมีความเกี่ยวข้องโดยตรงกับการ ทํางานแบบ CRUD (Create(save), Read(select), Update(update) และ Delete(delete)) โดยการใช้งานร่วมกับ Session อ็อบ-เจกต์ที่ถูกกําหนดไว้ใน Hibernate แพ็คเกจ ซึ่งเมธอดต่าง ๆ ที่ใช้ในการทํางานแบบ CRUD มี ดังต่อไปนี้ save() get() delete() update()
Bidirectional One To Many : CRUD
@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; }
Create
Company company1 = new Company("Indythaitester"); Employee employee1 = new Employee("Somchai Jaidee"); Employee employee2 = new Employee("Somsri Jaipak"); company1.getEmployees().add(employee1); company1.getEmployees().add(employee2); employee1.setCompany(company1); employee2.setCompany(company1); Company company2 = new Company("Information Technology"); Employee employee3 = new Employee("Somrak Jaijing"); Employee employee4 = new Employee("Somying Jaimon"); company2.getEmployees().add(employee3); company2.getEmployees().add(employee4); employee3.setCompany(company2); employee4.setCompany(company2); company1.setEmployees(company1.getEmployees()); session.save(company1); company2.setEmployees(company2.getEmployees()); session.save(company2);
List
@SuppressWarnings("unchecked") public static void listCompany() { Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); List <Company> companies = session.createQuery("from Company").list(); for (Company com: companies) { System.out.println(company); for(Employee employee : company.getEmployees()) { System.out.println(employee); } } session.getTransaction().commit(); session.close(); } }
Update
@SuppressWarnings("unchecked") public static void updateCompany(String oldName, String newName) { Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); List <Company> companies = session.createQuery("from Company where company_name ='" + oldName + "'").list(); for (int i = 0; i < companies.size(); i++) { Company company = (Company) companies.get(i); if(company.getCompanyName().equals(oldName)) { company.setCompanyName(newName); session.update(company); } } session.getTransaction().commit(); session.close(); } }
Delete
@SuppressWarnings("unchecked") public static void deleteCompany(String name) { Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); List <Company> companies = session.createQuery("from Company").list(); for (int i = 0; i < companies.size(); i++) { Company company = (Company) companies.get(i); if (company.getCompanyName().equals(name)) session.delete(company); } } session.getTransaction().commit(); session.close(); } }
Delete : Orphan
@SuppressWarnings("unchecked") public static void listCompany() { Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); List <Employee> employees = session.createQuery("from Employee").list(); for(Employee employee : employees ) { if (employee.getEmployeeName().equals(name)) { Company company = Company)session.get(Company.class, employee.getCompany().getId()); company.getEmployees().remove(employee); session.saveOrUpdate(company); break; } } session.getTransaction().commit(); session.close(); } } @OneToMany (cascade=CascadeType.ALL, orphanRemoval = true, mappedBy = "company")
HCQL (Hibernate Criteria Query Language)
Criteria API ถูกออกแบบมาเพื่อให้ผู้ใช้สามารถเขียนคําสั่งเงื่อนไขต่าง ๆ ที่ ใช้ในการคิวรีข้อมูลที่ต้องการได้อย่างมีประสิทธิภาพ Criteria API ประกอบไปด้วยเมธอดต่าง ๆ ที่ใช้งานบ่อย ๆ ดังต่อไปนี้ public Criteria add(Criterion c) public Criteria addOrder(Order o) public Criteria setFirstResult(int firstResult) public Criteria setMaxResult(int totalResult) public List list() public Criteria setProjection(Projection projection)
Criteria API : How To
Criteria สามารถเรียกใช้อ็อบเจกต์จากคลาส Session ร่วมกับเมธอด createCriteria() เพื่อใช้ในการประมวลผลการคิวรีผ่านการเรียกใช้เมธอดต่าง ๆ พร้อมทั้งระบุเงื่อนไขที่ผู้ใช้ต้องการทํางาน
Criteria criteria = session.createCriteria(Student.class). addOrder(Order.asc("gpa") ); @SuppressWarnings("unchecked") List<Student> results = criteria.list(); for (Student stu: results) { System.out.println(stu); }
Criteria restrictions
Criteria ยังสามารถใช้ในการจํากัดผลลัพธ์จากคิวรี โดยใช้คลาส Restriction ที่ประกอบไปด้วยเมธอดสําคัญ ๆ ดังต่อไปนี้
public static SimpleExpression lt(String propertyName,Object value) public static SimpleExpression le(String propertyName,Object value) public static SimpleExpression gt(String propertyName,Object value) public static SimpleExpression ge(String propertyName,Object value) public static SimpleExpression ne(String propertyName,Object value) public static SimpleExpression eq(String propertyName,Object value) public static SimpleExpression like(String propertyName, Object value) public static Criterion between(String propertyName, Object low, Object high)
Restrictions.eq()
Criteria criteria = session.createCriteria(Student.class); criteria.add(Restrictions.eq("major","Information Technology")); @SuppressWarnings("unchecked") List<Student> results = criteria.list(); for (Student stu: results) { System.out.println(stu); }
คลาส Restriction จําเป็นต้องเรียกใช้เมธอด add() จากคลาส Criteria เพื่อ เรียกใช้เมธอดต่าง ๆ ที่ใช้ในการจํากัดผลลัพธ์โดยการเปรียบเทียบค่า เช่น ในกรณีที่ต้องการอ่านค่าแอททริบิวต์ (property) ที่มีการจํากัดค่า เฉพาะที่เท่ากับ “equals” สามารถทําได้โดยเรียกใช้เมธอด eq() ดังนี้
Restrictions : others
Criteria criteria = session.createCriteria(Student.class); criteria.add(Restrictions.ne("major","Information Technology")); @SuppressWarnings("unchecked") List<Student> results = criteria.list(); Criteria criteria = session.createCriteria(Student.class); criteria.add(Restrictions.gt(“gpa", 3.0); @SuppressWarnings("unchecked") List<Student> results = criteria.list();
Restrictions.like()
การค้นหาโดยใช้คําสั่งประเภท SQL LIKE clause ร่วมกับการเรียกใช้ เมธอด like() หรือ ilike() ที่มีลักษณะเป็น case-insensitive ที่มีโหมดการ ค้นหาต่าง ๆ อาทิ ANYWHERE, END, EXACT และ START ดัง ตัวอย่างต่อไปนี้
Criteria criteria = session.createCriteria(Student.class); criteria.add(Restrictions.like("studentName","%sri",MatchMode.ANYWHERE)); @SuppressWarnings("unchecked") List<Student> results = criteria.list(); for (Student stu: results) { System.out.println(stu); }
Suppliers & Product
กําหนดให้ คลาส Supplier มีความสัมพันธ์แบบหนึ่งต่อกลุ่มไปยังคลาส Product ภายในตารางประกอบไปด้วยข้อมูลดังต่อไปนี้
Criteria
Session session = HibernateUtil.getSessionFactory().openSession(); Criteria c1=session.createCriteria(Supplier.class); List<Supplier> suppliers = c1.list(); for(Supplier s: suppliers){ System.out.println(s); } Session session = HibernateUtil.getSessionFactory().openSession(); Criteria c2 = session.createCriteria(Product.class); c2.add(Restrictions.like("productName", "Dove")); Product pro = (Product) c2.uniqueResult(); System.out.println("Name = " + pro.getProductName());
Criteria c3 = session.createCriteria(Product.class); c3.add(Restrictions.le("price", new Double(100.0))); List<Product> products = c3.list(); for (Product p: products) System.out.println(p);
Criteria : Cont.
Criteria c4 = session.createCriteria(Product.class); c4.setProjection(Projections.rowCount()); List<Long> rows = c4.list(); System.out.println("Row count: "+rows);
Criteria c5 = session.createCriteria(Product.class); ProjectionList projList = Projections.projectionList(); projList.add(Projections.max("price")); projList.add(Projections.min("price")); projList.add(Projections.avg("price")); projList.add(Projections.countDistinct("description")); c5.setProjection(projList); List<Object[]> result = c5.list(); for(int i=0; i<result.size(); i++) { Object[] row = (Object[]) result.get(i); System.out.println("Max price: "+row[0]+" Min price: "+row[1]+ " Avg price: "+row[2]); }
Criteria : Cont.
Max price: 112.0 Min price: 25.0 Avg price: 60.666666666666664
Criteria c6 = session.createCriteria(Product.class); ProjectionList projList1 = Projections.projectionList(); projList1.add(Projections.property("productName")); projList1.add(Projections.property("description")); c6.setProjection(projList); c6.addOrder(Order.asc("price")); List<Object[]> results = c6.list(); for(int i=0; i<results.size(); i++) { Object[] row = (Object[]) results.get(i); System.out.println(" "+row[0]+" "+row[1]); }
Criteria : Cont.
Lux soap Pao detergent Dove shampoo
Entity Relationship : Join
Hibernate สนับสนุนการทํางานแบบ Join 4 ชนิดดังต่อไปนี้ Inner join เลือกจับคู่ข้อมูลจากสองอ็อบเจกต์เฉพาะที่มีค่าเท่ากันเท่านั้น inner join เป็นค่า DEFAULT สําหรับการใช้งานร่วมกับ Hibernate Left join ใช้สําหรับการเลือกจับคู่ข้อมูลจากทั้งสองอ็อบเจกต์ที่เท่ากัน ของการ join โดยเน้นไปที่อ็อบเจกต์ที่อยู่ทางด้านซ้ายมือเป็นหลัก แม้ว่าไม่มีอ็อบเจกต์ที่เท่ากันปรากฏอยู่ทางด้านขวามือก็ตาม Right join ใช้สําหรับการเลือกจับคู่ข้อมูลจากทั้งสองอ็อบเจกต์ที่เท่ากัน ของการ join โดยเน้นไปที่อ็อบเจกต์ที่อยู่ทางด้านขวามือเป็นหลัก แม้ว่าไม่มีอ็อบเจกต์ที่เท่ากันปรากฏอยู่ทางด้านซ้ายมือก็ตาม Full join ใช้สําหรับการเลือกจับคู่ข้อมูลจากทั้งสองอ็อบเจกต์ทั้งที่ เท่ากันและไม่เท่ากันจากทั้งสองด้าน
Bidirectional 1 : M
@Entity @Table(name = "DOCTOR") public class Doctor { ..........; @OneToMany (cascade=CascadeType.ALL, mappedBy = "doctor") private Set<Patient> patients = new HashSet<Patient>(); } @Entity @Table (name = "PATIENT") public class Patient { @ManyToOne @JoinColumn (name = "doctor_id") private Doctor doctor;
Data in DB
Doctor doctor1 = new Doctor("Dr.Sombat Jingjai", "General practitioner"); Patient patient1 = new Patient("Somchai Jaidee", "Headache"); Patient patient2 = new Patient("Somsri Jaipak", "Stomachache"); doctor1.getPatients().add(patient1); doctor1.getPatients().add(patient2); patient1.setDoctor(doctor1); patient2.setDoctor(doctor1); Doctor doctor2 = new Doctor("Dr.Somporn Jaijam", "Allergist"); Patient patient3 = new Patient("Somrak Jaijing", "cold"); Patient patient4 = new Patient("Somying Jaimon", "burn"); doctor2.getPatients().add(patient3); doctor2.getPatients().add(patient4); Doctor doctor3 = new Doctor("Dr.Somboon Jaijade", "Surgery"); patient3.setDoctor(doctor2); patient4.setDoctor(doctor2); doctor1.setPatients(doctor1.getPatients()); doctor2.setPatients(doctor2.getPatients()); session.save(doctor1); session.save(doctor2); session.save(doctor3);
Data in DB
Inner Join
String hql = "from Doctor as D inner join D.patients as P"; Query query = session.createQuery(hql); List<Object[]> list = query.list(); for(int i=0; i<list.size(); i++) { Object[] row = (Object[]) list.get(i); Doctor doctor = (Doctor)row[0]; Patient patient = (Patient)row[1]; System.out.println("doctor Id: "+doctor.getDoctorId()+", doctor Name: "+ doctor.getDoctorName()+ ", patient Id: "+ patient.getPatientId()+", patient Name: "+ patient.getPatientName()); }
Left OUTER JOIN
String hql = "from Doctor as D left outer join D.patients as P"; List<?> list = session.createQuery(hql).list(); for(int i=0; i<list.size(); i++) { Object[] row = (Object[]) list.get(i); Doctor doctor = (Doctor)row[0]; Patient patient = (Patient)row[1]; if ( doctor != null) System.out.println("doctor Id: "+doctor.getDoctorId()+", doctor Name: "+ doctor.getDoctorName()); if (patient != null) System.out.println("patient Id: "+ patient.getPatientId()+", patient Name: "+ patient.getPatientName()); }
Right OUTER JOIN
String hql = "from Doctor as D right outer join D.patients as P"; List<?> list = session.createQuery(hql).list(); for(int i=0; i<list.size(); i++) { Object[] row = (Object[]) list.get(i); Doctor doctor = (Doctor)row[0]; Patient patient = (Patient)row[1]; if ( doctor != null) System.out.println("doctor Id: "+doctor.getDoctorId()+", doctor Name: "+ doctor.getDoctorName()); if (patient != null) System.out.println("patient Id: "+ patient.getPatientId()+", patient Name: "+ patient.getPatientName()); }
Cross JOIN
String hql = "from Doctor as D, patient as P"; List<?> list = session.createQuery(hql).list();