zoukankan      html  css  js  c++  java
  • 四、hibernate的缓存

    缓存:

      就是将数据保存到内存中,需要使用时直接从内存中获取,不需要每次查询数据库或者磁盘中的文件

    hibernate的缓存

    • 一级缓存:Session级别的缓存
    • 二级缓存:SessionFactory级别的缓存

    一级缓存

    简介

    hibernate的一级缓存指的就是Session缓存,Session缓存是一块内存空间,用来存放相互管理的Java对象。在使用hibernate查询对象的时候,首先会使用对象属性的OID值在hibernate的一级缓存中查询,如果能匹配到该OID值的对象,直接将对象从一级缓存中取出来,不需要再查询数据库;如果找不到匹配该OID值的对象,就查询数据库获取对象,并放入一级缓存中

    hibernate一级缓存的主要作用就是减少数据库访问次数,是hibernate的一种重要优化手段

    一级缓存是由Session内的一系列Java集合组成的

    一级缓存的生命周期和Session一致,Session被创建时一级缓存开启,Session被销毁时一级缓存也被销毁

    一级缓存是hibernate自带的,不可卸载的;只要使用hibernate,就会有一级缓存

            @Test
    	public void get(){
    		Session session = SessionFactoryUtil.getSession();
    		Transaction ts = session.beginTransaction();
    		
    		//连续查询两次id为1的数据,看控制台输出查询sql的次数
    		User user1 = session.get(User.class, 1);
    		User user2 = session.get(User.class, 1);
    		
    		System.out.println("两次查询的是否为同一对象:"+ (user1 == user2));
    		
    		ts.commit();
    		session.close();
    	}    
    

      console输出

    Hibernate: 
        select
            user0_.id as id1_0_0_,
            user0_.name as name2_0_0_,
            user0_.password as password3_0_0_ 
        from
            user user0_ 
        where
            user0_.id=?
    两次查询的是否为同一对象:true
    

      两次查询只输出一次查询sql,说明第二次查询使用的是session缓存中的对象数据

    结构

    session缓存的主要实现在于actionQueue和persistenceContext这两个属性

    • actionQueue:队列
    • persistenceContext:一组map集合

    Session缓存中存在一块特殊区域:快照区。快照区的作用是用于保证数据的一致性

    @Test
    public void test(){
    	Session session = SessionFactoryUtil.getSession();
    	Transaction ts = session.beginTransaction();
    	
    	//代码1
    	User user = session.get(User.class, 1);
    	//代码2
    	user.setName("qf");
    	//代码3
    	ts.commit();
    	
    	session.close();
    }
    

      

    执行完代码1:

    执行完代码2:

    执行代码3

      比较缓存区和快照区数据,一致就不更新数据库;不一致就更新数据库

    特点

    1. 调用Session的close()方法时,一级缓存会被清空

    2. 程序执行Session接口中的save()、update()、saveOrUpdate()方法时,如果Session缓存中没有相应的对象,就会自动把从数据库中查到的对象信息加入到Session缓存中

    @Test
    public void test(){
    	Session session = SessionFactoryUtil.getSession();
    	Transaction ts = session.beginTransaction();
    	
    	//保存新用户
    	User user = new User("admin", "123");
    	Serializable id = session.save(user);
    	//根据保存返回的用户id查询用户信息
    	User user2 = session.get(User.class, id);
    	
    	System.out.println(user2);
    	
    	ts.commit();
    	session.close();
    } 

    console输出信息

    Hibernate: 
        insert 
        into
            user
            (name, password) 
        values
            (?, ?)
    User [id=8, name=admin, password=123]

    结果:

      输出信息中,只有插入数据的sql,并没有查询数据的sql,说明save保存对象后把对象数据放入session缓存中了,并且查询数据使用的是session缓存中的user对象

    3. 程序执行Session接口中的get()、load()方法,或者Query接口的list()、iterator()方法时,会判断缓存中是否有该对象,有就直接返回,没有就查询数据库并添加缓存

    @Test
    public void test(){
    	Session session = SessionFactoryUtil.getSession();
    	Transaction ts = session.beginTransaction();
    	
    	session.get(User.class, 1);
    	
    	session.get(User.class, 1);
    	
    	ts.commit();
    	session.close();
    }  

    console输出信息

    Hibernate: 
        select
            user0_.id as id1_0_0_,
            user0_.name as name2_0_0_,
            user0_.password as password3_0_0_ 
        from
            user user0_ 
        where
            user0_.id=?

    结果:

      只发送一次查询sql,说明第一次查询后将对象放入缓存中了,第二此查询直接从缓存中获取对象数据

    二级缓存

    hibernate并没有提供相应的二级缓存的组件,所以需要加入额外的二级缓存包,常用的二级缓存包是EHcache

    在hibernate.cfg.xml配置文件中配置我们二级缓存的一些属性

    <!-- 开启二级缓存 -->
    <property name="hibernate.cache.use_second_level_cache">true</property>
    <!-- 二级缓存的提供类 在hibernate4.0版本以后我们都是配置这个属性来指定二级缓存的提供类-->
    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
    <!-- 二级缓存配置文件的位置 -->
    <property name="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</property>
    

    配置hibernate的二级缓存是通过使用 ehcache的缓存包,所以我们需要创建一个 ehcache.xml 的配置文件,来配置我们的缓存信息,将其放到项目根目录下

    开启二级缓存:在映射文件中配置<cache usage="read-only"/>

    二级缓存是sessionFactory级别的缓存,在配置了二级缓存以后,当session关闭以后,再去查询对象的时候hibernate首先会去二级缓存中查询是否有该对象,有就不会再发sql了

  • 相关阅读:
    EELS
    企业管理软件随想透视>包容,无形思想>有形方便
    定风波
    企业管理软件随想也谈企业框架软件需求
    Delphi数据库开发-前言
    游戏引发的……
    js 当前时间
    代码片段
    阶段总结
    Web界面设计
  • 原文地址:https://www.cnblogs.com/qf123/p/10156442.html
Copyright © 2011-2022 走看看