1、持久化对象的状态
【1】临时对象(Transient)
- 在使用代理主键的情况下, OID 通常为 null
- 不处于 Session 的缓存中
- 在数据库中没有对应的记录
【2】持久化对象(也叫”托管”)(Persist)
- OID 不为 null
- 位于 Session 缓存中
- 若在数据库中已经有和其对应的记录,持久化对象和数据库中的相关记录对应
- Session 在 flush 缓存时,会根据持久化对象的属性变化,来同步更新数据库
- 在同一个 Session 实例的缓存中,数据库表中的每条记录只对应唯一的持久化对象
【3】删除对象(Removed)
- 在数据库中没有和其 OID 对应的记录
- 不再处于 Session 缓存中
- 一般情况下, 应用程序不该再使用被删除的对象
【4】游离对象(也叫”脱管”) (Detached)
- OID 不为 null
- 不再处于 Session 缓存中
- 一般情况需下, 游离对象是由持久化对象转变过来的, 因此在数据库中可能还存在与它对应的记录
2、对象的状态转换图
3、Session中的几个重要方法说明
【1】save()
- 使一个临时对象变为持久化对象
- 自动为对象分配ID
- 在flush缓存时,会发送一条insert语句
- 在save之前,使用setxx()方法设置的ID是无效的
- 在save之后不能修改ID/持久化对象的ID是不能被修改的
【2】persist()
- 与save()方法类似,也会执行insert操作
- persist()与save()的区别:在调用persist()方法之前,若对象已经有ID了,则不会执行insert操作,而是会抛出异常。
【3】get()与load()的区别
-get()
是立即检索,load()
是延迟检索。执行get()
方法,会立即加载对象;执行load()
方法,若不适用该对象,则不会立即执行查询操作,而是返回一个代理对象。
- 在需要初始化代理对象之前关闭
session
,load()
方法会抛出LazyInitializationException的异常。 - 若数据表中没有对应的记录,session也没有被关闭,
get
会返回null
,load
会抛出异常。
【4】update()方法
- 若更新一个持久化对象,不需要显式地调用
update()
方法,因为在调用Transaction
的commit()
方法时,会先执行session
的flush()
方法。 - 更新一个游离对象,需要显式地调用
session
的update()
方法。隐藏作用:可以将一个游离对象变为持久化对象。
注意:
① 无论要更新的游离对象和数据表的记录是否一致,都会发送update语句。
② 如何能让update方法不再盲目地发送update语句?
在*.hbm.xml
文件的class
节点设置select-before-update=true(默认为false)
,通常不设置此属性。
③ 若数据表中没有对应的记录,但是又调用了update
方法,则会抛出异常。
④ 当update()
方法关联一个游离对象时,如果在session的缓存中已经存在相同的OID,则会抛出异常。因为- 在session缓存中,不存在相同OID的对象
【5】saveOrUpdate()方法
- 如果OID不为null,但数据表中还没有其对应的记录,则会抛出异常。
- 如果OID为null,调用session的saveOrUpdate()方法后执行的是insert语句。如果OID不为null,且数据表中有与之对应的记录,调用session的saveOrUpdate()方法后执行的是update语句。
- 了解:OID值等于id的
unsaved-value
属性值的对象,也被认为是一个游离对象。
【6】delete()方法
- 执行删除操作。只要OID和数据表中的一条记录对应,就会执行delete操作;若OID在数据表中没有对应的记录,则抛出异常。
- 可以通过设置Hibernate配置文件的
hibernate.use_identifier_rollback
为true
,使删除对象后,把OID置为null。其默认值是false。
【7】evict()方法
- 作用:从session中移除指定的持久化对象。