一、Session概述

Session是应用程序与数据库之间的一个会话,是Hibernate运作的中心,持久层操作的基础,相当于JDBC中的Connection。Session对象是通过SessionFactory创建的:

Session session = SessionFactory.openSession();

一个持久化类与普通的JavaBean没有任何区别,但是它与Session关联后,就具有了持久化能力。当然,这种持久化操作是受Session控制的,即通过Session对象的装载,保存,创建或查询持久化对象。Session类的save(),delete()和load()等方法,来分别完成对持久化对象的保存,删除,修改加载等操作!Session类方法的用途可以分以下五类:

1:取得持久化对象:get()和load()等方法。

2:持久化对象的保存,更新和删除:save(),update()saveOrUpdate()和delete()等方法。

3:createQuery()方法:用来从Session生成的Query对象。

4:beginTransaction()方法:从Session对象生成一个Transaction对象。

5:管理Session的方法:isOpen(),flush(),clear(),evict()和close()等方法,其中isOpen()方法用来检查Session是否仍然打开;flush()用来清理Session缓存,并把缓存中的SQL语句发送出去,clear()用来清除Session中的所有缓存对象evict()方法来清楚Session缓存中的某个对象;close()关闭Session。

二、取得持久化对象的方法详解

1、get方法:

TRegister tr = (TRegister)session.get(TRegister.class, new Integer(1));

get()方法的执行顺序如下:

--首先通过id在session缓存中查找对象,如果存在此id的对象,直接将其返回

--在二级缓存中查找,找到后将其返回。

--如果在session缓存和二级缓存中都找不到此对象,则从数据库中加载有此ID的对象

因此get()方法并不总是导致SQL语句,只有缓存中无此数据时,才向数据库发送SQL!

2、load方法

TRegister tr = (TRegister)session.load(TRegister.class, new Integer(1));

与get()的区别:

---在立即加载对象时,如果对象存在,load()和get()方法没有区别,都可以取得已初始化的对象;但如果当对象不存在且是立即加载时,使用get()方法则返回null,而使用load()则抛出一个异常。因此使用load()方法时,要确认查询的主键ID一定是存在的。

---load 方法支持延迟加载策略。而 get 不支持。在延迟加载对象(Hibernate从数据库中取得数据组装好一个对象后,不会立即再从数据库取得数据组装此对象所关联的对象,而是等到需要时,从数据库取得数据组装此对象关联的对象)时,get()方法仍然使用立即加载的方式发送SQL语句,并得到已初始化的对象。而load()方法则根本不发送SQL语句,它返回一个代理对象,直到这个对象被访问时才被初始化。

三、持久化对象的保存,更新和删除方法

1、save()方法

session的save()方法将 一个POJO的属性取出放入PreparedStatement语句中,然后向数据库中插入一条记录(或多条记录,如果有级联)。

session保存一个对象时,按如下步骤进行:

---根据配置文件为主键id设置的生成算法 ,为POJO指定 一个ID。

---将 POJO对象纳入session内部缓存(一个Map)内。

---事务提交时,清理缓存,将 新对象通过insert语句持久化到数据库中。

如果要为新的POJO强制指定一个ID,可以调用Session的重载方法save(Object obj,Serializable id)

例:

       session.save(tRegister, new Integer(123));

---在调用save()方法时,并不立即执行SQL语句,而是等到清理完毕缓存时才执行。如果在调用save()方法后又修改了POJO的属性,则Hibernate将 会发送一条insert语句和额外的一条update语句来完成持久化操作。

例如:

session.save(tr);

tr.setUserName("chen");//在save后又修改了PO名字

上述语句执行后产生的SQL语句如下:

Hibernate: select max(id) from t_register

Hibernate: insert into t_register (userName, userPwd, sex, age, id) values (?, ?, ?, ?, ?)

Hibernate: update t_register set userName=?, userPwd=?, sex=?, age=? where id=?

因此,最好是在对象状态稳定时再调用 save()方法,可以少执行一条update语句。

---Hibernate 通过持久化对象的 OID 来维持它和数据库相关记录的对应关系. 当 对象处于持久化状态时, 不允许程序随意修改它的 ID。

2、persist() 方法

persist()使一个临时实例持久化。然而,它不保证立即把标识符值分配给持久性实例,而推迟到flush的时候。persist() 也保证它在事务边界外调用时不会执行 INSERT 语句。这对于长期运行的带有扩展会话/持久化上下文的会话是很有用的。

与save的区别:

