Hibernate笔记二

1.延迟加载(懒加载)

概念

       需要用到该数据的时候才要加载

种类

类的延迟加载

案例

说明:注意:使用的是Load方法

1、  执行22行代码的时候,不发出sql语句,说明类的延迟加载和主键没有关系

2、  执行23行代码的时候,发出sql语句,说明只有在得到具体属性的时候才要发出sql语句。

3、  Session.load方法返回的对象是

而该对象是由javassist的jar包生成的,从代码结构可以看出该代理对象是持久化类的子类。

4、  在Classes.hbm.xml文件中

 

Lazy的属性默认为true

     5、如果把上述的lazy改成false,则类的延迟加载不起作用了,默认为延迟加载。

集合的延迟加载

案例1

 

值说明

  默认情况是true,当遍历集合的时候发出sql语句

  Lazy的值为false,当加载classes的时候就把student加载出来了

  Extra是更进一步的延迟加载策略,如果求大小、平均数、和等

案例2

案例3

当执行到上述的student.size()的时候,发出了如下的sql语句:

 

该sql语句只加载了大小,并没有加载具体的数据

Many-to-one的延迟加载

 

No-proxy 延迟加载   默认值

Proxy是加强版的延迟加载

因为是通过多的一方加载一的一方,所以对效率影响不大,所以一般情况下用默认值即可。

总结

       延迟加载是通过什么时候发出sql语句来优化性能的。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <hibernate-mapping>
 5     <class name="com.itheima09.hibernate.domain.Classes" lazy="true">
 6         <id name="cid" length="5">
 7             <generator class="increment"></generator>
 8         </id>
 9         <property name="name" length="20"></property>
10         <property name="description" length="100"></property>
11         <!-- 
12             fetch 抓取策略
13               join  通过做外链接
14               select  默认值
15               subselect
16          -->
17         <set name="students" cascade="all" fetch="subselect" lazy="extra">
18             <!-- 
19                 key代表外键
20                 用来关联classes表和student表,用于在hibernate低层生成sql语句
21              -->
22             <key>
23                 <column name="cid"></column>
24             </key>
25             <!-- 
26                 建立类与类之间的关联,用于客户端的编码
27              -->
28             <one-to-many class="com.itheima09.hibernate.domain.Student"/>
29         </set>
30     </class>
31 </hibernate-mapping>
Classes.hbm.xml
 1 package com.itheima09.hibernate.domain;
 2 
 3 import java.io.Serializable;
 4 import java.util.Set;
 5 
 6 public class Classes implements Serializable{
 7     private Long cid;
 8     private String name;
 9     private String description;
10     private Set<Student> students;
11     public Long getCid() {
12         return cid;
13     }
14     public void setCid(Long cid) {
15         this.cid = cid;
16     }
17     public String getName() {
18         return name;
19     }
20     public void setName(String name) {
21         this.name = name;
22     }
23     public String getDescription() {
24         return description;
25     }
26     public void setDescription(String description) {
27         this.description = description;
28     }
29     public Set<Student> getStudents() {
30         return students;
31     }
32     public void setStudents(Set<Student> students) {
33         this.students = students;
34     }
35 }
Classes.java
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <hibernate-mapping>
 5     <class name="com.itheima09.hibernate.domain.Student">
 6         <id name="sid" length="5">
 7             <generator class="increment"></generator>
 8         </id>
 9         <property name="name" length="20"></property>
10         <property name="description" length="100"></property>
11         <!-- 
12             column 为外键
13          -->
14         <many-to-one name="classes" column="cid" 
15             class="com.itheima09.hibernate.domain.Classes" cascade="save-update" lazy="false">
16         </many-to-one>
17     </class>
18 </hibernate-mapping>
Student.hbm.xml
 1 import java.io.Serializable;
 2 
 3 public class Student implements Serializable{
 4     private Long sid;
 5     private String name;
 6     private String description;
 7     private Classes classes;
 8     
 9     public Classes getClasses() {
10         return classes;
11     }
12     public void setClasses(Classes classes) {
13         this.classes = classes;
14     }
15     public Long getSid() {
16         return sid;
17     }
18     public void setSid(Long sid) {
19         this.sid = sid;
20     }
21     public String getName() {
22         return name;
23     }
24     public void setName(String name) {
25         this.name = name;
26     }
27     public String getDescription() {
28         return description;
29     }
30     public void setDescription(String description) {
31         this.description = description;
32     }
33 }
Student.java
 1 package com.itheima09.hibernate.lazy;
 2 
 3 import java.util.List;
 4 import java.util.Set;
 5 
 6 import org.hibernate.Session;
 7 import org.hibernate.Transaction;
 8 import org.junit.Test;
 9 
