Hibernate - Session

旧城冷巷雨未停 提交于 2020-03-19 18:17:34

  • 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);
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!