实体状态和转换
JPA提供一个持久化上下文作为一级缓存,提供自动脏检查.对应某个id的实例在持久化上下文中只有一个对象.
查询时总是尝试在当前上下文中先搜索对象,不存在再触发数据库查询.
托管状态的bean会建立一个和缓存数据的联系,这时bean的属性改变同时会修改缓存数据,此时这条数据就变成了脏数据。
实体状态详解
临时状态:
实际上就是new了一个普通的JavaBean对象。
托管状态
临时状态实体在调用persist()后,会根据策略分配ID,然后会被持久化到数据库中,同时也会在缓存中生成一条数据,即将一般的JavaBean变为了托管状态的Bean,该Bean的任何属性改动都会修改缓存状态,让缓存数据和数据库数据有差异,这时这条数据就变为了脏数据,当进行flush时,就会产生更新数据库操作。
一旦该记录flush到数据库之后,并且事务提交了,那么此对象不在持久化上下文中,即:变为了游离(没人管的孩子)状态了。
在游离状态的时候调用更新、刷新方法后,游离状态对象就变为了在持久化上下文的托管状态了。
通过管理器的find方法,将实体从数据库查询出来后,该实体也就变为了托管形态。
持久化状态
当处在托管状态的实体Bean被管理器flush了,那么就在极短暂的时间进入了持久化状态,事务提交之后,立刻变为了游离状态。
您可以把持久化状态当做实实在在的数据库记录。
游离状态
游离状态就是提交到数据库后,事务commit后实体的状态,因为事务已经提交了,此时实体的属性任你如何改变,也不会同步到数据库,因为游离是没人管的孩子,不在持久化上下文中。
销毁对象
一般要删除一个持久化对象的时候都是先find出来,之后调用remove方法删之,此时这个对象就是销毁对象,实际上就是瞬时对象的另一种形态罢了。
EntityManager一些常用的API
SELECT
find() 和 getReference()
Person person = em.find(Person.class,1);
Person person = em. getReference (Person.class,1);
异同:
1.当在数据库中没有找到记录时,find()方法会返回null,
而getReference() 方法会抛出javax.persistence.EntityNotFoundException异常,
2.调用getReference()方法,返回的其实并不是实例对象,而是一个代理。当你要使用实体时,才会真正的调用查询语句来查询实例对象
3.另外getReference()方法不保证 entity Bean已被初始化。
4.如果传递进getReference()或find()方法的参数不是实体Bean,都会引发 IllegalArgumentException
INSERT
persist()
将临时状态的实体持久化到数据库
Person person = new Person();
person.setName(name);
//把数据保存进数据库中