10 import com.itheima09.hibernate.domain.Classes;
11 import com.itheima09.hibernate.domain.Student;
12 import com.itheima09.hibernate.utils.HibernateUtils;
13 
14 public class LazyTest extends HibernateUtils{
15     /**
16      * 类的延迟加载
17      */
18     @Test
19     public void testload(){
20         Session session  = sessionFactory.openSession();
21         Classes classes  = (Classes)session.load(Classes.class, 1L);
22         System.out.println(classes.getCid());//不发出sql
23         session.close();
24         System.out.println(classes.getName());//发出sql
25     }
26     
27     @Test
28     public void testSet(){
29         Session session = sessionFactory.openSession();
30         Classes classes = (Classes)session.get(Classes.class, 1L);
31         Set<Student> students = classes.getStudents();
32         for(Student student:students){
33             System.out.println(student.getName());
34         }
35     }
36     
37     @Test
38     public void testSet_Extra(){
39         Session session = sessionFactory.openSession();
40         Classes classes = (Classes)session.get(Classes.class, 1L);
41         Set<Student> students = classes.getStudents();
42         System.out.println(students.size());
43         session.close();
44     }
45 }
LazyTest.java
 1 import org.hibernate.SessionFactory;
 2 import org.hibernate.cfg.Configuration;
 3 
 4 public class HibernateUtils {
 5     public static SessionFactory sessionFactory;
 6     static{
 7         Configuration configuration = new Configuration();
 8         configuration.configure();
 9         sessionFactory = configuration.buildSessionFactory();
10     }
11 }
HibernateUtils.java

抓取策略和延迟加载的结合

研究对象

       Set集合

1、  当fetch为join时,lazy失效

2、  当fetch为select时

如果lazy为true/extra

        当遍历集合的时候,发出加载集合的sql语句

如果lazy为false

        当获取班级的时候,发出加载集合的sql语句

3、  当fetch为subselect时和上面的情况一致。

二级缓存

概念

1、  是sessionFactory级别的缓存

2、  存放的是公有数据:共享数据

3、  二级缓存的生命周期是随着hibernate容器启动就开了,hibernate销毁,结束。

4、  Hibernate本身对二级缓存没有提供实现,是借助第三方插件实现的。

特点

       公有数据的特征:

1、  一般情况下保持不变

2、  所有的人都能访问

3、  访问的频率比较高

4、  安全性不是特别高的数据

配置(重点)

1、  在hibernate的配置文件中

    2、二级缓存分为类的二级缓存和集合的二级缓存

       3、开启classes类的二级缓存

案例1

 

说明:

      当第二次执行session.get方法的时候,并没有发出sql语句

案例2

      

说明:session.save方法不进二级缓存

案例3

说明:

     Update方法不能让一个对象进入到二级缓存中。

案例4

说明:

     执行55行代码的时候,把classes表中的所有的对象进入到了二级缓存中

        执行59行代码的时候,重新从数据库中查找记录

     所以createQuery(hql).list方法能把一个对象放入到二级缓存中,但是不利用二级缓存获取对象。

案例5

       在classpath的根目录下放置一个ehcache.xml文件

 

从上述的配置可以看出,classes对象在内存中存放的数量最多为5个,多余的对象将存在磁盘上。

 

查找classes表中所有的对象,在内存中放置5个对象,剩余的对象将被存在磁盘上。

案例6

      

 相当于开启了classes类中的set集合的二级缓存

 

把集合放入到了二级缓存中。

读写策略

       Usage

              Ready-only

                     只能把一个对象放入到二级缓存中不能修改

       Read-write

            能把一个对象放入到二级缓存中,也能修改

 1 <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 2          xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
 3          
 4     <diskStore path="e:\TEMP1"/>
 5     <defaultCache
 6             maxElementsInMemory="12"
 7             eternal="false"
 8             timeToIdleSeconds="1200"
 9             timeToLiveSeconds="1200"
