映射文件(hbm)合理的存在的前提就是“有与之对应的实体的存在”——业务实体。
今天这篇博客就来说说实体到数据库的过程,这是一个从代码到数据的持久化过程,就是hibernate实现ORM持久化的生命周期。
一、持久化对象生命周期
下图是hibernate持久化的一个状态图,从图中可以看出,ORM这个过程经历了三个状态:transient,Persistent,Detached。
首先来理解一下 实体对象的三种状态:Transient object ,persist object,detached object包含的信息:
1、Transient Object(临时对象):很明显图中,在起点位置:我们New 了一个对象,进入了Transient 状态。也就是说:使用new 操作符初始化的对象不是立即就持久化的,它们的状态是瞬时的,它们没有任何跟数据库表相关的行为,那么只要程序不再调用这些对象,它们的状态就会丢失,并且由垃圾回收机制回收。
代码示例:
<span style="font-family:KaiTi_GB2312;font-size:18px;">//创建一个瞬态对象
User user = new User();
user.setName(userName);
user.setPassword("test");
//user仍是一个瞬态对象</span>
2、Persist Object(持久化对象):持久实例是任何具有数据库标识的实例。它被持久化管理器session统一管理,持久实例是在事务中进行操作的————它们的状态在事务结束时同数据库进行同步,当事务提交时,通过执行SQL的insert,update,和delete语句把内存中的状态同步到数据库中。
代码实例:
//创建一个瞬态对象
User user = new User();
user.setName(userName);
user.setPassword("test");
//user仍是一个瞬态对象
Session session = sessionFactory.openSession();
Tansaction tx = session.beginTansaction();
//此时user仍是一个瞬态对象
session.save(user);
//此时user已变为持久态
3、Detached Object(离线对象):session关闭之后,持久化对象就变为离线对象,离线表示这个对象不能再与数据库保持同步,不再受hibernate的管理。
代码示例:
<span style="font-family:KaiTi_GB2312;font-size:18px;">//创建一个瞬态对象
User user = new User();
user.setName(userName);
user.setPassword("test");
//user仍是一个瞬态对象
Session session = sessionFactory.openSession();
Tansaction tx = session.beginTansaction();
//此时user仍是一个瞬态对象
session.save(user);
//此时user已变为持久态
tx.commit();
session.close(); // clear() evict() 3种变游离态
user对象已经变成游离态</span>
注意:ORM的过程中,区分三态的标志就是“是否被Session”管理。
Transient ,detached的状态都不被session管理,只有persistent被session管理,注意这里的session是hibernate的session,不是http中用户会话的session。实体对象处于Hibernate框架所管理的状态,也就是说这个实体对象与session对象的实例相关,对这个实体所做的任何变更操作都将被Hibernate持久化到数据库层。
通过这个表格来说明三种状态的区别:
二、hibernate三态之间的相互转换
还是这副图,大家看看图中的箭头,三种状态之间是可以相互转换的。
图中,三态之间的转换有两种:
1、进入session,蓝色的箭头,被session管理。
三个口:transient ,detached,transient之前。
操作方法:修改:save ,saveorupdate ,lock;这样不论是在transient,还是detached都可以转换成 persistent状态。
查询:get,load,find,iterator()。
2、出session,红色箭头不被session管理。
一个口:persistent 。
方法:evict,close,clear,delete。
三、persistent 特殊说明
1、直接调用到persistent。
以上说明中,有一个特例就是:查询:get,load,find,iterator()。所以hibernate的三态生命周期不包含查询性质的操作,图中明显可以看到查询语句从是可以从程序中,直接调用到persistent的。查询只跟persistent相关。
从一个实例中来说明:
Session session = sessionFactory.openSession();
Tansaction tx = session.beginTansaction();
User user = (User) session.load(User.class,"key"); ------相当于hql 从DB读出来的 当然是持久态
//user对象已是持久太对象
tx.commit();
session.close();
2、在persistent自动更新
第一点说的是直接调到persistent,这里说的是通过transitent,进入persistent后,进行的自动更新。看代码如下:
//创建一个瞬态对象
User user = new User();
user.setName(userName);
user.setPassword("test");
//user仍是一个瞬态对象
Session session = sessionFactory.openSession();
Tansaction tx = session.beginTansaction();
//此时user仍是一个瞬态对象
session.save(user);
//此时user已变为持久态
tx.commit();
//persistent自动更新代码
Tansaction tx2 = session.beginTansaction();
user.setPassword("pdw");
tx2.commit();
//虽然在这个事物中并没有调用session的save()方法来保存user对象,但是usr处于持久太,
//所以对user对象所做的任何修改都持久化到数据库中 ---------持久态自动更新
//那么数据库中的密码也变成了pdw
session.close();
当user进入persistent后,我们可以直接对其进行set操作,因为本来就处在persistent,所以不用通过“save"或者“saveorupdate"来再次进入persistent。这就好比,我们买了游乐园的通票去游玩,只要进去了,就可以玩每个项目,不用每玩一个项目再出去买票了。
这就是操作hibernate对象持久化到数据库的一个流程,三个状态,一个生命周期,状态之间的相互转换,他们都是遵循一定的“事物发展规律”。
本篇博客只是粗显地介绍了基础,是我们开发必须要知道了解的用户手册的一部分。当然还有API,详细的记录了hibernate包含的方法,特性,这里就不在一一介绍,这些仅仅是入门,上手,还是需要多多的练习。