Hibernate的缓存策略

Hibernate是个ORM框架,ORM框架解决的就是数据库访问的问题,我们评判一个ORM框架是否有优秀,主要看访问数据库的效率

hibernate使用其缓存机制来提升访问数据库的效率。


缓存机制的基本原理:

 

对于每次对数据的请求,先去缓存中查找数据,如果命中,则读取数据,若未命中,再到数据库中查找数据,并将数据存入到缓存中,以此来提升访问效率。

Hibernate的一级缓存: 


hibernate 的一级缓存又称session缓存,或会话级缓存,它是跟session相关的,当通过session从数据库查询实体时,会把实体在内存中存储起来,下次再查询同一实体时不再去数据库获取数据,而是在内存中获取。

一级缓存的生命周期和session是相同的,session销毁,一级缓存也销毁。


与一级缓存相关的两个方法:

session.evict(之前获取的对象)    //用于清除一级缓存中的指定对象

session.clear()  //用于清除一级缓存中的所有对象 


query两个方法的区别:

query.list()方法不会使用到一级缓存

query.iterate()方法,现在数据库查找数据的主键,再根据主键去缓存中查找数据,未命中再去数据库查找。

            

       tx = session.beginTransaction();
     User user1 = (User)session.load(User.class, 1); //下面用到setName,会执行sql语句,getId也会执行
      user1.setName("张三");  
      user1.setName("李四");  //在缓存中进行修改
     tx.commit();    //只在事务提交时执行一次update语句


        tx = session.beginTransaction();
        User user1 = (User)session.load(User.class, 1); //不发送任何sql语句
        User user2 = (User) session.load(User.class, 1);
        System.out.println(user1==user2);  //打印true
        tx.commit();//都得到相同的代理对象

Hibernate的二级缓存: 

二级缓存是应用级缓存,每个session共用的缓存,


它不是默认开启的,其开启步骤为

1>开启二级缓存


 <property name="hibernate.cache.use_second_level_cache">true</property>


2>指定二级缓存的实现类,这里用ehcache


<property      name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>


3>配置文件位置


<property name="hibernate.cache.provider_configuration_file_resource_path">classpath:ehcache.xml</property>


4>在需要被缓存的表对应的映射文件中添加<cache/>标签


 <cache usage="read-only"/>  //一般二级缓存都设置为只读

 或者用注解的方式,在需要缓存的类上加@Cache        


 其中关于<cache/>标签的详细介绍 : 

      usage 指定缓存策略,可用于处理并发问题

      region:指定二级缓存域名,可在ehcache的配置文件中进行缓存策略的配置

      include: 指定是否缓存延迟加载的对象,all--缓存  non-lazy ----不缓存


 try
        {
        	Session session1 = HibernateUtil.getSessionFactory().openSession();
            Transaction tx1 = session1.beginTransaction();
            User user1 = (User)session1.load(User.class, 1); //下面用到setName,会执行sql语句,getId也会执行
            System.out.println(user1.getName()); 
            tx1.commit(); 
            session1.close();
            
            Session session2 = HibernateUtil.getSessionFactory().openSession();
            Transaction tx2 = session2.beginTransaction();
            User user2= (User)session2.load(User.class, 1); //下面用到setName,会执行sql语句,getId也会执行
            System.out.println(user2.getName());  
            tx2.commit(); 
            session2.close();
        	
        }


第二次并没有发送sql语句,二级缓存生效。


二级缓存缓存的仅仅是对象,如果查询出来的是对象的一些属性,则不会被加到缓存中去

Session session1 = HibernateUtil.getSessionFactory().openSession();
            Transaction tx1 = session1.beginTransaction();
            User user1 = (User)session1.load(User.class, 1); //下面用到setName,会执行sql语句,getId也会执行
            System.out.println(user1.getName()); 
            tx1.commit(); 
            session1.close();
            
            Session session2 = HibernateUtil.getSessionFactory().openSession();
            Transaction tx2 = session2.beginTransaction();
            Object[] obj = (Object[]) session.createQuery(" select u.name,u.sex from User u where u.id=1").uniqueResult();
            tx2.commit(); 
            session2.close();


查询缓存:

在配置文件中加入

  <property name="hibernate.cache.use_query_cache">true</property>//开启查询缓存

查询缓存能缓存sql语句,只有当sql语句包括变量值完全相同时,才会使用查询缓存


查询缓存也是SessionFactory级别的,他只缓存主键值。可能会引起n+1的问题。所以一般使用查询缓存要配合二级缓存使用

 注意:

缓存也有可能对程序的性能产生影响,原因是当我们对数据库数据进行增删改的时候,同需要对一级缓存进行相应的操作,但总体一级缓存可以提高查询效率。

通常情况下具有以下特点的数据会放到二级缓存中:

1.很少被修改的数据

2.不是很重要的数据,语序出现偶尔的并发

3.不会被并发的数据

4.参考数据





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值