一、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. codeforces B. Eugeny and Play List 解题报告

    题目链接:http://codeforces.com/problemset/problem/302/B 题目意思:给出两个整数n和m,接下来n行给出n首歌分别的奏唱时间和听的次数,紧跟着给出m个时刻, ...

  2. Python GIL、线程锁、信号量及事件

    GIL是什么? GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念.就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码.有名的编 ...

  3. Understand JavaScript Callback Functions and Use Them

    In JavaScript, functions are first-class objects; that is, functions are of the type Object and they ...

  4. 【转载】如何在 C#中访问 JavaScript函数?

    如何在 C#中访问 JavaScript函数? 时间:13-10-17 栏目:Unity3D教程 作者:zqcyou 评论:0     如何在 C#中访问 JavaScript函数?答案如下:c#代码 ...

  5. 【C】论‘\r’和'\n'的纯粹性

  6. BZOJ_4809_皇后_爆搜

    BZOJ_4809_皇后_爆搜 Description 众所不知,rly现在不会玩国际象棋.但是,作为一个OIer,rly当然做过八皇后问题.这里再啰嗦几句,皇后可以攻击到同行同列同对角线,在n*n的 ...

  7. 洛谷P4014分配问题——网络流24题

    题目:https://www.luogu.org/problemnew/show/P4014 最大/小费用最大流裸题. 代码如下: #include<iostream> #include& ...

  8. bzoj2750Road——最短路计数

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2750 以每个点作为源点,spfa跑出一个最短路图(不一定是树,因为可能很多条最短路一样长): ...

  9. Lsyncd搭建同步镜像-用Lsyncd实现本地和远程服务器之间实时同步

    Lysncd即Live Syncing Daemon,它是开源的数据实时同步工具(后台进程),基于inotify和rsync. lsyncd会密切监测本地服务器上的参照目录,当发现目录下有文件或目录变 ...

  10. FFmpeg常用命令 (二)

    使用网络上的各种转码软件,简直崩溃了!比如,它竟然强行把你要编辑的视频的前面,现在可以使用ffmpeg. ffmpeg做IT media的都知道,很强大,只不多对windows用户比较麻烦,可以使用L ...