本文内容来自尚硅谷
目录
1.2session核心方法之间的关系,以及几个临时对象之间的关系图
3.3若数据表中没有对应的记录, Session 也没有被关闭.
1先介绍几个概念
1.1持久化对象的状态
说明:站在持久化角度,hibernate把对象分为临时状态,持久化状态,游离状态,删除状态
1.1.1临时对象
在使用代理主键的情况下, OID 通常为 null
不处于 Session 的缓存中
在数据库中没有对应的记录
1.1.2持久化对象
OID 不为 null
位于 Session 缓存中
若在数据库中已经有和其对应的记录, 持久化对象和数据库中的相关记录对应
Session 在 flush 缓存时, 会根据持久化对象的属性变化, 来同步更新数据库
在同一个 Session 实例的缓存中, 数据库表中的每条记录只对应唯一的持久化对象
1.1.3删除对象(Removed)
在数据库中没有和其 OID 对应的记录
不再处于 Session 缓存中
一般情况下, 应用程序不该再使用被删除的对象
1.1.4游离对象(也叫”脱管”) (Detached)
OID 不为 null
不再处于 Session 缓存中
一般情况需下, 游离对象是由持久化对象转变过来的, 因此在数据库中可能还存在与它对应的记录
1.2session核心方法之间的关系,以及几个临时对象之间的关系图
在下面的实例中,会具体介绍到哪些对象属于持久化对象,哪些属于临时对象或者托管对象等。下面分别介绍session的核心方法。save()与persist(),get与load,close,clear和evict方法,update() 与saveOrUpdate(),delete方法
下面方法代码都是在Hibernate总结(四)--session缓存中1.4创建的helloworld代码基础上编写代码
2save与persist方法
2.1在HibernateTest中添加一个test
2.2对象解释
在执行save前news对象为临时状态,在执行save这行代码后news对象为持久化对象
2.3注意
2.3.1
临时对象没有设置id值,系统会制动分配一个id值将对象保存到数据库中所以271行输出的news对象中是有id值得,而269行输出的news对象是没有id值的
2.3.2在 save 方法之前设置id 是无效的
因为数据库中id值不会代表任何业务上的意义,所以hibernate在这里不允许制动的设置id值。如下
对象依然保持到了数据库,并且代码不会报错。但是id值依然是采用默认的方式设置的值并保存到数据库中(也就是说值不是100)。下面这种情况也是
2.3.3持久化对象的 ID 是不能被修改的!
如下图的代码执行后会抛异常
因为hibernate中持久化对象的id是不能被修改的。
2.4persist方法
2.4.3在HibernateTest中添加一个test
persist方法和save方法一样都能把一个临时对象保存在数据中并使其变为持久化对象。
2.4.4persist与save区别
下面的代码会抛出异常
在调用 persist 方法之前, 若对象已经有 id 了, 则不会执行 INSERT, 而抛出异常。save就不会抛出异常。
3get方法与load方法的区别
面试的时候可能会问到
3.1get 是 立即检索, load 是延迟检索
3.1.2在HibernateTest中增加两个test
3.1.3说明
在get方法中执行了229行后230以前news对象就已经有值了,而在load方法时在224行用到news对象时才会向数据查询数据并得到news对象。
执行 get 方法: 会立即加载对象. 执行 load 方法, 若不适用该对象, 则不会立即执行查询操作, 而返回一个代理对象。
3.2 load 方法可能会抛出异常
3.2.1代码部分
下面代码会抛出错误
3.2.2说明一
load属于延迟加载,而此时session已经关闭如果再在227行去执行查询操作,则会抛出 LazyInitializationException 异常
3.3若数据表中没有对应的记录, Session 也没有被关闭.
get 返回 null
load 若不使用该对象的任何属性, 没问题; 若需要初始化了, 抛出异常
3.3.1代码部分
若数据库中news表中id值没有10和1这两条记录,则执行下面代码224行会报错,230行会控制台打印null
即
若数据表中没有对应的记录, Session 也没有被关闭.
get 返回 null
load 若不使用该对象的任何属性, 没问题; 若需要初始化了, 抛出异常.