10             overflowToDisk="false"
11             maxElementsOnDisk="10000000"
12             diskPersistent="false"
13             diskExpiryThreadIntervalSeconds="120"
14             memoryStoreEvictionPolicy="LRU"
15             />
16             
17        <Cache
18             name="com.itheima09.hibernate.domain.Classes"
19             maxElementsInMemory="5" 
20             eternal="false"
21             timeToIdleSeconds="120"
22             timeToLiveSeconds="120"
23             overflowToDisk="true"
24             maxElementsOnDisk="10000000"
25             diskPersistent="false"
26             diskExpiryThreadIntervalSeconds="120"
27             memoryStoreEvictionPolicy="LRU"
28             />
29 </ehcache>
ehcache.xml
 1 <?xml version='1.0' encoding='utf-8'?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 5 <hibernate-configuration>
 6     <!-- 
 7         一个session-factory代表一个数据库
 8      -->
 9 <session-factory>
10     <!-- 
11         链接数据库的用户名
12     -->
13     <property name="connection.username">root</property>
14     <!-- 
15         链接数据库的密码
16     -->
17     <property name="connection.password">root</property>
18     <!-- 
19         链接数据库的驱动
20     -->
21     <property name="connection.driver_class">
22         com.mysql.jdbc.Driver
23     </property>
24     <!-- 
25         链接数据库的url
26     -->
27     <property name="connection.url">
28         jdbc:mysql://localhost:3306/itheima09_hibernate
29     </property>
30     <!-- 
31         方言
32         告诉hibernate用什么样的数据库
33     -->
34     <property name="dialect">
35         org.hibernate.dialect.MySQLDialect
36     </property>
37     <!-- 
38         validate 加载hibernate时,验证数据库的结构
39         update  加载hibernate时,检查数据库,如果表不存在,则创建,如果存在,则更新
40         create  每次加载hiberante,都会创建表
41         create-drop  每次加载hiberante,创建,卸载hiberante时,销毁
42     -->
43     <property name="hbm2ddl.auto">update</property>
44     <!-- 
45         显示sql语句
46     -->
47     <property name="show_sql">true</property>
48     <!-- 
49         格式化sql语句
50     -->
51     <property name="format_sql">true</property>
52     <!-- 
53         session要从当前线程中产生
54     -->
55     <property name="current_session_context_class">thread</property>
56     <!-- 
57         开启二级缓存
58      -->
59      <property name="cache.use_second_level_cache">true</property>
60      <!-- 
61         二级缓存的供应商
62      -->
63     <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
64     <!-- 
65         开启hibernate的统计机制
66      -->
67      <property name="hibernate.generate_statistics">true</property>
68     <!-- 
69         加载映射文件
70     -->
71     <mapping resource="com/itheima09/hibernate/domain/Classes.hbm.xml" />
72     <mapping resource="com/itheima09/hibernate/domain/Student.hbm.xml" />
73 </session-factory>
74 </hibernate-configuration>
hibernate.cfg.xml
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <hibernate-mapping>
 5     <class name="com.itheima09.hibernate.domain.Classes" lazy="true">
 6         <cache usage="read-only"/>
 7         <id name="cid" length="5">
 8             <generator class="increment"></generator>
 9         </id>
10         <property name="name" length="20"></property>
11         <property name="description" length="100"></property>
12         <!-- 
13             fetch 抓取策略
14               join  通过做外链接
15               select  默认值
16               subselect
17          -->
18         <set name="students" cascade="all" fetch="select" lazy="true">
19             <cache usage="read-only"/>
20             <!-- 
21                 key代表外键
22                 用来关联classes表和student表,用于在hibernate低层生成sql语句
23              -->
24             <key>
25                 <column name="cid"></column>
26             </key>
27             <!-- 
28                 建立类与类之间的关联,用于客户端的编码
29              -->
30             <one-to-many class="com.itheima09.hibernate.domain.Student"/>
31         </set>
32     </class>
33 </hibernate-mapping>
Classes.hbm.xml
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <hibernate-mapping>
 5     <class name="com.itheima09.hibernate.domain.Student">
 6         <id name="sid" length="5">
 7             <generator class="increment"></generator>
 8         </id>
 9         <property name="name" length="20"></property>