---使用 save() 方法保存持久化对象时,该方法返回该持久化对象的标识属性值(即对应记录的主键值);但使用 persist() 方法来保存持久化对象时,该方法没有任何返回值。

---因为 save() 方法需要立即返回持久化对象的标识属性,所以程序执行 save() 会立即将持久化对象对应的数据插入数据库;而 persist() 则保证当它在一个事物外部被调用时,并不立即转换成 insert 语句, 这个功能是很有用的,尤其当我们封装一个长会话流程的时候,persist() 方法就显得尤为重要了。

---当对一个 OID 不为 Null 的对象执行 save() 方法时, 会把该对象以一个新的 oid 保存到数据库中;  但执行 persist() 方法时会抛出一个异常。

调用save()方法将临时对象保存到数据库中,对象的游离状态将 变为持久化状态。当对象在持久化状态时,它一直位于Session缓存中,对它的任何操作在事物提交时都将同步保存到数据库中,因此,对一个已经持久化的对象调用save()或update()方法是没有意义的。

3、update()方法

Session 的 update() 方法使一个游离对象转变为持久化对象, 并且计划执行一条 update 语句。调用update()方法时,并不是立即发送SQL语句,对对象的更新操作将积累起来,在事物提交时由flush()清理缓存,然后发送一条SQL语句完成全部的更新操作! 若希望 Session 仅当修改了持续化对象的属性时,
才执行 update() 语句, 可以把映射文件中 <class> 元素的 select-before-update 设为 true. 该属性的默认值为 false。当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象, 会抛出异常。如果在数据库中不存在相应的记录, 也会抛出异常。

使用示例:

tr.setUserName("chen");  //设置新值

session.update(tr); //更新数据库

4、saveOrUpdate()方法

Session 的 saveOrUpdate() 方法同时包含了 save() 与 update() 方法的功能。

saveOrUpdate()方法首先会判断该PO是脱管对象还是临时对象,然后会调用合适的方法。

那么saveOrUpdate()方法如何判断PO是临时对象还是 游离对象呢?当满足下载情况之一时,Hibernate就认定它是临时对象。

-----在映射表中为<id>设元素设置了unsaved-valu属性,并且实体对象的ID取值和unsaved-value匹配(默认为null)(注意:int和long型的ID的unsaved-value默认值为0)。

-----在映射文件中为<version>元素设置了unsaved-value属性,并且实体对象的version取值和unsaved-value匹配(默认为null)。

5、delete()方法

Session 的 delete() 方法既可以删除一个游离对象, 也可以删除一个持久化对象。

处理过程:

----计划执行一条 delete 语句

----把对象从 Session 缓存中删除, 该对象进入删除状态。

在调用delete()方法时并不是发送SQL语句,而是在提交事务时,清理了缓存才发送SQL。使用delete()删除对象时,会有一些性能上的问题,当删除一个对象时,会先调用get()加载这个对象,然后调用delete()方法删除对象,所以发送了一个多余的selete SQL,所以当删除大量数据时对性能影响就比较大了。为了解决批量删除的性能问题,常用的办法是使用批量删除操作。

Hibernate 的 cfg.xml 配置文件中有一个 hibernate.use_identifier_rollback 属性, 其默认值为 false, 若把它设为 true, 将改变 delete() 方法的运行行为: delete() 方法会把持久化对象或游离对象的 OID 设置为 null, 使它们变为临时对象。

6、Query对象

Query接口主要方法有三个

setXXX()方法:用于设置HQL中问题或变量的值。

list()方法:返回查询结果,并把结果转换成List对象。

executeUpdate()方法:执行更新或删除名。

setXXX()方法都有二种重载方法:

1)setString(int position,String value):用于设置HQL中“?”的值:其中position表示?位置,而value是相应的值。如下:

Query query = session.createQuery("from TRegister tr where tr.age>? and tr.userName like ?");//生成一个Query实例

query.setInteger(1, 18);//设置第一个问号的值为18

query.setString(2, "%chen%");//设置第二个问号的值为%chen%

2)setString(String paraName,String value);用于设置HQL中“:”后跟变量的值;其中paraName代表HQL中“:”后跟变量,value为该变量设置的值。如下:

 Query query = session.createQuery("from TRegister tr where tr.age>:minAge and tr.userName like :userName");//生成一个Query实例

query.setInteger("minAge", 18);//设置变量minAge值为18

query.setString("userName", "%yan%");//设置变量userName值为%yan%

 

推荐在HQL中使用第二种方法,相比第一种有以下好处:

---变量不依赖于它们在查询字符串中出现 的顺序。

