一、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. CSU 1554 SG Value —— 思维

    题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1554 Description The SG value of a set (mult ...

  2. aidl笔记 2/5/2015

    interface Test { //测试的接口 void fun();} Stub 是一个Binderclass Stub extend Binder implements Test { publi ...

  3. redis实例

    <?php Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. 本篇文章,主要介绍利用PHP使用Redis ...

  4. ARM之工作模式

    前言            以下内容是个人学习之后的感悟,转载请注明出处~ ARM工作模式 ARM工作模式根据功能不同,可分为7类: User Mode:用户模式.操作系统的Task一般以这种模式执行 ...

  5. TimeUtils(没试过)

    package util; import java.text.DateFormat; import java.text.DecimalFormat; import java.text.ParseExc ...

  6. c/c++面试19-22----inline的那些事儿

    19 为什么引入内联函数 a:宏定义为什么效率高 通常替代c语言中表达式形式的宏定义来解决程序函数调用问题,使用的是预处理器实现,没有参数压栈等到做. 缺点: (1) 仅仅进行简单的替换,不能进行参数 ...

  7. TypeScript完全解读(26课时)_19.其他重要更新

    ts3.3升级过来有很多重要的更新 没法归类的更新,在本节课几种讲一下 创建update.ts,然后在index.ts内引入 async和promise es6中增加了promise的支持,能够很好处 ...

  8. EasyUI 启用行内编辑

    创建数据网格(DataGrid) $(function(){ $('#tt').datagrid({ title:'Editable DataGrid', iconCls:'icon-edit', w ...

  9. myeclipse 去掉spring特性支持

    myeclipse10.0 去掉spring支持  手工修改工程目录下的.project文件中相关的内容 删除<nature>com.genuitec.eclipse.springfram ...

  10. Qt测试代码执行时间

    ////////////////////////////////////////////////////////////////// QString _GetIntervalTime(QTime&am ...