10         <property name="description" length="100"></property>
11         <!-- 
12             column 为外键
13          -->
14         <many-to-one name="classes" column="cid" 
15             class="com.itheima09.hibernate.domain.Classes" cascade="save-update" lazy="false">
16         </many-to-one>
17     </class>
18 </hibernate-mapping>
Student.hbm.xml
 1 import java.util.Iterator;
 2 import java.util.List;
 3 import java.util.Set;
 4 
 5 import org.hibernate.Session;
 6 import org.hibernate.Transaction;
 7 import org.junit.Test;
 8 import org.omg.CORBA.TRANSACTION_MODE;
 9 
10 import com.itheima09.hibernate.domain.Classes;
11 import com.itheima09.hibernate.domain.Student;
12 import com.itheima09.hibernate.utils.HibernateUtils;
13 
14 public class SessionFactoryCacheTest extends HibernateUtils{
15     @Test
16     public void testGet(){
17         Session session = sessionFactory.openSession();
18         Classes classes = (Classes)session.get(Classes.class, 1L);
19         System.out.println(sessionFactory.getStatistics().getEntityLoadCount());//输出的值为1
20         session.close();//一级缓存已经关闭了
21         session = sessionFactory.openSession();//该session是一个新的session
22         classes = (Classes)session.get(Classes.class, 1L);//没有发出sql语句
23         session.close();
24     }
25     
26     @Test
27     public void testSaveClasses(){
28         Session session = sessionFactory.getCurrentSession();
29         Transaction transaction = session.beginTransaction();
30         Classes classes = new Classes();
31         classes.setName("aaa");
32         session.save(classes);
33         System.out.println(sessionFactory.getStatistics().getEntityLoadCount());//输出为0
34         transaction.commit();
35     }
36     
37     @Test
38     public void testUpdateClasses(){
39         Session session = sessionFactory.getCurrentSession();
40         Transaction transaction = session.beginTransaction();
41         Classes classes = new Classes();
42         classes.setCid(1L);
43         classes.setName("aa");
44         session.update(classes);
45         System.out.println(sessionFactory.getStatistics().getEntityLoadCount());//输出为0
46         transaction.commit();
47     }
48     
49     @Test
50     public void testQuery() throws Exception{
51         Session session = sessionFactory.openSession();
52         //把classes表中的所有的数据放在了二级缓存中
53         List<Classes> classesList = session.createQuery("from Classes").list();
54         System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
55         session.close();
56         session = sessionFactory.openSession();
57         List<Classes> list = session.createQuery("from Classes where cid in(1,2,3,4)").list();
58         for(Classes classes1:list){
59             Set<Student> students = classes1.getStudents();
60             for(Student student:students){
61                 System.out.println(student.getName());
62             }
63         }
64         session.close();
65         Thread.sleep(1000l);
66     }
67     
68     @Test
69     public void testOverToDisk() throws Exception{
70         Session session = sessionFactory.openSession();
71         //把classes表中的所有的数据放在了二级缓存中
72         List<Classes> classesList = session.createQuery("from Classes").list();
73         session.close();
74         Thread.sleep(1000l);
75     }
76     
77     @Test
78     public void testSet(){
79         Session session = sessionFactory.openSession();
80         Classes classes = (Classes)session.get(Classes.class, 1L);
81         Set<Student> students = classes.getStudents();
82         for(Student student:students){
83             System.out.println(student.getName());
84         }
85         //输出为1
86         System.out.println(sessionFactory.getStatistics().getCollectionLoadCount());
87         session.close();
88     }
89 }
SessionFactoryCacheTest.java

查询缓存

概念

1、  查询缓存就是数据缓存

能够按照需求加载数据

2、  一级缓存和二级缓存都是对象缓存

在表中的一行有多少个字段,就会加载多少个数据

配置

1、  建立在二级缓存基础之上的

2、  开启查询缓存

 

案例1

说明:

       当执行24行代码的时候,发出sql语句

       当执行30行代码的时候,没有发出sql语句,因为利用了查询缓存

案例2

  

说明:

1、  当两次query.list的时候,都会发出sql语句

2、  原因是两次的查询hql语句不一样。

3、  从这里可以看出查询缓存的命中率比较低

案例3

从list的内存快照中可以看出,list里存放的不是持久化对象,而是name属性的值。

一级缓存和二级缓存存放的是持久化对象,如果集合中存放的不是持久化对象,则不能进入二级缓存中,但是能够进入查询缓存中。

数据缓存和对象缓存

1、  一级缓存和二级缓存是对象缓存,只能缓存持久化对象

