Hibernate - Session
- Session 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心,所有持久化对象必须在 session 的管理下才可以进行持久化操作, 此对象的生命周期很短。
- Session 对象有一个一级缓存,显式执行 flush 之前,所有的持久层操作的数据都缓存在 session 对象处, 相当于 JDBC 中的 Connection。
- Session 接口是 Hibernate 向应用程序提供的操纵数据库的最主要的接口, 它提供了基本的保存, 更新, 删除和加载 Java 对象的方法.
- Session 具有一个缓存, 位于缓存中的对象称为持久化对象, 它和数据库中的相关记录对应. Session 能够在某些时间点, 按照缓存中对象的变化来执行相关的 SQL 语句, 来同步更新数据库, 这一过程被称为刷新缓存(flush)
站在持久化的角度, Hibernate 把对象分为 4 种状态: 临时状态, 持久化状态,, 游离状态, 删除状态. Session 的特定方法能使对象从一个状态转换到另一个状态
--------------------------------------------------------------------------------------------------------------------------------------
- Session 类的方法:
– 取得持久化对象的方法: get() load()
– 持久化对象都得保存,更新和删除:save(),presist(),update(),saveOrUpdate(),delete()
– 开启事务: beginTransaction().
– 管理 Session 的方法:isOpen(),flush(), clear(), evict(), close()等
-------------------------------------------------------------SAVE-------------------------------------------------------------------------
-----------------------------------------------GET AND LOAD---------------------------------------------------------------------------------------
1. 执行 get 方法: 会立即加载对象. 执行 load 方法, 若不使用该对象, 则不会立即执行查询操作, 而返回一个代理对象,get 是 立即检索, load 是延迟检索.
2. load 方法可能会抛出 LazyInitializationException 异常: 在需要初始化代理对象之前已经关闭了 Session
3. 若数据表中没有对应的记录, Session 也没有被关闭. get 返回 nullload 若不使用该对象的任何属性, 没问题; 若需要初始化了, 抛出异常.
--------------------------------------------------------UPDATE------------------------------------------------------------------------------
1. 若更新一个持久化对象, 不需要显示的调用 update 方法. 因为在调用 Transaction
的 commit() 方法时, 会先执行 session 的 flush 方法.
2. 更新一个游离对象, 需要显式的调用 session 的 update 方法. 可以把一个游离对象
变为持久化对象
需要注意的:
1. 无论要更新的游离对象和数据表的记录是否一致, 都会发送 UPDATE 语句.
如何能让 updat 方法不再盲目的出发 update 语句呢 ? 在 .hbm.xml 文件的 class 节点设置
select-before-update=true (默认为 false). 但通常不需要设置该属性.
2. 若数据表中没有对应的记录, 但还调用了 update 方法, 会抛出异常
3. 当 update() 方法关联一个游离对象时,
如果在 Session 的缓存中已经存在相同 OID 的持久化对象, 会抛出异常. 因为在 Session 缓存中
不能有两个 OID 相同的对象!
----------------------------------------------------SAVEORUPDATE----------------------------------------------------------------------------------
若 OID 不为 null, 但数据表中还没有和其对应的记录. 会抛出一个异常.
------------------------------------------------------------FLUSH--------------------------------------------------------------------------
- flush:Session 按照缓存中对象的属性变化来同步更新数据库
- 默认情况下 Session 在以下时间点刷新缓存:
– 显式调用 Session 的 flush() 方法
– 当应用程序调用 Transaction 的 commit()方法的时, 该方法先 flush ,然后在向数据库提交事务
– 当应用程序执行一些查询(HQL, Criteria)操作时,如果缓存中持久化对象的属性已经发生了变化,会先 flush 缓存,以保证查询结果能够反映持久化对象的最新状态
- flush 缓存的例外情况: 如果对象使用 native 生成器生成 OID, 那么当调用 Session 的 save() 方法保存对象时, 会立即执行向数据库插入该实体的 insert 语句.
commit() 和 flush() 方法的区别:flush 执行一系列 sql 语句,但不提交事务;commit 方法先调用flush() 方法,然后提交事务. 意味着提交事务意味着对数据库操作永久保存下来。
- 若希望改变 flush 的默认时间点, 可以通过 Session 的 setFlushMode() 方法显式设定 flush 的时间点
------------------------------------------------------------DELETE--------------------------------------------------------------------------
/**
* evict: 从 session 缓存中把指定的持久化对象移除
*/
@Test
public void testEvict(){
News news1 = (News) session.get(News.class, 1);
News news2 = (News) session.get(News.class, 2);
news1.setTitle("AA");
news2.setTitle("BB");
session.evict(news1);
}