hibernate提供的一级缓存

  hibernate是一个线程对应一个session,一个线程可以看成一个用户。也就是说session级缓存(一级缓存)只能给一个线程用,别的线程用不了,一级缓存就是和线程绑定了。

  hibernate一级缓存生命周期很短,和session生命周期一样,一级缓存也称session级的缓存或事务级缓存。

如果tb事务提交或回滚了,我们称session就关闭了,生命周期结束了。

实例:

(hibernate使用load查询)

//同一个session中,发出两次load方法查询
Student student = (Student)session.load(Student.class, 1);
System.out.println("student.name=" + student.getName());
//不会发出查询语句,load使用缓存
student = (Student)session.load(Student.class, 1);
System.out.println("student.name=" + student.getName());

第二次查询第一次相同的数据,第二次load方法就是从缓存里取数据,不会发出sql语句到数据库里查询。

(hibernate使用get查询)

//同一个session,发出两次get方法查询
Student student = (Student)session.get(Student.class, 1);
System.out.println("student.name=" + student.getName()); //不会发出查询语句,get使用缓存
student = (Student)session.get(Student.class, 1);
System.out.println("student.name=" + student.getName());

第二次查询第一次相同的数据,第二次不会发出sql语句查询数据库,而是到缓存里取数据。

(hibernate使用iterate查询)

//同一个session,发出两次iterate查询实体对象
Iterator iter = session.createQuery("from Student s where s.id<5").iterate();
while (iter.hasNext()) {
  Student student = (Student)iter.next();
  System.out.println(student.getName());
}
System.out.println("--------------------------------------"); //它会发出查询id的语句,但不会发出根据id查询学生的语句,因为iterate使用缓存
iter = session.createQuery("from Student s where s.id<5").iterate();
while (iter.hasNext()) {
  Student student = (Student)iter.next();
  System.out.println(student.getName());
}

第二次查询第一次相同的数据,第二次不会发出sql语句查询数据库,而是到缓存里取数据。

说到iterater查询就要立刻想起:iterater查询在没有缓存的情况下会有N+1的问题。

  执行上面代码查看控制台的sql语句,第一次iterate查询会发出N+1条sql语句,第一条sql语句查询所有的id,然后根据id查询实体对象,有N个id就发出N条语句查询实体。

  第一次发出N+1条sql语句,第二次还是发出了N+1条sql语句。因为一级缓存只缓存实体对象,tb不会缓存普通属性,所以第二次还是发出sql查询语句。

-----------

(测试两个session之间不能共享缓存数据)

//两个session,每个session发出一个load方法查询实体对象
try {
  session = HibernateUtils.getSession();
  session.beginTransaction();
  Student student = (Student)session.load(Student.class, 1);
  System.out.println("student.name=" + student.getName());
  session.getTransaction().commit();
}catch(Exception e) {
  e.printStackTrace();
  session.getTransaction().rollback();
}finally {
  HibernateUtils.closeSession(session);
}

第二个session调用load方法

try {
  session = HibernateUtils.getSession();
  session.beginTransaction();
  Student student = (Student)session.load(Student.class, 1);
  //会发出查询语句,session间不能共享一级缓存数据
  //因为他会伴随着session的消亡而消亡
  System.out.println("student.name=" + student.getName());
  session.getTransaction().commit();  
}catch(Exception e) {
  e.printStackTrace();
  session.getTransaction().rollback();  
}finally {  
  HibernateUtils.closeSession(session);  
}

第一个session的load方法会发出sql语句查询实体对象,第二个session的load方法也会发出sql语句查询实体对象。因为session间不能共享一级缓存的数据,所以第二个session的load方法查询相同的数据还是要到数据库中查询,因为它找不到第一个session里缓存的数据。

(session的save支持缓存)

//同一个session,先调用save方法再调用load方法查询刚刚save的数据
Student student = new Student();
student.setName("张三");
//save方法返回实体对象的id
Serializable id = session.save(student);
student = (Student)session.load(Student.class, id);
//不会发出查询语句,因为save支持缓存
System.out.println("student.name=" + student.getName());

先save保存实体对象,再用load方法查询刚刚save的实体对象,则load方法不会发出sql语句到数据库查询的,而是到缓存里取数据,因为save方法也支持缓存。当然前提是同一个session。

大批量的数据添加(内存的溢出)

for (int i=0; i<100; i++) {
  Student student = new Student();
  student.setName("张三" + i);
  session.save(student);
  //每20条更新一次
  if (i % 20 == 0) {
    session.flush();
    //清除缓存的内容
    session.clear();
  }
}

大批量数据添加时,会造成内存溢出的,因为save方法支持缓存,每save一个对象就往缓存里放,如果对象足够多内存肯定要溢出。一般的做法是先判断一下save了多少个对象,如果save了20个对象就对缓存手动的清理缓存,这样就不会造成内存溢出。

注意:清理缓存前,要手动调用flush方法同步到数据库,否则save的对象就没有保存到数据库里。

注意:大批量数据的添加还是不要使用hibernate,这是hibernate弱项。可以使用jdbc(速度也不会太快,只是比hibernate好一点),或者使用工具产品来实现,比如oracle的Oracle SQL Loader,导入数据特别快。