2、  对象缓存的特别就是要把数据库表中所有的字段全部查询出来

3、  查询缓存是数据缓存,可以查询一个对象的部分属性,而且可以把部分属性放入到查询缓存中,查询缓存也支持对象。

 1 <?xml version='1.0' encoding='utf-8'?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 5 <hibernate-configuration>
 6     <!-- 
 7         一个session-factory代表一个数据库
 8      -->
 9 <session-factory>
10     <!-- 
11         链接数据库的用户名
12     -->
13     <property name="connection.username">root</property>
14     <!-- 
15         链接数据库的密码
16     -->
17     <property name="connection.password">root</property>
18     <!-- 
19         链接数据库的驱动
20     -->
21     <property name="connection.driver_class">
22         com.mysql.jdbc.Driver
23     </property>
24     <!-- 
25         链接数据库的url
26     -->
27     <property name="connection.url">
28         jdbc:mysql://localhost:3306/itheima09_hibernate
29     </property>
30     <!-- 
31         方言
32         告诉hibernate用什么样的数据库
33     -->
34     <property name="dialect">
35         org.hibernate.dialect.MySQLDialect
36     </property>
37     <!-- 
38         validate 加载hibernate时,验证数据库的结构
39         update  加载hibernate时,检查数据库,如果表不存在,则创建,如果存在,则更新
40         create  每次加载hiberante,都会创建表
41         create-drop  每次加载hiberante,创建,卸载hiberante时,销毁
42     -->
43     <property name="hbm2ddl.auto">update</property>
44     <!-- 
45         显示sql语句
46     -->
47     <property name="show_sql">true</property>
48     <!-- 
49         格式化sql语句
50     -->
51     <property name="format_sql">true</property>
52     <!-- 
53         session要从当前线程中产生
54     -->
55     <property name="current_session_context_class">thread</property>
56     <!-- 
57         开启二级缓存
58     -->
59     <property name="cache.use_second_level_cache">true</property>
60     <!-- 
61         二级缓存的供应商
62     -->
63     <property name="cache.provider_class">
64         org.hibernate.cache.EhCacheProvider
65     </property>
66     <!-- 
67         开启hibernate的统计机制
68     -->
69     <property name="hibernate.generate_statistics">true</property>
70     <!-- 
71         开启查询缓存
72      -->
73     <property name="cache.use_query_cache">true</property>
74     <!-- 
75         加载映射文件
76     -->
77     <mapping resource="com/itheima09/hibernate/domain/Classes.hbm.xml" />
78     <mapping resource="com/itheima09/hibernate/domain/Student.hbm.xml" />
79 </session-factory>
80 </hibernate-configuration>
hibernate.cfg.xml
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <hibernate-mapping>
 5     <class name="com.itheima09.hibernate.domain.Student">
 6         <id name="sid" length="5">
 7             <generator class="increment"></generator>
 8         </id>
 9         <property name="name" length="20"></property>
10         <property name="description" length="100"></property>
11         <!-- 
12             column 为外键
13          -->
14         <many-to-one name="classes" column="cid" 
15             class="com.itheima09.hibernate.domain.Classes" cascade="save-update" lazy="false">
16         </many-to-one>
17     </class>
18 </hibernate-mapping>
Student.hbm.xml
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <hibernate-mapping>
 5     <class name="com.itheima09.hibernate.domain.Classes" lazy="true">
 6         <cache usage="read-only"/>
 7         <id name="cid" length="5">
 8             <generator class="increment"></generator>
 9         </id>
10         <property name="name" length="20"></property>
11         <property name="description" length="100"></property>
12         <!-- 
13             fetch 抓取策略
14               join  通过做外链接
15               select  默认值
16               subselect
17          -->
18         <set name="students" cascade="all" fetch="select" lazy="true">
19             <cache usage="read-only"/>
20             <!-- 
21                 key代表外键
22                 用来关联classes表和student表,用于在hibernate低层生成sql语句
23              -->
24             <key>
25                 <column name="cid"></column>
26             </key>
27             <!-- 
28                 建立类与类之间的关联,用于客户端的编码
29              -->
30             <one-to-many class="com.itheima09.hibernate.domain.Student"/>
31         </set>
32     </class>
33 </hibernate-mapping>
Classes.hbm.xml
 1 import java.util.Iterator;
 2 import java.util.List;
 3 import java.util.Set;
 4 
 5 import org.hibernate.Query;
 6 import org.hibernate.Session;
 7 import org.hibernate.Transaction;
 8 import org.junit.Test;
 9 import org.omg.CORBA.TRANSACTION_MODE;
