• 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;
        }
    }
    合群是堕落的开始 优秀的开始是孤行
  • 相关阅读:
    消息中间件(一)MQ详解及四大MQ比较
    WebSocket 详解教程
    Nginx 简易教程
    排序七 归并排序
    排序五 简单选择排序
    排序四 希尔排序
    排序二 快速排序
    排序一 冒泡排序
    [算法题] 人民币大小写转换(阿拉伯数字和汉字转换)
    Linux编程 18 安装软件程序(yum工具对软件包安装,删除,更新介绍)
  • 原文地址:https://www.cnblogs.com/biaogejiushibiao/p/9446694.html
Copyright © 2020-2023  润新知