一、Session缓存的介绍

  简单说,缓存介于应用程序和数据库之间,是临时存放数据的内存区域,作用是减少对数据库的访问次数,从而提高应用程序的运行性能。Session有一个缓存,也叫hibernate的一级缓存,Hibernate查询数据的时候,首先到session缓存中看看有没有,有的话直接拿来使用,没有的话,才去访问数据库读取数据。

  众所周知,一个java对象如果没有被任何变量引用的话,就会被GC自动回收,生命周期结束。Session接口的实现中包含一系列的java集合,这些java集合构成了session的缓存。也就是说,Session持有这些java对象的引用,所以只要session实例没有结束生命周期,存放在它缓存中的对象也不会结束生命周期。

二、Session的清理缓存和脏检查机制

  清理缓存:session会在某些时间点根据缓存的对象数据的变化来执行相关的sql语句,来同步更新数据库。

  脏检查:当一个java对象加载到session缓存中,Session会为该对象的值类型属性复制一份快照。当session清理缓存的时候,会将对象目前的值与它的快照相比较,若有变化,这个对象便称为“脏对象”,session会根据脏对象最新的值来执行相关的sql语句。

  下面来看一个小例子:

    Session session = sessionFactory.openSession();
User user = (User) session.get(User.class, 1l);
user.setPassword("123"); //起初数据库password值为null
session.close(); //session关闭后,数据库password值仍为null
//另一种情况:
Session session2 = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user2 = (User) session.get(User.class, 1l);
user2.setPassword("123"); //起初数据库password值为null
tx.commit();
session.close(); //session关闭后,数据库password值变为'123'

首先,如果不开启事务的话,利用session的get方法从数据库读取得到一个对象,然后修改该对象的值,session缓存中的对象属性值改变了,但数据库的值不会改变(发出一条sql查询语句);在开启事务的情况下,修改该对象的值,然后提交事务,数据库中对应的值会改变(发出两条sql语句,一条查询一条更新)。Why?

  因为,在默认情况下,session会在以下时间点清理缓存:

  a)调用transaction的commit()方法时,先清理缓存再提交事务;

  b)显式调用session的flush()方法时;

  c)应用程序执行一些查询操作,涉及到缓存中其属性值已经改变的对象。

  session的关闭并不会自动清理缓存,进行脏检查。不过,我们使用session更新保存对象的时候,一般会开启事务,在提交事务的时候,session便会清理缓存了,并且会释放session占用的数据库连接。要想理解session各方法,就应该知道hibernate什么时候会向数据库发出SQL语句,发出多少条怎样的SQL语句。

三、Session主要方法的介绍

  简略谈谈各方法之前,得说说java对象在hibernate持久化的状态:

  a)临时状态:刚new出来,不存在数据库中(没被持久化),不存在session缓存中;

  b)持久化状态:存在数据库中(已被持久化),存在session缓存中;

  c)游离状态:存在数据库中(已被持久化),但不存在session缓存中;

  d)删除状态:不再存在session缓存中,且session已计划将其从数据库中删除。

1)save()方法:如果对象使用native生成器生成OID的话,会马上发出一条insert语句,我们便可通过getId()得到该对象的id。对临时对象save完后,再save的话无效(仅发出1条insert语句);对游离状态多次save的话,则会保存多条重复记录(会发出多条insert语句)。

2)load()和get()方法:
load()使用延迟检索策略,不存在该记录时,抛出异常 (调用load的时候等到需要查询其属性再发出select语句,否则不发出select语句);
get()使用立即检索策略,不存在某条记录时,返回null(调用get的时候会立即发出select语句)。

3)update()方法:将游离状态的对象转换为持久化状态,保存到数据库(发出一条update语句)。在清理缓存之前,即使该对象属性值改变多次,session也只是最后才发出执行一次sql语句。

4)saveOrUpdate()方法:判断对象是游离状态还是临时状态,然后发出insert或者update语句。

5)delete()方法:session在清理缓存的时候才发出delete语句,一次只能删除一个对象。

四、Session的获取与管理

  1,sessionFactory.openSession(),需要手动关闭session;

  2,若hibernate与spring整合后,需要配置加入spring提供的事务管理机制,例如加上@Transactional,才能通过sessionFactory.getCurrentSession()获取当前线程绑定的Session,之后无须手动关闭session。简单来说,Spring的Session总是与某个线程绑定的,而这个线程往往就是承载Servlet或Jsp的那个线程,也就是说,它的生命周期scope是request的,线程结束之前,与线程绑定的session会自动被关闭。