10 
11 import com.itheima09.hibernate.domain.Classes;
12 import com.itheima09.hibernate.domain.Student;
13 import com.itheima09.hibernate.utils.HibernateUtils;
14 
15 public class QueryCache extends HibernateUtils{
16     @Test
17     public void testQueryCache(){
18         Session session = sessionFactory.openSession();
19         Query query = session.createQuery("from Classes");
20         //允许把查询出来的集合放入到查询缓存中
21         query.setCacheable(true);
22         query.list();
23         System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
24         session.close();
25         session = sessionFactory.openSession();
26         query = session.createQuery("from Classes where cid=1");
27         //允许从查询缓存中提取数据
28         query.setCacheable(true);
29         query.list();
30         session.close();
31     }
32     
33     @Test
34     public void testSessionFactory(){
35         Session session = sessionFactory.openSession();
36         Query query = session.createQuery("select name from Classes");
37         //允许把查询出来的集合放入到查询缓存中
38         query.setCacheable(true);
39         query.list();
40         System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
41         session.close();
42         session = sessionFactory.openSession();
43         query = session.createQuery("select name from Classes");
44         //允许从查询缓存中提取数据
45         query.setCacheable(true);
46         query.list();
47         session.close();
48     }
49 }
QueryCache.java

Hql语句

单表

操作

案例1

案例2

      

      

   说明:List中含有Object[],该数组中有两个元素,第一个元素为Long类型,第二个元素为String类型。

案例3

      

在持久化类中,必须有两个构造器

    

  

案例4

      

案例5

      

案例6

      

案例7

      

一对多

案例1

案例2

      

      

   采用了左外链接,但是出来的结构不是很好。

案例3

      

说明:在join后面跟fetch,就为迫切左外链接。

案例4

     

      

案例5

    

  

说明:

     如果用select,则不能用fetch,如果用fetch,则不能用select。

多对多

案例1

      

      

案例2

      

      

一对多和多对多

案例1

      

List<Classes>

Classes<Set<Student>>

