hibernate缓存(一级缓存二级缓存)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate缓存(一级缓存二级缓存)相关的知识,希望对你有一定的参考价值。

一、一级缓存(Session缓存)
     意义:提高hibernate查询效率。
     缺点:可能会因并发,产生数据不一致。
 
   基于session的缓存,利用hibernate执行查询的时候,hibernate会首先从session缓存去找,如果存在,则直接返回,如果不存在,则利用orm执行查询,将得到的对象保存至session缓存。
 
   可以使用session.evict(obj);将obj从session缓存中移除。
注意:一级缓存,自动开启
hibernate一些与一级缓存相关的操作:
数据放入缓存:
1、save():当session对象调用save方法保存一个对象后,该对象会被放入到session的缓存中。
(2)、get( )和load( ):当session对象调用get( )和load( )方法从数据库中取出一个对象后,该对象也会被放入session的缓存中。
下面证明一下缓存的存在:
技术分享
 1 package com.it.test;
 2 import org.hibernate.SessionFactory;
 3 import org.hibernate.Transaction;
 4 import org.hibernate.cfg.Configuration;
 5 import org.hibernate.classic.Session;
 6 import com.it.bean.UserInfo;
 7 public class Test2 {
 8      public static void main(String[] args) {
 9          // TODO Auto-generated method stub
10          //创建SessionFactory
11          SessionFactory sessionfactory = null;
12          //创建session
13          Session session = null;
14          //创建事务
15          Transaction tx = null;
16          try {
17               sessionfactory = new Configuration().configure().buildSessionFactory();
18               session = sessionfactory.getCurrentSession();
19               //开启事务
20               tx=session.beginTransaction();
21               UserInfo u = (UserInfo) session.get(UserInfo.class, "1001");
22               System.out.println("-------");
23               //清除缓存,这里如果没有清除缓存,那么控制台就会只输出一次查询,当清除了缓存后就会有输出两次查询语句。这正好说明了缓存的存在。
24               session.evict(u);
25               UserInfo u1 = (UserInfo) session.get(UserInfo.class, "1001");
26               //提交
27               tx.commit();
28          } catch (Exception e) {
29               e.printStackTrace();
30               //事务回滚
31               tx.rollback();
32          }
33      }
34 }
View Code
数据从缓存中清除:
(1)、evict( ):将指定的持久化对象从缓存中清除,释放对象所占的内存资源,指定对象从持久化状态变为脱管状态,从而成为游离对象。
(2)、clear( ):将缓存中的所有持久化对象清除,释放其占用的内存资源;
其他缓存操作:
(1)、contains( ):判断指定的对象是否存在于缓存中。
(2)、flush( ):刷新缓存区的内容,使之与数据库保持同步。
 
二、二级缓存(SessionFactory缓存)
   基于SessionFactory 的缓存,利用hibernate执行查询的时候,hibernate会首先从session缓存去找,如果存在,则直接返回,如果不存在则去二级缓存中去找,存在则返回,不存在则利用orm执行查询,将得到的对象保存至session缓存,可以存至二级缓存。
     
     注意:二级缓存需要在SessionFactory配置文件中,进行两处配置。
          a.配置启用二级缓存
          b.配置二级缓存实现类
          需要对缓存本身进行专门的配置。(xxx.xml--配置缓存)
适用场合:频繁查询,海量数据,极少修改的对象。
 
三、延迟加载
hibernate下延迟加载:load执行查询时,返回hibernate代理对象,当操作其非主属性时才会利用orm执行。
eg:(部分代码)
技术分享
1 //延迟加载--用的时候才执行
2               UserInfo u = (UserInfo) session.load(UserInfo.class, "1001");
3               System.out.println("---1----");
4               System.out.println(u.getUser_name());
5 //输出结果:查询语句在------1-----后才执行,用到的时候再执行,且如果取得是主属性,就不用查询,因为load里已经给了
View Code
延迟加载可以在bean对应的xxxxx.hbm.xml文件中设置lazy="false"(关闭了延时加载,就会变成即可加载)
 
load和get的区别:
     load                   get
  默认:延迟加载   默认:即可加载
  查不到:抛出异常     查不到:返回null
 
使用load需注意:操作非主属性时要在事务提交之前使用(会报错:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session);
而使用get时在提交事务后仍能操作非主属性。
技术分享
 1 使用load:  //延迟加载--用的时候才执行
 2              UserInfo u = (UserInfo) session.load(UserInfo.class, "1001");
 3              System.out.println("---1----");     
 4              tx.commit();
 5           //在事务提交之后操作非主属性会抛异常:org.hibernate.LazyInitializationException           
 6 |          System.out.println(u.getUser_name());                                                   |
 7 |--------------------------------------------------------------------------------------------------|
 8 使用get:     //使用get
 9               UserInfo u = (UserInfo) session.load(UserInfo.class, "1001");
10               System.out.println("---1----");
11               tx.commit();
12                //在事务提交之后还能操作属性,因为已经得到在之前已经得到了该对象
13               System.out.println(u.getUser_name());          
View Code

 

以上是关于hibernate缓存(一级缓存二级缓存)的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate中一级缓存和二级缓存使用详解

hibernate一级和二级缓存介绍

Hibernate一级缓存与二级缓存的区别

Hibernate一级缓存和二级缓存具体解释

Hibernate中的一级缓存二级缓存和懒加载

hibernate缓存(一级缓存二级缓存)