Hibernate-一级缓存session的更多相关文章

  1. Hibernate一级缓存Session和对象的状态

    建议看原文:https://blog.csdn.net/qq_42402854/article/details/81461496 一.session简介        首先,SessionFactor ...

  2. hibernate一级缓存

    理解 Hibernate 一级缓存 Hibernate 一级缓存默认是打开,不需要任何的配置.实际上,你无法强制禁止它的使用. 如果你理解了一级缓存实际上和会话是关联的,就很容易理解一级缓存.总所周知 ...

  3. Hibernate一级缓存(基于查询分析)

    首先我们应该弄清什么是hibernate缓存:hibernate缓存是指为了降低应用程序对物理数据源的访问频次,从而提高应用程序的运行性能的一种策略.我们要将这个跟计算机内存或者cpu的缓存区分开. ...

  4. hibernate一级缓存及对象的状态

    hibernate中实体类对象的状态 在hibernate中实体类对象有三种状态 (1)瞬时态(临时态) 瞬时态:即我们自己创建一个对象,还没有保存到数据库就叫临时态,其实也可以说是对像没有id值,跟 ...

  5. Hibernate一级缓存(补)

    ------------------siwuxie095                                 什么是缓存         缓存是介于应用程序和永久性数据存储源(如:硬盘上的 ...

  6. Hibernate一级缓存测试分析

    Hibernate 一级缓存测试分析 Hibernate的一级缓存就是指Session缓存,此Session非http的session会话技术,可以理解为JDBC的Connection,连接会话,Se ...

  7. 转载 hibernate一级缓存和二级缓存的区别

    文章来源:http://blog.csdn.net/defonds/article/details/2308972     hibernate一级缓存和二级缓存的区别 缓存是介于应用程序和物理数据源之 ...

  8. Hibernate一级缓存和三种状态

    Hibernate一级缓存又称session缓存,生命周期很短,跟session生命周期相同. 三种状态:1.transient(瞬时态):刚new出来的对象,既不在数据库中,也不在session管理 ...

  9. hibernate - 一级缓存和三种状态解析

    转载自:http://www.cnblogs.com/whgk/p/6103038.html 一.一级缓存和快照 什么是一级缓存呢? 很简单,每次hibernate跟数据库打交道时,都是通过sessi ...

  10. hibernate笔记--缓存机制之 一级缓存(session缓存)

    一级缓存: 又称为session缓存,它和session生命周期相同,周期非常短.是事务级别的缓存: 还是以Book和Category这两个表为例,我们用代码观察一个缓存的存在: 假设现在我要去查询i ...

随机推荐

  1. 谷歌和HTTPS

    谷歌和HTTPS HTTPS被觉得是加强互联网安全的次要部分,而且使用广泛.google近来做了一份关于数据加密近况的陈述. 正在陈述的最新部分中,提到了google以及第三方构造对于数据加密所做的贡 ...

  2. Codeforces 234D Cinema

    这题做的我好苦啊,编码调试整整搞了一个多小时,而且调到天昏地暗才调出来.. 回归正题,这题是一道本人做过的比较烦,比较无聊的题之一.题意是一个人,在m个影星里有k个喜欢的影星,然后给出n场电影,每场电 ...

  3. C# 读取Excel

    直接添代码: public void connExcel(string strPath) { //string strConn = @"Provider=Microsoft.Jet.OLED ...

  4. Apache轻量级性能测试工具

    平时工作中会需要一些性能测试,简单的性能测试完全可以由AB来替代,而不需要动用LR这样重量级的工具. 此文简单介绍一下ab的工具使用与结果分析.当作个笔记,以便以后查阅. 1.安装:要使用AB,需要先 ...

  5. java 20 - 9 带有缓冲区的字节输出流和字节输入流

    由之前字节输入的两个方式,我们可以发现,通过定义数组读取数组的方式比一个个字节读取的方式快得多. 所以,java就专门提供了带有缓冲区的字节类: 缓冲区类(高效类) 写数据:BufferedOutpu ...

  6. 如何用chrome插件使上网生活更美好-持续更新

    所有插件都可以到Chrome Web Store搜索下载 1.Read Later Fast v-1.6.8 ***刷网页的时候,有很多值得我们阅览但当时木有时间看怎么办? --加可书签啊! ***可 ...

  7. html5中上传图片

    从相册中选择图片上传 function uploadFromAlbum(type) { var dirtype = ""; if ("pick_store_license ...

  8. mvc control 请求两次问题

    今天在做项目时,突然发现一个mvc 的control中action被执行了两次,最终发现是由于favicon.ico导致的.问题代码: <link rel="shortcut icon ...

  9. Linux下目录的合并以及文件的覆盖

    有两个目录test和new,test目录下有目录和文件,new目录下有更改过的一些test下的目录和文件,以及一些新增的文件,现在对两个目录进行合并以及覆盖test下的旧文件. cp -frap ne ...

  10. survival analysis 生存分析与R 语言示例 入门篇

    原创博客,未经允许,不得转载. 生存分析,survival analysis,顾名思义是用来研究个体的存活概率与时间的关系.例如研究病人感染了病毒后,多长时间会死亡:工作的机器多长时间会发生崩溃等. ...