Student<Set<Course>>

  1 import java.util.Map.Entry;
  2 import java.util.Set;
  3 
  4 import org.hibernate.Query;
  5 import org.hibernate.Session;
  6 import org.hibernate.metadata.ClassMetadata;
  7 import org.junit.Test;
  8 
  9 import com.itheima09.hibernate.domain.Classes;
 10 import com.itheima09.hibernate.domain.Student;
 11 import com.itheima09.hibernate.manytomany.domain.Course;
 12 import com.itheima09.hibernate.utils.HibernateUtils;
 13 
 14 public class HqlTest extends HibernateUtils{
 15     
 16     @Test
 17     public void testCreateTable(){
 18         
 19     }
 20     
 21     @Test
 22     public void testQueryClasses(){
 23         Session session = sessionFactory.openSession();
 24         List<Classes> classesList = session.createQuery("from Classes").list();
 25         session.close();
 26     }
 27     
 28     @Test
 29     public void testQueryClasses_Properties(){
 30         Session session = sessionFactory.openSession();
 31         List classesList = session.createQuery("select cid,name from Classes").list();
 32         session.close();
 33     }
 34     
 35     @Test
 36     public void testQueryClasses_Constructor(){
 37         Session session = sessionFactory.openSession();
 38         List classesList = session.createQuery("select new com.itheima09.hibernate.domain.Classes(cid,name) from Classes").list();
 39         session.close();
 40     }
 41     
 42     /*
 43      * 查询classes表中所有的数据的个数
 44      */
 45     @Test
 46     public void testQueryCount(){
 47         Session session = sessionFactory.openSession();
 48         Long count = (Long)session.createQuery("select count(*) from Classes").uniqueResult();
 49         System.out.println(count);
 50         session.close();
 51     }
 52     
 53     /**
 54      * 带参数的查询
 55      */
 56     @Test
 57     public void testQuery_Parameter_1(){
 58         Session session = sessionFactory.openSession();
 59         Query query = session.createQuery("from Classes where name=?");
 60         query.setString(0, "aa");
 61         List<Classes> classesList = query.list();
 62         System.out.println(classesList.size());
 63         session.close();
 64     }
 65     
 66     @Test
 67     public void testQuery_Parameter_2(){
 68         Session session = sessionFactory.openSession();
 69         Query query = session.createQuery("from Classes where name=:name");
 70         query.setString("name", "aa");
 71         List<Classes> classesList = query.list();
 72         System.out.println(classesList.size());
 73         session.close();
 74     }
 75     
 76     @Test
 77     public void testQuery_Dynamic_Parameter(){
 78         /**
 79          * key代表持久化类中属性的名称 
 80          * value代表属性的值
 81          */
 82         Map<String, String> map = new HashMap<String, String>();
 83         map.put("name","aa");
 84         this.queryDynamic(map, Classes.class);
 85     }
 86     
 87     private void queryDynamic(Map<String, String> map,Class className){
 88         Session session = sessionFactory.openSession();
 89         StringBuffer buffer = new StringBuffer();
 90         /**
 91          * classes持久化类的元数据
 92          */
 93         ClassMetadata classMetadata = sessionFactory.getClassMetadata(className);
 94         //得到持久化类的名称
 95         buffer.append("from "+classMetadata.getEntityName());
 96         buffer.append(" where 1=1");
 97         //得到map中所有的key值
 98         Set<String> keys = map.keySet();
 99         //拼接hql语句:查询条件
100         Iterator<String> iterator = keys.iterator();
101         for(int i=0;i<keys.size();i++){
102             String temp = iterator.next();
103             buffer.append(" and "+temp+"=:"+temp);
104         }
105         Query query = session.createQuery(buffer.toString());
106         /**
107          * 给所有的查询条件赋值
108          */
109         for(Entry<String, String> entry:map.entrySet()){
110             query.setString(entry.getKey(), entry.getValue());
111         }
112         List<Classes> classesList = query.list();
113         System.out.println(classesList.size());
114         session.close();
115     }
116     
117     
118     /**
119      * 一对多
120      */
121     /**
122      * 等值链接
123      * 内链接
124      * 左外链接
125      * 迫切内链接
126      * 迫切左外链接
127      */
128     @Test
129     public void testQueryClassesAndStudent_EQ(){
130         Session session = sessionFactory.openSession();
131         List list = session.createQuery("from Classes c,Student s where c.cid=s.classes.cid").list();
132         session.close();
133     }
134     
135     @Test
136     public void testQueryClassesAndStudent_LeftJoin(){
137         Session session = sessionFactory.openSession();
138         List list = session.createQuery("from Classes c left join c.students s").list();
139         session.close();
140     }
141     
142     /**
143      * 迫切左外链接
144      */
145     @Test
146     public void testQueryClassesAndStudent_LeftJoin_fetch(){
147         Session session = sessionFactory.openSession();
148         List list = session.createQuery("from Classes c left outer join fetch c.students s").list();
149         session.close();
150     }
151     
152     /**
153      * 迫切内连接
154      */
155     @Test
156     public void testQueryClassesAndStudent_Innerjoin_fetch(){
157         Session session = sessionFactory.openSession();
158         List list = session.createQuery("from Classes c inner join fetch c.students s").list();
159         session.close();
160     }
161     
162     /**
163      * 查询classes中的name和student中的name
164      */
165     @Test
166     public void testQueryClassesPropertyAndStudentProperty(){
167         Session session = sessionFactory.openSession();
168         List list = session.createQuery("select new com.itheima09.hibernate.domain.ClassesView(c.name,s.name) " +
169                 "                            from Classes c inner join c.students s").list();
170         session.close();
171     }
172     
173     /**
174      * 多对多的迫切内连接
175      */
176     @Test
177     public void testQueryCourseAndStudent_1(){
178         Session session = sessionFactory.openSession();
179         List<Course> list = session.createQuery("from Course c inner join fetch c.students s").list();
180         session.close();
181     }
182     @Test
183     public void testQueryCourseAndStudent_2(){
184         Session session = sessionFactory.openSession();
185         List<Student> list = session.createQuery("from Student s inner join fetch s.courses c").list();
186         session.close();
187     }
188     
189     /**
190      * 多对多迫切左外链接
191      */
192     @Test
193     public void testQueryCourseLeftouterjoin_fetch(){
194         Session session = sessionFactory.openSession();
195         List<Course> list = session.createQuery("from Course c left outer join fetch c.students s").list();
196         session.close();
197     }
198     
199     /**
200      * 一对多和多对多的结合
201      * 
202      * 如果用迫切内链接做,最好查找核心表
203      */
204     /**
205      * 内连接
206      */
207     @Test
208     public void testQueryManyToManyToOne_1(){
209         Session session = sessionFactory.openSession();
210         StringBuffer buffer = new StringBuffer();
211         buffer.append("from Student s inner join fetch s.courses c inner join fetch s.classes cc");
212         List list = session.createQuery(buffer.toString()).list();
213         session.close();
214     }
215     
216     @Test
217     public void testQueryManyToManyToOne_2(){
218         Session session = sessionFactory.openSession();
219         StringBuffer buffer = new StringBuffer();
220         //from Course c inner join fetch c.students s inner join fetch s.classes cc 
221         buffer.append("from Classes c inner join fetch c.students s inner join fetch s.courses cc");
222         List list = session.createQuery(buffer.toString()).list();
223         session.close();
224     }
225     
226     @Test
227     public void testList(){
228         Session session = sessionFactory.openSession();
229         List list = session.createQuery("select new list(cid,name) from Classes").list();
230         session.close();
231     }
232     
233     @Test
234     public void Map(){
235         Session session = sessionFactory.openSession();
236         /**
237          *  n:ads
238             c:1
239             n:adsf
240             c:2
241          */
242         //别名为map中的key值,value值为属性的值
243         List<Map<String, Object>> list = session.createQuery("select new map(cid as c,name as n) from Classes").list();
244         for(Map<String, Object> map:list){
245             for(Entry<String, Object> entry:map.entrySet()){
246                 System.out.println(entry.getKey()+":"+entry.getValue());
247             }
248         }
249         session.close();
250     }
251     
252     /**
253      * 分页
254      */
255     @Test
256     public void testDispage(){
257         Session session = sessionFactory.openSession();
258         Query query = session.createQuery("from Classes");
259         query.setFirstResult(1);//当前页的第一行在集合中的位置
260         query.setMaxResults(2);//当前页有多少行
261         List<com.itheima09.hibernate.onetomanytomany.Classes> classesList = query.list();
262         for(com.itheima09.hibernate.onetomanytomany.Classes classes:classesList){
263             System.out.println(classes.getCid());
264         }
265         session.close();
266     }
267 }
HqlTest.java

