一、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. java random配置修改

    不知道 报啥错的时候 ,改这个 vim /usr/java/latest/jre/lib/security/java.security 原值: securerandom.source=file:/de ...

  2. 脚踏实地学C#3-装箱和拆箱

    装箱:一种接受值类型的值,根据这个值在堆中创建一个完整的引用类型对象并返回对象的引用(堆地址)的隐式转换 int i_number = 2; //在栈中声明int类型i_Number变量并初始化 ob ...

  3. poj3181【Dollar Dayz】

    做完这道题,心里五味陈杂,明明是最水的一道题,我却做了最长的时间. 题意是求用1-k的和表示n的方案数. 显然是个计数dp,但我不会.思考半小时未果. 然后找尹鹏哲,他给我讲了个错的dp方程,结果调试 ...

  4. 51Nod - 1821:最优集合 (求第一个不能被表示为多个数的和的数)(不错的动脑题)

    一个集合S的优美值定义为:最大的x,满足对于任意i∈1,x1,x,都存在一个S的子集S',使得S'中元素之和为i. 给定n个集合,对于每一次询问,指定一个集合S1和一个集合S2,以及一个数k,要求选择 ...

  5. SQL连接查询和嵌套查询详解

    连接查询 若一个查询同时涉及两个或两个以上的表,则称之为连接查询.连接查询是数据库中最最要的查询, 包括: 1.等值连接查询 2.自然连接查询 3.非等值连接查询 4.自身连接查询 5.外连接查询 6 ...

  6. Android开发者的四大工具

    1. Basic4Android Basic4Android是Android平台上一个简单而又强大的可视化快速应用开发工具,它可被用来开发和测试数据库通信,甚至可以被用来开发2D的即时游戏! 主要特性 ...

  7. python下载各大主流视频网站电影

    You-Get 是一个命令行工具, 用来下载各大视频网站的视频, 是我目前知道的命令行下载工具中最好的一个, 之前使用过 youtube-dl, 但是 youtube-dl 吧, 下载好的视频是分段的 ...

  8. Docker运行MongoDB及Redis及ssh端口映射远程连接

    Docker运行MongoDB及Redis及ssh端口映射远程连接 本节内容简介 在本实验里我们将通过完成 MongoDB 和 Redis 两个容器来学习Dockerfile及Docker的运行机制. ...

  9. Google 马来西亚主页被黑

    互联网并没有想象中安全,Google 马来西亚主页被黑 | TheVerge 消… 查阅全文 ›

  10. Unity4.0配置

    关于Unity4.0的使用: 一 安装Unity 在程序包管理器控制台输入命令:Istall-Pckage unity.mvc安装后会在App_Start中生成UnityConfig.cs 和Unit ...