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了

  • 相关阅读:
    PAT Advanced 1067 Sort with Swap(0, i) (25分)
    PAT Advanced 1048 Find Coins (25分)
    PAT Advanced 1060 Are They Equal (25分)
    PAT Advanced 1088 Rational Arithmetic (20分)
    PAT Advanced 1032 Sharing (25分)
    Linux的at命令
    Sublime Text3使用指南
    IntelliJ IDEA创建第一个Groovy工程
    Sublime Text3 安装ftp插件
    Sublime Text3配置Groovy运行环境
  • 原文地址:https://www.cnblogs.com/qf123/p/10156442.html
Copyright © 2011-2022 走看看