Hibernate内部的list

      

      

Hibernate内部的map

      

      

分页

      

原生态的sql查询

     

 接口回调

https://blog.csdn.net/liangxw1/article/details/50701205

参考这里的文章

 1 public List findByPage(final String hql,
 2         final int offset, final int pageSize)
 3     {
 4         //通过一个HibernateCallback对象来执行查询
 5         List list = getHibernateTemplate()
 6             .executeFind(new HibernateCallback()
 7         {
 8             //实现HibernateCallback接口必须实现的方法
 9             public Object doInHibernate(Session session)
10                 throws HibernateException, SQLException
11             {
12                 //执行Hibernate分页查询
13                 List result = session.createQuery(hql)
14                     .setFirstResult(offset)
15                     .setMaxResults(pageSize)
16                     .list();
17                 return result;
18             }
19         });
20         return list;
21     }

第5行:获取Hibernatetemplate对象

第6行:执行Hibernatetemplate的 executeFind ()方法,并且传入HibernateCallback接口的实例化对象(匿名内部类)

这里的Hibernatetemplate对象 就类似  参考文章  的B的对象;而Hibernatetemplate对象中有一个方法是接收HibernateCallback接口的实例化对象,所以直接调用HibernateCallback接口的实例化对象的方法

interface AA{
    public String method1();
    public int method2();
}


public class InterFaceCallBack {
    public static void main(String[] args){

        BB  bb=new BB();
        bb.Method(new AA() {
            @Override
            public String method1() {
                return "I am AAImpl Method1";
            }
            @Override
            public int method2() {
                return 1+1;
            }
        });

    }
}
class BB{

    public int Method(AA aa){

        String a1=aa.method1();
        System.out.println("a1="+a1);
        int a2=aa.method2();
        System.out.println("a2="+a2);
        return 0;
    }
}
合群是堕落的开始 优秀的开始是孤行
原文地址:https://www.cnblogs.com/biaogejiushibiao/p/9446694.html