---在同一个查询中可以多次使用。

---可读性好。



list()方法:

Query的list()方法用于取得查询结果,并将结果转变成一个List接口的实例。

Query query = session.createQuery("from TRegister");  //初始化Query

java.util.List list = query.list(); //获取查询结果并转为List对象

executeUpdate()方法:

Query的executeUpdate()方法用于更新或删除语句。它常用于批量删除或批量更新操作

Hibernate中的Sesson操作的更多相关文章

  1. [原创]关于Hibernate中的级联操作以及懒加载

    Hibernate: 级联操作 一.简单的介绍 cascade和inverse (Employee – Department) Casade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似 ...

  2. Hibernate中的CRUD操作

    1.添加数据操作 插入数据使用session对象的save()方法完成.   插入代码: @Test public void Test1(){ SessionFactory sessionFactor ...

  3. 如何理解Hibernate中的HibernateSessionFactory类

    package com.zz.util; import org.hibernate.HibernateException; import org.hibernate.Session; import o ...

  4. (转)Hibernate中的多表操作

    http://blog.csdn.net/yerenyuan_pku/article/details/70556208 Hibernate中的多表操作 在实际开发中,我们不可能只是简简单单地去操作单表 ...

  5. Hibernate中的锁机制

    锁机制:是数据库为了保证数据的一致性<一个事务的各种操作不相互影响>而使各种共享资源在被并发访问访问变得有序所设计的一种规则,用来保证在当前用户进行操作数据的时候其他的用户不能对同一数据进 ...

  6. Java三大框架之——Hibernate中的三种数据持久状态和缓存机制

    Hibernate中的三种状态   瞬时状态:刚创建的对象还没有被Session持久化.缓存中不存在这个对象的数据并且数据库中没有这个对象对应的数据为瞬时状态这个时候是没有OID. 持久状态:对象经过 ...

  7. Hibernate 系列 07 - Hibernate中Java对象的三种状态

    引导目录: Hibernate 系列教程 目录 1. Java对象的三种状态 当应用通过调用Hibernate API与框架发生交互时,需要从持久化的角度关注应用对象的生命周期. 持久化声明周期是Hi ...

  8. Hibernate中evict方法和clear方法说明

    Hibernate中evict方法和clear方法说明 先创建一个对象,然后调用session.save方法,然后调用evict方法把该对象清除出缓存,最后提交事务.结果报错: Exception i ...

  9. hibernate(七) hibernate中查询方式详解

    序言 之前对hibernate中的查询总是搞混淆,不明白里面具体有哪些东西.就是因为缺少总结.在看这篇文章之前,你应该知道的是数据库的一些查询操作,多表查询等,如果不明白,可以先去看一下 MySQL数 ...

随机推荐

  1. Java-动态规划-最多苹果数量的方法

    平面上有N*M个格子,每个格子中放着一定数量的苹果.你从左上角的格子开始,每一步只能向下走或是向右走,每次走到一个格子上就把格子里的苹果收集起来,这样下去,你最多能收集到多少个苹果. 思路: 解这个问 ...

  2. Enable and Use Remote Commands in Windows PowerShell

    The Windows PowerShell remoting features are supported by the WS-Management protocol and the Windows ...

  3. javascript 函数重载另一种实现办法

    最近在读javascript忍者 感受下jquery作者 john Resig对于js的独到见解. 先上代码: function addMethod(object,name,fn){ var old ...

  4. Epoll详解及源码分析【转】

    转自:http://blog.csdn.net/chen19870707/article/details/42525887 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] ...

  5. 【leetcode】Find All Anagrams in a String

    [leetcode]438. Find All Anagrams in a String Given a string s and a non-empty string p, find all the ...

  6. Ural 1774 Barber of the Army of Mages 最大流

    题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1774 1774. Barber of the Army of Mages Time li ...

  7. 简单的makefile模板

    makefile不是总用到,每次用到的时候总要重新找资料,有点麻烦(怪自己基础知识不扎实,汗).留一个通用模板放这,方便以后使用 CC = gcc CXX = g++ LINK = g++ CFLAG ...

  8. poj 2104 K-th Number(主席树

    Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 59058   Accepted: 20529 Case Time Limi ...

  9. webstorm 2016 激活破解

    2017.2.27更新 选择“license server” 输入:http://idea.imsxm.com/ 2016.2.2 版本的破解方式: 安装以后,打开软件会弹出一个对话框:选择“lice ...

  10. 深入理解Activity启动流程(三)–Activity启动的详细流程2

    本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--A ...