最后,以上仅供参考,有何地方出错,欢迎拍砖指正。

Hibernate-Session使用的背后的更多相关文章

  1. org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

    org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not a ...

  2. Use Spring transaction to simplify Hibernate session management

    Spring对Hibernate有很好的支持    DataSource ->SessionFactory-> HibernateTranscationManagerHibernate中通 ...

  3. Could not open Hibernate Session for transaction;

    javax.servlet.ServletException: org.springframework.transaction.CannotCreateTransactionException: Co ...

  4. Hibernate3回顾-5-简单介绍Hibernate session对数据的增删改查

    5. Hibernate对数据的增删改查 5.1Hibernate加载数据 两种:get().load() 一. Session.get(Class arg0, Serializable arg1)方 ...

  5. [转]Hibernate Session各种状态转换方法分析

    摘自http://spiritfrog.iteye.com/blog/221177 我的印象里, Hibernate session中常用的保存操作只有:save, update, saveOrUpd ...

  6. spring事务管理出错。No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy ...

  7. [原理][源代码解析]spring中@Transactional,Propagation.SUPPORTS,以及 Hibernate Session,以及jdbc Connection关系---转载

    问题: 一. 1. Spring 如何处理propagation=Propagation.SUPPORTS? 2. Spring 何时生成HibernateSession ? 3. propagati ...

  8. No Hibernate Session bound to thread, and configuration does not allow creat

    No Hibernate Session bound to thread, and configuration does not allow creat 今天遇到这么一个错误,在网上差了很多都没有能解 ...

  9. Hibernate Session 获取connection

    Hibernate Session 获取connection 由于最近一个项目要用到一条辅助的SQL ,hibernate里面的SQLQuery API 总的SQL语句不能包含 : 冒号, 固放弃Hi ...

  10. hibernate.Session简介

    ★→→SessionFactory (org.hibernate.SessionFactory) 包含已经编译的映射(mappings),是制造session的工厂,可能含有一些可以在各个事务(tra ...

随机推荐

  1. UVA11624(bfs最短路)

    Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of the m ...

  2. Strom配置说明

    在进群生产环境下运行Topology和在本地模式下运行非常相似.下面是步骤: 1.定义Topology(如果使用Java开发语言,则使用TopologyBuilder来创建) 2.使用StormSub ...

  3. bzoj2159

    树形dp+第二类斯特林数 又是这种形式,只不过这次不用伯努利数了 直接搞肯定不行,我们化简一下式子,考虑x^n的组合意义,是把n个物品放到x个箱子里的方案数.那么就等于这个i=1->n,sigm ...

  4. Coding WebIDE 开放支持第三方 Git 仓库

    为了给开发者提供更多便捷的开发方式,Coding.net 现正式宣布 WebIDE 开放啦 ! 用户可以自由选择各大代码托管平台,推送代码到其它家代码仓库啦,同时新版的 WebIDE 还有如下特性: ...

  5. 生产环境下Flask项目目录构建

    接触Flask已经有大半年了,本篇博客主要来探讨如何规范化生产环境下Flask的项目目录结构.虽然目录结构见仁见智,个人有个人的看法和习惯,但总的来说,经过很多人的实践和总结,还是有很多共同的意见和想 ...

  6. 【Linux学习】Linux文件系统1--文件系统的目录结构

    Linux文件系统1--文件系统的目录结构 一.linux文件系统的类型 LINUX有四种基本文件系统类型:普通文件.目录文件.连接文件和特殊文件,可用file命令来识别. 1.普通文件:如文本文件. ...

  7. Flutter实战视频-移动电商-37.路由_Fluro引入和商品详细页建立

    37.路由_Fluro引入和商品详细页建立 https://github.com/theyakka/fluro pages/details_page.dart新建页面 使用路由 先添加路由插件的引用 ...

  8. PHP实现人脸识别技术

    这次人脸识别技术,是实现在微信端的,也就是说利用公众微信平台,调用第三的API来实现人脸识别这项技术的. 实现的思路: 首先呢,将收集的照片,建立一个照片库,然后利用在微信平台发送的照片,去到照片库进 ...

  9. Linux下共享库嵌套依赖问题 (转载)

    转自:http://my.oschina.net/moooofly/blog/506466 问题场景: 动态库 librabbitmq_r.so 内部依赖动态库 libevent_core.so 和 ...

  10. jQuery 实现网页跳转或用命令打开指定网页!

    Jquery实现网页跳转或用命令打开指定网页! location.href = "www.baidu.com"; location.href = "aa.aspx&quo ...