package com.zze.bean; import java.util.HashSet; import java.util.Set; public class Class { public Class() { } public Class(Integer id, String name) { this.id = id; this.name = name; } private Integer id; private String name; private Set<Student> students = new HashSet<>(); public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<Student> getStudents() { return students; } public void setStudents(Set<Student> students) { this.students = students; } @Override public String toString() { return "Class{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.zze.bean.Class" table="class"> <id name="id"> <generator class="native"/> </id> <property name="name" length="32"/> <set name="students" cascade="save-update"> <key column="cid"/> <one-to-many class="com.zze.bean.Student"/> </set> </class> </hibernate-mapping>
package com.zze.bean; import java.util.Date; import java.util.HashSet; import java.util.Set; public class Student { public Student() { } public Student(Integer id, String name, Integer age,String gender) { this.id = id; this.name = name; this.age = age; this.gender = gender; } private Integer id; private String name; private Integer age; private String gender; private Class clazz; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public Class getClazz() { return clazz; } public void setClazz(Class clazz) { this.clazz = clazz; } @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.zze.bean.Student" table="student"> <id name="id"> <generator class="native"/> </id> <property name="name" length="32"/> <property name="age"/> <property name="gender"/> <many-to-one name="clazz" column="cid" class="com.zze.bean.Class"/> </class> </hibernate-mapping>
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://192.168.208.153:3306/1221</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <property name="current_session_context_class">thread</property> <property name="hibernate.hbm2ddl.auto">create</property> <mapping resource="com/zze/bean/Class.hbm.xml"></mapping> <mapping resource="com/zze/bean/Student.hbm.xml"></mapping> </session-factory> </hibernate-configuration>
package com.zze.util; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { public static final Configuration cfg; public static final SessionFactory sf; static { cfg = new Configuration().configure(); sf = cfg.buildSessionFactory(); } public static Session openSession() { return sf.openSession(); } public static Session getCurrentSession() { return sf.getCurrentSession(); } }
@Test public void initData(){ Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Class clazz1 = new Class(null,"軟件一班"); Class clazz2 = new Class(null,"軟件二班"); Class clazz3 = new Class(null,"汽修一班"); Class clazz4 = new Class(null,"汽修二班"); Student student1 = new Student(null, "張三", 12,"男"); Student student2 = new Student(null, "李四", 13,"女"); Student student3 = new Student(null, "王五", 14,"男"); Student student4 = new Student(null, "趙六", 15,"男"); Student student5 = new Student(null, "吳剛", 39,"男"); Student student6 = new Student(null, "王如花", 30,"女"); Student student7 = new Student(null, "李志靜", 49,"女"); Student student8 = new Student(null, "何王天", 30,"男"); clazz1.getStudents().add(student1); clazz1.getStudents().add(student2); clazz2.getStudents().add(student3); clazz2.getStudents().add(student4); clazz3.getStudents().add(student5); clazz3.getStudents().add(student6); clazz4.getStudents().add(student7); clazz4.getStudents().add(student8); session.save(clazz1); session.save(clazz2); session.save(clazz3); session.save(clazz4); transaction.commit(); }
Hibernate 根據對象的 OID(主鍵)進行檢索。java
@Test public void test1(){ Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Class clazz = session.get(Class.class, 1); System.out.println(clazz); transaction.commit(); /* Hibernate: select class0_.id as id1_0_0_, class0_.name as name2_0_0_ from class class0_ where class0_.id=? Class{id=1, name='軟件一班'} */ }
@Test public void test2() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Class clazz = session.load(Class.class, 1); System.out.println(clazz); transaction.commit(); /* Hibernate: select class0_.id as id1_0_0_, class0_.name as name2_0_0_ from class class0_ where class0_.id=? Class{id=1, name='軟件一班'} */ }
Hibernate 根據一個已經查詢到的對象,得到其關聯的對象的一種查詢方式。mysql
@Test public void test3(){ Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Class clazz = session.load(Class.class, 1); System.out.println(clazz); System.out.println(Arrays.toString(clazz.getStudents().toArray())); transaction.commit(); /* Hibernate: select class0_.id as id1_0_0_, class0_.name as name2_0_0_ from class class0_ where class0_.id=? Class{id=1, name='軟件一班'} Hibernate: select students0_.cid as cid5_1_0_, students0_.id as id1_1_0_, students0_.id as id1_1_1_, students0_.name as name2_1_1_, students0_.age as age3_1_1_, students0_.gender as gender4_1_1_, students0_.cid as cid5_1_1_ from student students0_ where students0_.cid=? [Student{id=2, name='張三'}, Student{id=1, name='李四'}] */ }
Hibernate Language Query,Hibernate 自己提供語法支持的一種檢索方式。sql
/** * 查詢全部班級 */ @Test public void test4(){ Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); String hql ="from Class"; Query query = session.createQuery(hql); List<Class> list = query.list(); System.out.println(list); transaction.commit(); /* Hibernate: select class0_.id as id1_0_, class0_.name as name2_0_ from class class0_ [Class{id=1, name='軟件一班'}, Class{id=2, name='軟件二班'}, Class{id=3, name='汽修一班'}, Class{id=4, name='汽修二班'}] */ }
@Test public void test5(){ Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); String hql ="select c from Class c"; Query query = session.createQuery(hql); List<Class> list = query.list(); System.out.println(list); transaction.commit(); /* Hibernate: select class0_.id as id1_0_, class0_.name as name2_0_ from class class0_ [Class{id=1, name='軟件一班'}, Class{id=2, name='軟件二班'}, Class{id=3, name='汽修一班'}, Class{id=4, name='汽修二班'}] */ }
/** * 根據年齡排序 */ @Test public void test6(){ Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); // 升序 String hql = "from Student order by age"; // 降序 // String hql = "from Student order by age desc"; Query query = session.createQuery(hql); List<Class> list = query.list(); System.out.println(list); transaction.commit(); /* Hibernate: select student0_.id as id1_1_, student0_.name as name2_1_, student0_.age as age3_1_, student0_.gender as gender4_1_, student0_.cid as cid5_1_ from student student0_ order by student0_.age [Student{id=2, name='張三'}, Student{id=1, name='李四'}, Student{id=3, name='王五'}, Student{id=4, name='趙六'}, Student{id=6, name='王如花'}, Student{id=8, name='何王天'}, Student{id=5, name='吳剛'}, Student{id=7, name='李志靜'}] */ }
/** * 一個條件,查詢 name='張三' 的 Student * 參數按位置綁定 */ @Test public void test7() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); String hql = "from Student where name = ?"; Query query = session.createQuery(hql); query.setParameter(0, "張三"); List<Student> list = query.list(); System.out.println(list); transaction.commit(); /* Hibernate: select student0_.id as id1_1_, student0_.name as name2_1_, student0_.age as age3_1_, student0_.gender as gender4_1_, student0_.cid as cid5_1_ from student student0_ where student0_.name=? [Student{id=2, name='張三'}] */ } /** * 多個條件 查詢 name 中包含 '王' 且 age 大於 18 的Student * 參數按名稱綁定 */ @Test public void test8() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); String hql = "from Student where name like :name and age>:age"; Query query = session.createQuery(hql); query.setParameter("name", "%王%"); query.setParameter("age", 18); List<Student> list = query.list(); System.out.println(list); transaction.commit(); /* Hibernate: select student0_.id as id1_1_, student0_.name as name2_1_, student0_.age as age3_1_, student0_.gender as gender4_1_, student0_.cid as cid5_1_ from student student0_ where ( student0_.name like ? ) and student0_.age>? [Student{id=6, name='王如花'}, Student{id=8, name='何王天'}] */ }
/** * 查詢單個屬性 返回 Object List */ @Test public void test9() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); String hql = "select s.name from Student s"; Query query = session.createQuery(hql); List<Object> list = query.list(); System.out.println(list); transaction.commit(); /* Hibernate: select student0_.name as col_0_0_ from student student0_ [李四, 張三, 王五, 趙六, 吳剛, 王如花, 李志靜, 何王天] */ } /** * 查詢多個屬性 返回 Object[] List */ @Test public void test10() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); String hql = "select s.name,s.age from Student s"; Query query = session.createQuery(hql); List<Object[]> list = query.list(); for (Object[] objects : list) { System.out.println(Arrays.toString(objects)); } transaction.commit(); /* Hibernate: select student0_.name as col_0_0_, student0_.age as col_1_0_ from student student0_ [李四, 13] [張三, 12] [王五, 14] [趙六, 15] [吳剛, 39] [王如花, 30] [李志靜, 49] [何王天, 30] */ } /** * 查詢多個屬性 返回對應對象類型 List */ @Test public void test11() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); /* 須要讓模型提供對應構造: public Student(String name, Integer age) { this.name = name; this.age = age; } */ String hql = "select new Student(name,age) from Student"; Query query = session.createQuery(hql); List<Student> list = query.list(); System.out.println(list); transaction.commit(); /* Hibernate: select student0_.name as col_0_0_, student0_.age as col_1_0_ from student student0_ [Student{id=null, name='李四'}, Student{id=null, name='張三'}, Student{id=null, name='王五'}, Student{id=null, name='趙六'}, Student{id=null, name='吳剛'}, Student{id=null, name='王如花'}, Student{id=null, name='李志靜'}, Student{id=null, name='何王天'}] */ }
@Test public void test12() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); String hql = "from Student"; Query query = session.createQuery(hql); query.setFirstResult(0); // 起始行索引 query.setMaxResults(3); // 每頁條數 List<Student> list = query.list(); System.out.println(list); transaction.commit(); /* Hibernate: select student0_.id as id1_1_, student0_.name as name2_1_, student0_.age as age3_1_, student0_.gender as gender4_1_, student0_.cid as cid5_1_ from student student0_ limit ? [Student{id=1, name='李四'}, Student{id=2, name='張三'}, Student{id=3, name='王五'}] Process finished with exit code 0 */ }
/** * 聚合查詢 */ @Test public void test13() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); // 聚合函數使用 count max min avg sum String hql = "select count(1) from Student"; Query query = session.createQuery(hql); Object o = query.uniqueResult(); System.out.println(o.getClass()); System.out.println(o); transaction.commit(); /* Hibernate: select count(1) as col_0_0_ from student student0_ class java.lang.Long 8 */ } /** * 分組查詢 返回 Object[] List * 根據 gender 分組,查詢每一個 gender 的對應數據條數 */ @Test public void test14() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); String hql = "select gender,count(1) from Student group by gender"; Query query = session.createQuery(hql); List<Object[]> list = query.list(); for (Object[] objects : list) { System.out.println(Arrays.toString(objects)); } transaction.commit(); /* Hibernate: select student0_.gender as col_0_0_, count(1) as col_1_0_ from student student0_ group by student0_.gender [女, 3] [男, 5] */ }
@Test public void test23() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); String hql = "from Student c join c.clazz"; Query query = session.createQuery(hql); List<Object[]> list = query.list(); for (Object[] objects : list) { System.out.println(Arrays.toString(objects)); } transaction.commit(); /* Hibernate: select student0_.id as id1_1_0_, class1_.id as id1_0_1_, student0_.name as name2_1_0_, student0_.age as age3_1_0_, student0_.gender as gender4_1_0_, student0_.cid as cid5_1_0_, class1_.name as name2_0_1_ from student student0_ inner join class class1_ on student0_.cid=class1_.id [Student{id=1, name='李四'}, Class{id=1, name='軟件一班'}] [Student{id=2, name='張三'}, Class{id=1, name='軟件一班'}] [Student{id=3, name='王五'}, Class{id=2, name='軟件二班'}] [Student{id=4, name='趙六'}, Class{id=2, name='軟件二班'}] [Student{id=5, name='吳剛'}, Class{id=3, name='汽修一班'}] [Student{id=6, name='王如花'}, Class{id=3, name='汽修一班'}] [Student{id=7, name='李志靜'}, Class{id=4, name='汽修二班'}] [Student{id=8, name='何王天'}, Class{id=4, name='汽修二班'}] */ }
/** * 查詢全部學生及其班級 */ @Test public void test24() { /* 迫切內鏈接 其實就是在普通的內鏈接 inner join 後添加關鍵字 fetch 將關聯表數據封裝到查詢對象的屬性中 */ Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); String hql = "from Student c join fetch c.clazz"; Query query = session.createQuery(hql); List<Student> list = query.list(); for (Student student : list) { System.out.println(String.format("%s %s", student, student.getClazz())); } transaction.commit(); /* Hibernate: select student0_.id as id1_1_0_, class1_.id as id1_0_1_, student0_.name as name2_1_0_, student0_.age as age3_1_0_, student0_.gender as gender4_1_0_, student0_.cid as cid5_1_0_, class1_.name as name2_0_1_ from student student0_ inner join class class1_ on student0_.cid=class1_.id Student{id=1, name='李四'} Class{id=1, name='軟件一班'} Student{id=2, name='張三'} Class{id=1, name='軟件一班'} Student{id=3, name='王五'} Class{id=2, name='軟件二班'} Student{id=4, name='趙六'} Class{id=2, name='軟件二班'} Student{id=5, name='吳剛'} Class{id=3, name='汽修一班'} Student{id=6, name='王如花'} Class{id=3, name='汽修一班'} Student{id=7, name='李志靜'} Class{id=4, name='汽修二班'} Student{id=8, name='何王天'} Class{id=4, name='汽修二班'} */ } /** * 查詢全部班級及屬於該班級的學生 */ @Test public void test25() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); String hql = "select distinct c from Class c join fetch c.students"; Query query = session.createQuery(hql); List<Class> list = query.list(); for (Class clazz : list) { System.out.println(String.format("%s %s", clazz, clazz.getStudents())); } transaction.commit(); /* Class{id=1, name='軟件一班'} [Student{id=2, name='張三'}, Student{id=1, name='李四'}] Class{id=2, name='軟件二班'} [Student{id=4, name='趙六'}, Student{id=3, name='王五'}] Class{id=3, name='汽修一班'} [Student{id=5, name='吳剛'}, Student{id=6, name='王如花'}] Class{id=4, name='汽修二班'} [Student{id=7, name='李志靜'}, Student{id=8, name='何王天'}] */ }
Query By Criteria,條件查詢,是一種更加面向對象化的查詢方式。緩存
@Test public void test15(){ Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Criteria criteria = session.createCriteria(Class.class); List<Class> list = criteria.list(); System.out.println(list); transaction.commit(); /* Hibernate: select this_.id as id1_0_0_, this_.name as name2_0_0_ from class this_ [Class{id=1, name='軟件一班'}, Class{id=2, name='軟件二班'}, Class{id=3, name='汽修一班'}, Class{id=4, name='汽修二班'}] */ }
@Test public void test16(){ Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Criteria criteria = session.createCriteria(Class.class); // 升序 criteria.addOrder(Order.asc("id")); // 降序 // criteria.addOrder(Order.desc("id")); List<Class> list = criteria.list(); System.out.println(list); transaction.commit(); /* Hibernate: select this_.id as id1_0_0_, this_.name as name2_0_0_ from class this_ order by this_.id asc [Class{id=1, name='軟件一班'}, Class{id=2, name='軟件二班'}, Class{id=3, name='汽修一班'}, Class{id=4, name='汽修二班'}] */ }
@Test public void test17() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Criteria criteria = session.createCriteria(Student.class); criteria.setFirstResult(0); // 數據起始索引 criteria.setMaxResults(2); // 每頁數據條數 List<Student> list = criteria.list(); System.out.println(list); transaction.commit(); /* Hibernate: select this_.id as id1_1_0_, this_.name as name2_1_0_, this_.age as age3_1_0_, this_.gender as gender4_1_0_, this_.cid as cid5_1_0_ from student this_ limit ? [Student{id=1, name='李四'}, Student{id=2, name='張三'}] */ }
/** * 簡單 and 條件查詢 * 查詢 name 包含 '王' 且 age>10 */ @Test public void test18() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Criteria criteria = session.createCriteria(Student.class); // 默認多個 criteria.add 的條件是用 and 鏈接 criteria.add(Restrictions.like("name", "%王%")); criteria.add(Restrictions.gt("age", 10)); List<Student> list = criteria.list(); System.out.println(list); transaction.commit(); /* Hibernate: select this_.id as id1_1_0_, this_.name as name2_1_0_, this_.age as age3_1_0_, this_.gender as gender4_1_0_, this_.cid as cid5_1_0_ from student this_ where this_.name like ? and this_.age>? [Student{id=3, name='王五'}, Student{id=6, name='王如花'}, Student{id=8, name='何王天'}] */ } /** * 簡單 or 條件查詢 * 查詢 name 包含 '王' 或 name 包含 '張' */ @Test public void test19() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Criteria criteria = session.createCriteria(Student.class); // or 條件能夠經過 Restrictions.or 方法實現 criteria.add(Restrictions.or(Restrictions.like("name", "%王%"), Restrictions.like("name", "%張%"))); List<Student> list = criteria.list(); System.out.println(list); transaction.commit(); /* Hibernate: select this_.id as id1_1_0_, this_.name as name2_1_0_, this_.age as age3_1_0_, this_.gender as gender4_1_0_, this_.cid as cid5_1_0_ from student this_ where ( this_.name like ? or this_.name like ? ) [Student{id=2, name='張三'}, Student{id=3, name='王五'}, Student{id=6, name='王如花'}, Student{id=8, name='何王天'}] */ } /** * 複雜 and 和 or 查詢 * 查詢 (name 包含 '王' 且 age>10) 或 name 包含 '張' */ @Test public void test20() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Criteria criteria = session.createCriteria(Student.class); // 經過 conjunction.add 添加的條件是 and 鏈接 Conjunction conjunction = Restrictions.conjunction(); conjunction.add(Restrictions.like("name", "%王%")); conjunction.add(Restrictions.gt("age", 10)); // 經過 disjunction.add 添加的條件是 or 鏈接 Disjunction disjunction = Restrictions.disjunction(); disjunction.add(conjunction); disjunction.add(Restrictions.like("name", "%張%")); criteria.add(disjunction); List<Student> list = criteria.list(); System.out.println(list); transaction.commit(); /* Hibernate: select this_.id as id1_1_0_, this_.name as name2_1_0_, this_.age as age3_1_0_, this_.gender as gender4_1_0_, this_.cid as cid5_1_0_ from student this_ where ( ( this_.name like ? and this_.age>? ) or this_.name like ? ) [Student{id=2, name='張三'}, Student{id=3, name='王五'}, Student{id=6, name='王如花'}, Student{id=8, name='何王天'}] */ }
/** * 聚合統計查詢 * 統計男女人數及最大年齡 */ @Test public void test21() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Criteria criteria = session.createCriteria(Student.class); /* criteria : add : 普通條件,where addOrder : 排序 setProjection : 聚合函數和 group by having */ ProjectionList projectionList = Projections.projectionList(); projectionList.add(Projections.groupProperty("gender")); projectionList.add(Projections.rowCount()); projectionList.add(Projections.max("age")); criteria.setProjection(projectionList); List<Object[]> list = criteria.list(); for (Object[] objects : list) { System.out.println(Arrays.toString(objects)); } transaction.commit(); /* Hibernate: select this_.gender as y0_, count(*) as y1_, max(this_.age) as y2_ from student this_ group by this_.gender [女, 3, 49] [男, 5, 39] */ }
/** * 離線條件查詢 * 查詢 name 包含 '一' */ @Test public void test22(){ DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Class.class); detachedCriteria.add(Restrictions.like("name", "%一%")); Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Criteria criteria = detachedCriteria.getExecutableCriteria(session); List<Class> list = criteria.list(); System.out.println(list); transaction.commit(); /* Hibernate: select this_.id as id1_0_0_, this_.name as name2_0_0_ from class this_ where this_.name like ? [Class{id=1, name='軟件一班'}, Class{id=3, name='汽修一班'}] */ }
Hibernate 支持的原生 SQL 查詢。session
/** * 查詢全部 Class,返回 Object[] List */ @Test public void test26() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); String sql = "select * from class"; SQLQuery sqlQuery = session.createSQLQuery(sql); List<Object[]> list = sqlQuery.list(); for (Object[] objects : list) { System.out.println(Arrays.toString(objects)); } transaction.commit(); /* Hibernate: select * from class [1, 軟件一班] [2, 軟件二班] [3, 汽修一班] [4, 汽修二班] */ } /** * 查詢全部 Class,返回 Class List */ @Test public void test27() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); String sql = "select * from class"; SQLQuery sqlQuery = session.createSQLQuery(sql); sqlQuery.addEntity(Class.class); List<Class> list = sqlQuery.list(); for (Class clazz : list) { System.out.println(clazz); } transaction.commit(); /* Hibernate: select * from class Class{id=1, name='軟件一班'} Class{id=2, name='軟件二班'} Class{id=3, name='汽修一班'} Class{id=4, name='汽修二班'} */ }
只有真正使用對象的屬性時纔會發送 SQL 進行查詢。如: session.load(Student.class,1); 。app
指的是查詢某個類的對象時,針對這個類的對象是否使用延遲加載。ide
一、將持久化類以 final 修飾。函數
二、經過調用 Hibernate.initialize(proxy); 。工具
指的是查詢到某個對象後,再查詢其關聯的對象是否使用延遲加載。fetch
/** * 懶加載 * 修改映射文件 : * com/zze/bean/Class.hbm.xml : * <class name="com.zze.bean.Class" table="class" lazy="true"> * lazy 默認爲 true */ @Test public void test27() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Class clazz = session.load(Class.class, 1); System.out.println(clazz.getClass()); // class com.zze.bean.Class_$$_jvst718_0 System.out.println(clazz); // 發出 SQL transaction.commit(); } /** * 當即加載 * 修改映射文件 : * com/zze/bean/Class.hbm.xml : * <class name="com.zze.bean.Class" table="class" lazy="false"> */ @Test public void test28() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Class clazz = session.load(Class.class, 1); // 發出 SQL System.out.println(clazz.getClass()); // class com.zze.bean.Class System.out.println(clazz); transaction.commit(); }
/** * 懶加載 * 修改映射文件 : * com/zze/bean/Class.hbm.xml : * <set name="students" cascade="save-update" lazy="true"> * lazy 默認爲 true */ @Test public void test29() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Class clazz = session.get(Class.class, 1); Set<Student> students = clazz.getStudents(); System.out.println(students); // 發出 SQL transaction.commit(); } /** * 即時加載 * 修改映射文件 : * com/zze/bean/Class.hbm.xml : * <set name="students" cascade="save-update" lazy="false"> */ @Test public void test30() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Class clazz = session.get(Class.class, 1); Set<Student> students = clazz.getStudents(); // 發出 SQL System.out.println(students); transaction.commit(); } /** * 懶加載 * 修改映射文件 : * com/zze/bean/Student.hbm.xml : * <many-to-one name="clazz" lazy="proxy" column="cid" class="com.zze.bean.Class"/> * com/zze/bean/Class.hbm.xml : * <class name="com.zze.bean.Class" table="class" lazy="true"> * <p> * proxy : 默認值,表示引用關聯類的加載策略。 */ @Test public void test31() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Student student = session.get(Student.class, 1); Class clazz = student.getClazz(); System.out.println(clazz); // 發出 SQL transaction.commit(); } /** * 即時加載 * 當關聯類的 lazy="false" 時,不管當前類 many-to-one 標籤上的 lazy 如何配置,都是即時加載。 * 修改映射文件 : * com/zze/bean/Student.hbm.xml : * * <many-to-one name="clazz" lazy="proxy" column="cid" class="com.zze. * com/zze/bean/Class.hbm.xml : * * <class name="com.zze.bean.Class" table="class" lazy="false"> * 或 : * com/zze/bean/Student.hbm.xml : * * <many-to-one name="clazz" lazy="false" column="cid" class="com.zze.bean.Class"/> * com/zze/bean/Class.hbm.xml : * * <class name="com.zze.bean.Class" table="class" lazy="true"> */ @Test public void test32() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Student student = session.get(Student.class, 1); Class clazz = student.getClazz(); // 發出 SQL System.out.println(clazz); transaction.commit(); }
經過一個對象抓取關聯對象須要發送 SQL ,SQL 如何發送及 SQL 的發送規則就能夠經過抓取策略進行配置。
經過 <set> 或 <many-to-one> 上的 fetch 屬性進行配置。
要考慮fetch 和這些標籤上的 lazy 如何配置才能最大化優化發送的 SQL 語句。
抓取策略,控制 SQL 語句格式。
在這裏 fetch 有三個可選值:
select : 默認值,發送普通 select 語句查詢關聯對象。
join: 發送一條迫切左外鏈接查詢關聯對象。
subselect : 發送子查詢查詢關聯對象。
延遲加載,控制查詢關聯對象時是否使用懶加載。
在這裏 lazy 有三個可選值:
true : 默認值,查詢關聯對象時,使用延遲加載。
false : 查詢關聯對象時,不使用延遲加載。
extra : 及其懶惰。
/** * com/zze/bean/Class.hbm.xml * 默認值: * <set name="students" cascade="save-update" fetch="select" lazy="true"> */ @Test public void test33() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Class clazz = session.get(Class.class, 1); for (Student student : clazz.getStudents()) { System.out.println(student);// 發送 SQL } transaction.commit(); /* Hibernate: select class0_.id as id1_0_0_, class0_.name as name2_0_0_ from class class0_ where class0_.id=? Hibernate: select students0_.cid as cid5_1_0_, students0_.id as id1_1_0_, students0_.id as id1_1_1_, students0_.name as name2_1_1_, students0_.age as age3_1_1_, students0_.gender as gender4_1_1_, students0_.cid as cid5_1_1_ from student students0_ where students0_.cid=? Student{id=2, name='張三'} Student{id=1, name='李四'} */ } /** * com/zze/bean/Class.hbm.xml * * <set name="students" cascade="save-update" fetch="select" lazy="false"> */ @Test public void test34() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Class clazz = session.get(Class.class, 1); //發送 2 條 SQL for (Student student : clazz.getStudents()) { System.out.println(student); } transaction.commit(); /* Hibernate: select class0_.id as id1_0_0_, class0_.name as name2_0_0_ from class class0_ where class0_.id=? Hibernate: select students0_.cid as cid5_1_0_, students0_.id as id1_1_0_, students0_.id as id1_1_1_, students0_.name as name2_1_1_, students0_.age as age3_1_1_, students0_.gender as gender4_1_1_, students0_.cid as cid5_1_1_ from student students0_ where students0_.cid=? Student{id=2, name='張三'} Student{id=1, name='李四'} */ } /** * com/zze/bean/Class.hbm.xml * * <set name="students" cascade="save-update" fetch="select" lazy="extra"> */ @Test public void test35() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Class clazz = session.get(Class.class, 1); System.out.println(clazz.getStudents().size()); // 針對數量發送一條sql transaction.commit(); /* Hibernate: select class0_.id as id1_0_0_, class0_.name as name2_0_0_ from class class0_ where class0_.id=? Hibernate: select count(id) from student where cid =? */ } /** * com/zze/bean/Class.hbm.xml * fetch="join" 時,lazy 失效 * <set name="students" cascade="save-update" fetch="join" lazy="true"> */ public void test36() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Class clazz = session.get(Class.class, 1);// 發送 SQL for (Student student : clazz.getStudents()) { System.out.println(student); } transaction.commit(); /* Hibernate: select class0_.id as id1_0_0_, class0_.name as name2_0_0_, students1_.cid as cid5_1_1_, students1_.id as id1_1_1_, students1_.id as id1_1_2_, students1_.name as name2_1_2_, students1_.age as age3_1_2_, students1_.gender as gender4_1_2_, students1_.cid as cid5_1_2_ from class class0_ left outer join student students1_ on class0_.id=students1_.cid where class0_.id=? Student{id=2, name='張三'} Student{id=1, name='李四'} */ } /** * com/zze/bean/Class.hbm.xml * * <set name="students" cascade="save-update" fetch="subselect" lazy="true"> */ @Test public void test37() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Query query = session.createQuery("from Class"); List<Class> list = query.list(); for (Class clazz : list) { Set<Student> students = clazz.getStudents(); // 發送 SQL System.out.println(students); } transaction.commit(); /* Hibernate: select class0_.id as id1_0_, class0_.name as name2_0_ from class class0_ Hibernate: select students0_.cid as cid5_1_1_, students0_.id as id1_1_1_, students0_.id as id1_1_0_, students0_.name as name2_1_0_, students0_.age as age3_1_0_, students0_.gender as gender4_1_0_, students0_.cid as cid5_1_0_ from student students0_ where students0_.cid in ( select class0_.id from class class0_ ) [Student{id=1, name='李四'}, Student{id=2, name='張三'}] [Student{id=4, name='趙六'}, Student{id=3, name='王五'}] [Student{id=5, name='吳剛'}, Student{id=6, name='王如花'}] [Student{id=7, name='李志靜'}, Student{id=8, name='何王天'}] */ } /** * com/zze/bean/Class.hbm.xml * * <set name="students" cascade="save-update" fetch="subselect" lazy="false"> */ @Test public void test38() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Query query = session.createQuery("from Class"); List<Class> list = query.list(); // 發送 SQL for (Class clazz : list) { Set<Student> students = clazz.getStudents(); System.out.println(students); } transaction.commit(); /* Hibernate: select class0_.id as id1_0_, class0_.name as name2_0_ from class class0_ Hibernate: select students0_.cid as cid5_1_1_, students0_.id as id1_1_1_, students0_.id as id1_1_0_, students0_.name as name2_1_0_, students0_.age as age3_1_0_, students0_.gender as gender4_1_0_, students0_.cid as cid5_1_0_ from student students0_ where students0_.cid in ( select class0_.id from class class0_ ) [Student{id=1, name='李四'}, Student{id=2, name='張三'}] [Student{id=4, name='趙六'}, Student{id=3, name='王五'}] [Student{id=5, name='吳剛'}, Student{id=6, name='王如花'}] [Student{id=7, name='李志靜'}, Student{id=8, name='何王天'}] */ }
抓取策略,控制 SQL 語句格式。
在這裏 fetch 有兩個可選值:
select : 默認值,發送普通的 select 語句查詢關聯對象。
join : 發送一條迫切左外鏈接查詢關聯對象。
延遲加載,控制查詢關聯對象時是否使用懶加載。
在這裏 lazy 有三個可選值:
proxy : 默認值,引用關聯對象類的類級別加載策略。
flase : 查詢關聯對象時,不使用延遲加載。
no-proxy:不使用。
/** * com/zze/bean/Student.hbm.xml * 默認值 * <many-to-one name="clazz" column="cid" class="com.zze.bean.Class" fetch="select" lazy="proxy"/> * * com/zze/bean/Class.hbm.xml * <class name="com.zze.bean.Class" table="class" lazy="true"> */ @Test public void test39(){ Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Student student = session.get(Student.class, 1); System.out.println(student.getClazz()); // 發送 SQL transaction.commit(); /* Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_, student0_.age as age3_1_0_, student0_.gender as gender4_1_0_, student0_.cid as cid5_1_0_ from student student0_ where student0_.id=? Hibernate: select class0_.id as id1_0_0_, class0_.name as name2_0_0_ from class class0_ where class0_.id=? Class{id=1, name='軟件一班'} */ } /** * com/zze/bean/Student.hbm.xml * 默認值 * <many-to-one name="clazz" column="cid" class="com.zze.bean.Class" fetch="select" lazy="proxy"/> * * com/zze/bean/Class.hbm.xml * <class name="com.zze.bean.Class" table="class" lazy="false"> */ @Test public void test40(){ Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Student student = session.get(Student.class, 1);// 一次發送 2 條 SQL System.out.println(student.getClazz()); transaction.commit(); /* Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_, student0_.age as age3_1_0_, student0_.gender as gender4_1_0_, student0_.cid as cid5_1_0_ from student student0_ where student0_.id=? Hibernate: select class0_.id as id1_0_0_, class0_.name as name2_0_0_ from class class0_ where class0_.id=? Class{id=1, name='軟件一班'} */ } /** * com/zze/bean/Student.hbm.xml * fetch="join" 時,lazy 失效 * <many-to-one name="clazz" column="cid" class="com.zze.bean.Class" fetch="join" lazy="proxy"/> */ @Test public void test41(){ Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Student student = session.get(Student.class, 1);// 一條關聯 SQL System.out.println(student.getClazz()); transaction.commit(); /* Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_, student0_.age as age3_1_0_, student0_.gender as gender4_1_0_, student0_.cid as cid5_1_0_, class1_.id as id1_0_1_, class1_.name as name2_0_1_ from student student0_ left outer join class class1_ on student0_.cid=class1_.id where student0_.id=? Class{id=1, name='軟件一班'} */ }
一批指定數量的關聯數據一塊兒查詢。
/** * 查詢全部班級 及 全部班級下的學生信息 * 默認狀況下,查詢全部班級會發一條 SQL,而後每次查詢班級上的學生也會發送一條 SQL * 即以下有 4 個班級,會發 5 條SQL */ @Test public void test42() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Query query = session.createQuery("from Class"); List<Class> list = query.list(); for (Class clazz : list) { System.out.println(clazz); for (Student student : clazz.getStudents()) { System.out.println(student); } } transaction.commit(); /* Hibernate: select class0_.id as id1_0_, class0_.name as name2_0_ from class class0_ Class{id=1, name='軟件一班'} Hibernate: select students0_.cid as cid5_1_0_, students0_.id as id1_1_0_, students0_.id as id1_1_1_, students0_.name as name2_1_1_, students0_.age as age3_1_1_, students0_.gender as gender4_1_1_, students0_.cid as cid5_1_1_ from student students0_ where students0_.cid=? Student{id=1, name='李四'} Student{id=2, name='張三'} Class{id=2, name='軟件二班'} Hibernate: select students0_.cid as cid5_1_0_, students0_.id as id1_1_0_, students0_.id as id1_1_1_, students0_.name as name2_1_1_, students0_.age as age3_1_1_, students0_.gender as gender4_1_1_, students0_.cid as cid5_1_1_ from student students0_ where students0_.cid=? Student{id=4, name='王五'} Student{id=3, name='趙六'} Class{id=3, name='汽修一班'} Hibernate: select students0_.cid as cid5_1_0_, students0_.id as id1_1_0_, students0_.id as id1_1_1_, students0_.name as name2_1_1_, students0_.age as age3_1_1_, students0_.gender as gender4_1_1_, students0_.cid as cid5_1_1_ from student students0_ where students0_.cid=? Student{id=5, name='王如花'} Student{id=6, name='吳剛'} Class{id=4, name='汽修二班'} Hibernate: select students0_.cid as cid5_1_0_, students0_.id as id1_1_0_, students0_.id as id1_1_1_, students0_.name as name2_1_1_, students0_.age as age3_1_1_, students0_.gender as gender4_1_1_, students0_.cid as cid5_1_1_ from student students0_ where students0_.cid=? Student{id=8, name='李志靜'} Student{id=7, name='何王天'} */ } /** * com/zze/bean/Class.hbm.xml * * <set name="students" cascade="save-update" batch-size="4"> * <p> * 一次抓取 4 條,就只須要發送 2 次 SQL * 一次查詢全部班級,一次查詢全部班級下的學生 */ @Test public void test43() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Query query = session.createQuery("from Class"); List<Class> list = query.list(); for (Class clazz : list) { System.out.println(clazz); for (Student student : clazz.getStudents()) { System.out.println(student); } } transaction.commit(); /* Hibernate: select class0_.id as id1_0_, class0_.name as name2_0_ from class class0_ Class{id=1, name='軟件一班'} Hibernate: select students0_.cid as cid5_1_1_, students0_.id as id1_1_1_, students0_.id as id1_1_0_, students0_.name as name2_1_0_, students0_.age as age3_1_0_, students0_.gender as gender4_1_0_, students0_.cid as cid5_1_0_ from student students0_ where students0_.cid in ( ?, ?, ?, ? ) Student{id=1, name='李四'} Student{id=2, name='張三'} Class{id=2, name='軟件二班'} Student{id=4, name='王五'} Student{id=3, name='趙六'} Class{id=3, name='汽修一班'} Student{id=5, name='王如花'} Student{id=6, name='吳剛'} Class{id=4, name='汽修二班'} Student{id=7, name='何王天'} Student{id=8, name='李志靜'} */ } /** * 查詢全部學生 及 全部學生所屬班級信息 * 默認狀況下,查詢全部學生會發送 1 條 SQL,而後每次查詢每一個學生的所屬班級時也會發送一條 SQL, * 有 8 個學生,但一共有 4 個班級,因爲一級緩存的做用,查詢班級須要發送 4 條 SQL * 共發 5 條 SQL */ @Test public void test44() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Query query = session.createQuery("from Student"); List<Student> list = query.list(); for (Student student : list) { System.out.println(student.getClazz()); } transaction.commit(); /* Hibernate: select student0_.id as id1_1_, student0_.name as name2_1_, student0_.age as age3_1_, student0_.gender as gender4_1_, student0_.cid as cid5_1_ from student student0_ Hibernate: select class0_.id as id1_0_0_, class0_.name as name2_0_0_ from class class0_ where class0_.id=? Class{id=1, name='軟件一班'} Class{id=1, name='軟件一班'} Hibernate: select class0_.id as id1_0_0_, class0_.name as name2_0_0_ from class class0_ where class0_.id=? Class{id=2, name='軟件二班'} Class{id=2, name='軟件二班'} Hibernate: select class0_.id as id1_0_0_, class0_.name as name2_0_0_ from class class0_ where class0_.id=? Class{id=3, name='汽修一班'} Class{id=3, name='汽修一班'} Hibernate: select class0_.id as id1_0_0_, class0_.name as name2_0_0_ from class class0_ where class0_.id=? Class{id=4, name='汽修二班'} Class{id=4, name='汽修二班'} */ } /** * com/zze/bean/Class.hbm.xml * <class name="com.zze.bean.Class" table="class" batch-size="3"> * <p> * many-to-one 關係時需在關聯屬性類映射文件下配置 batch-size * <p> * 查詢全部學生 1 條 SQL,查詢全部班級每次抓取 3 條,一共 4 個班級,會發 2 次 SQL */ @Test public void test45() { Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); Query query = session.createQuery("from Student"); List<Student> list = query.list(); for (Student student : list) { System.out.println(student.getClazz()); } transaction.commit(); /* Hibernate: select student0_.id as id1_1_, student0_.name as name2_1_, student0_.age as age3_1_, student0_.gender as gender4_1_, student0_.cid as cid5_1_ from student student0_ Hibernate: select class0_.id as id1_0_0_, class0_.name as name2_0_0_ from class class0_ where class0_.id in ( ?, ?, ? ) Class{id=1, name='軟件一班'} Class{id=1, name='軟件一班'} Class{id=2, name='軟件二班'} Class{id=2, name='軟件二班'} Class{id=3, name='汽修一班'} Class{id=3, name='汽修一班'} Hibernate: select class0_.id as id1_0_0_, class0_.name as name2_0_0_ from class class0_ where class0_.id=? Class{id=4, name='汽修二班'} Class{id=4, name='汽修二班'} */ }