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. 怎样用Zbrush中的Curves Tubes创建手指

    之前我们已经能够初步完成了模型的人体躯干,今天的Zbrush教程将继续使用Curves Tubes创建手指,实现更细致的塑形.文章内容仅以fisker老师讲述为例,您也可以按照自己的想法,跟着老师的步 ...

  2. MyBatis学习总结(一)

    一.Mybatis介绍 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以 ...

  3. 准备写一些读书笔记,最近在填坑 SQL学习指南 Spring in Action effective Java

    把一些读书的理解通过白板图的形式展示出来,加深自己的认识, 因为目前没有工程项目练手,暂时在学习中把这些知识深化认识一下

  4. Maven 小结

    Maven 的各项功能通过插件实现,有需要的时候学习那些插件的配置即可 一般一个大型项目会有 A:父管理工程,定义了所有的依赖和插件 B:工具工程 C:web 项目的父工程,同时也是一个聚合工程 D: ...

  5. 工作者队列原理解析(后台writeback)

    每一个CPU都会有两个(或者一个?)kwoker线程. kwoker线程,说白了就是尽量减少进程的数目,为了什么呢?因为线程数据太多的话,调度的成本比较高,占用太多的系统资源,所以这里是进程的一个简化 ...

  6. uart串口的调试学习

    用FPGA设计了数据接收和发送模块,FIFO模块,此处FIFO调用的是Show-ahead模式,在下一篇博客中将会分析这个问题. 用串口调试工具发送数据,数据接收模块将接收到的串行数据转换为并行数据( ...

  7. WP老杨解迷:开发生态两极化和榜单乱象

    Windows Phone 自2013年的一片浪潮推动下,2014年终于开始引起了各大小CP们的注意,于是大量的产品开始乘风破浪一路涌进Windows Phone平台,立即改变了榜单的格局,如今,苦B ...

  8. 在opencv3中进行图片人脸检测

    在opencv中,人脸检测用的是harr或LBP特征,分类算法用的是adaboost算法.这种算法需要提前训练大量的图片,非常耗时,因此opencv已经训练好了,把训练结果存放在一些xml文件里面.在 ...

  9. openssl知识点总结

    openssl知识点总结 实践总结见之前博客:http://www.cnblogs.com/Jclemo/p/6091201.html 简介 openssl是一个功能丰富且自包含的开源安全工具箱.它提 ...

  10. Jenkins进阶系列之——04Publish Over FTP Plugin插件

    说明:这个插件可以将构建的产物(例如:Jar)发布到FTP中去. 官方说明:Publish Over FTP Plugin 安装步骤: 系统管理→管理插件→可选插件→Artifact Uploader ...