hibernate中的Session详解

一、session概述

Session是应用程序与数据库之间交互操作的一个单线程对象,是Hibernate运作的中心,所有持久化对象必须在session的管理下才可以进行持久化操作。此对象的生命周期很短。Session对象有一个一级缓存,显示执行flush之前,所有的持久层操作的数据都缓存在session对象处。相当于JDBC中的Connection。持久化类与Session关联起来后就具有了持久化的能力。


二、通过session操作持久化类
Session接口是Hibernate向应用程序提供的操作数据库的最主要的接口,它提供了基本的保存,更新,删除和加载Java对象的方法

Session具有一个缓存,位于缓存中的对象称为持久化对象,它和数据库中的相关记录。对应。Session能够在某些时间点,按照缓存中对象的变化来执行相关的SQL语句,来同步更新数据库,这一过程被称为刷新缓冲(flush)

站在持久化的角度,hibernate把对象分为4种状态:持久化状态,临时状态,游离状态,删除状态。Session的特定方法能使对象从一个状态转换到另一个状态

Session缓存
在Session接口的实现中包含一系列的java集合,这些java集合构成了Session缓存。只要Session实例没有结束生命周期,存放在它缓存中的对象也不会结束生命周期


Session缓存可减少Hibernate应用程序访问数据库的频率。

session的flush()方法:使数据表中的记录和Session缓存中的对象的状态保持一致,为了保持一致,则可能会发送对应的
1.在Transaction的commit()方法中:先调用session的flush方法,再提交事务
2.flush()方法可能会发送SQL语句,但不会提交事务
refresh()会强制发送select语句,以使Session缓存中对象的状态和数据表中对应的记录保持一致!

3.注意:在未提交事务或显示的调用session.flush()方法之前,也有可能会进行flush()操作

1)执行HQL或QBC查询,会先进行flush()操作,以得到数据表的最新的记录

QBC操作示例:
News news2 = (News) session.createCriteria(News.class).uniqueResult();

2)若记录的ID是由底层数据库使用自增的方式生成的,则在调用save()方法后,就会立即发送INSERT语句
因为save方法后,必须保证对象的ID是存在的!

数据库的隔离级别


对于同时运行的多个事务,当这些事务访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致各种并发问题:
脏读:对于两个事务T1,T2,T1读取了已经被T2更新但还没有被提交的字段之后,若T2回滚,T1读取的内容就是临时且无效的。
不可重复读:对于两个事务T1,T2,T1读取了一个字段,然后T2更新了该字段,之后T1再次读取同一个字段,值就不同了。
幻读:对于两个事务T1,T2,T1从一个表中读取了一个字段,然后T2在该表中插入了一些新的行,之后,如果T1再次读取同一个表,就会多出几行。


数据库事务的隔离性:数据库系统必须具有隔离并发运行各个事务的能力,使他们不会相互影响,避免各种并发问题

一个事务与其他事务隔离的程度称为隔离级别。数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。

数据库提供的4种事务隔离级别:

在hibernate中设置隔离级别

JDBC数据库连接使用数据库系统默认的隔离级别。在hibernate的配置文件中可以显示的设置隔离级别。每一个隔离级别都对应一个整数:

1 READ UNCOMMITED
2 READ COMMITED
4 REPEATABLEREAD
8 SERIALIZEABLE


session.clear()方法:清理缓存

三、session核心方法

1.持久化对象的状态


站在持久化的角度,Hibernate把对象分为4种状态:

①、持久化状态

持久化对象(也叫“托管”)(Persist)


OID不为null
位于Session缓存中
若在数据库中已经有和其对应的记录,持久化对象和数据库中的相关记录对应
Session在flush缓存时,会根据持久化对象的属性变化,来同步更新数据库
在同一个Session实例的缓存中,数据库表中的每条记录只对应唯一的持久化对象



②、临时状态


临时对象(Transient):
在使用代理主键的情况下,OID通常为null
不处于Session的缓存中
在数据库中没有对应的记录


③、游离状态


OID不为null
不再处于Session缓存中
一般情况下,游离对象是由持久化对象转变过来的,因此在数据库中可能还存在与它对应的记录。


④、删除状态


在数据库中没有和其OID对应的记录
不再处于Session缓存中
一般情况下,应用程序不该再使用被删除的对象






Session的特定方法能使对象从一个状态转到另一个状态




1.save()方法
使一个临时对象变为持久化对象
为对象分配id
在flush缓存时会发送一条insert语句
在save方法之前设置的id是无效的
持久化对象的ID是不能被修改的


2.persist():也会执行insert操作


save()与persist()区别
在调用persist方法之前,若对象已经有id了,则不会执行INSERT,而抛出异常


3.get():立即检索

4.load():延迟检索


get VS load:


1.执行get方法:会立即加载对象,
而执行load方法,若不使用该对象,则不会立即执行查询操作,而返回一个代理对象


2.若数据表中没有对应的记录,且Session也没有被关闭,同时需要使用对象时,
get返回null
load抛出异常 :若不使用该对象的任何属性,没有问题;但是若要初始化了,抛出异常


3.load方法可能会抛出LazyInitializationException异常:在需要初始化代理对象之前已经关闭了session




Session的update()方法


1。若更新一个持久化对象,不需要显示的调用update方法。因为在调用Transaction的commit方法时,会先执行session的flush方法。。


2.更新一个游离对象,需要显示的调用session的update方法,可以把一个游离对象变成一个持久化对象


3.无论要更新的游离对象和数据表的记录是否一致,都会发送UPDATE语句。
如何能让update方法不再盲目的触发update语句呢?在.hbm.xml文件的class页面设置一个属性select-before-update="true",通常不要设置


4若数据表中没有对应的记录,但还调用了update方法,会抛出异常


5.当update()方法关联一个游离对象时,如果在session的缓存中已经存在相同OID的持久化对象,会抛出异常。因为session缓存中不能有两个OID




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


判定对象为临时对象的标准:
java对象的OID为null
映射文件中为<id> 设置了unsaved-value属性,并且java对象的OID取值与这个unsaved-value属性值匹配


注意:1.若OID不为null,但数据表中还没有和其对应的记录,会抛出一个异常,
2.了解OID值等于id的unsaved-value属性值的对象,也被认为是一个游离对象




Session的merge()方法


Session的delete()方法,执行删除操作,只要OID和数据表中一条记录对应,就会准备执行delete操作,


若OID在数据表中没有对应的记录,则抛出异常hibernate.use_identifier_rollback为可以通过设置hibernate配置文件true,使删除对象后,把其OID置为null


游离对象
News news = new News();
 news.setId(11);


持久化对象
News news = (News) session.get(News.class,131072);
session.delete(news);


session的evict方法:从session缓存中把指定的持久化对象移除




三、通过hibernate调用存储过程


session.doWork(new Work(){
public void execute(Connection connection){
//用connection对象操作存储过程
}


}


);

总结:
如何能让update方法不再盲目的触发update语句呢?在.hbm.xml文件的class页面设置一个属性select-before-update="true",通常不要设置,与触发器协同工作时使用
调用reflush()保持数据库与session缓存数据一致
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值