hibernate对象在内存中的四种状态
临时状态(transient):刚用new创建的,还没有被持久化,并且不处于Session的缓存中,处于临时状态的java对象成为临时对象。
持久化状态(persistent):已经被持久化,并且加入到了Session的缓存中,处于持久化状态的java对象成为持久化对象。
删除状态(removed):
游离状态(detached):已经被持久化,但不再处于Session的缓存中,处于游离状态的java对象成为游离对象。
举例:
tx = session.beginTransaction(); User u1 = new User("zhangsan"); | 开始生命周期 | 临时状态 |
session.save(u1); | 生命周期中 | 转变为持久化状态 |
Long id = u1.getId(); u1 = null; User u2 = (User)session.get(User.class,id); tx.commit(); | 生命周期中 | 持久化状态 |
session.close(); | 生命周期中 | 转变为游离状态 |
System.out.print(u2.getName()); | 生命周期中 | 游离状态 |
u2 = null; | 结束生命周期 | 结束生命周期 |
Session缓存的三大作用
1、减少访问数据库的频率。
2、当缓存中的持久化对象之间存在循环关联关系时,Session会保证不出现访问对象图的死循环,以及由于死循环引起的JVM堆栈溢出异常。
3、保证数据库中的相关记录与缓存中的相关对象保持同步。对象-关系映射文件建立了数据库表与持久化类的静态映射,而Session则建立了数据库表中的数据与程序运行时的Session缓存中的持久化对象的动态映射。
Session接口的具体方法
包含了save和update方法的功能,如果传入的参数是临时对象,就调用save方法,如果传入的参数是游离对象,就调用update方法,如果传入的参数是持久换对象,就直接返回。
5、merge方法
merge方法能够把一个游离对象的属性复制到一个持久化对象中。
u1.setName("zhangsan");//u1为游离对象,OID为1
User u2 = (User)session.get(User.class,new Long(1));//u2成为了持久化对象
User u3 = (User)session.merge(u1);//把游离对象u1的属性复制到持久化对象u2中,并返回User持久化对象的引用
u1 == u2;//false
u1 == u3;//false
u2 == u3;//true
处理流程:
a、merge方法根据u1游离对象的OID到Session缓存中查找匹配的持久化对象,找到了u2符合要求,就把u1游离对象的属性复制到u2持久化对象中,,计划执行一条update语句,返回u2持久化对象的引用。
b、如果在Session缓存中没有找到,那么就根据这个OID从数据库中加载User持久化对象,然后把u1游离对象的属性复制到这个刚从数据库加载的User持久化对象中,计划执行一条update语句,返回这个User持久化对象的引用。
c、如果数据库中不存在这样的User持久化对象,就会创建一个新的User对象,把u1游离对象的属性复制到这个新建的User对象中,再调用save方法持久化这个新建的对象,然后返回这个User持久化对象的引用。
d、如果u1是一个临时对象,那么也会创建一个新的User对象,把u1临时对象的属性复制到这个新建的User对象中,然后调用save方法持久化这个新建的User对象,然后返回这个User持久化对象的引用。
6、delete方法
用户从数据库中删除一个对象,既可以删除持久化对象,也可以删除游离对象。
delete方法把持久化对象或游离对象转变为被删除对象,被删除对象时无用对象,程序不应该再使用这些对象。
在Hibernate的hibernate.properties配置文件中有一个hibernate.use_identifier_rollback属性,默认值是false,如果改为true,就改变了Session的delete方法的运行时行为,这时delete方法会把持久化对象或游离对象的OID置为null,使他们变为临时对象,这样程序可以继续使用这些临时对象。
7、replicate
把一个数据库中的对象复制到另一个数据库中。不经常用,仅作了解。