hibernate有三种状态,分别为:
Transient(瞬时状态),Persistent(持久化状态),Detached(游离状态)
下图展示了对象在hibernate中的状态转换:
例一
@Test
public void Test12() {
Configuration cfg = new Configuration().configure();//获取配置
SessionFactory sessionFactory = cfg.buildSessionFactory();//创建会话工厂
Session session = sessionFactory.openSession();//开启会话
Transaction transaction = session.beginTransaction();//开启事务
Dept dept = new Dept(0, "gz", "123");//对象刚被new出来,瞬时状态
try {
session.save(dept);//经过save方法转换为持久状态
SessionDao.transaction.commit();//提交事务,转换为游离状态
}catch(Exception e) {
e.printStackTrace();
SessionDao.transaction.rollback();//事务异常则回滚
}finally{//关闭资源
session.close();
sessionFactory.close();
}
}
执行结果:
Hibernate:
insert
into
dept
(dname, loc, deptno)
values
(?, ?, ?)
可以看见hibernate提交了一条插入语句
例二:
Dept dept = new Dept(60, "gz", "123");//对象刚被new出来,瞬时状态
try {
session.save(dept);//经过save方法转换为持久状态
dept.setDname("gz1");//先比较dept是否改变,如果有,自动将dname save到持久对象中
transaction.commit();//提交事务,转换为游离状态
dept.setDname("gz2");
session.save(dept);//没有提交,无效语句
}
执行结果:
Hibernate:
insert
into
dept
(dname, loc, deptno)
values
(?, ?, ?)
Hibernate:
update
dept
set
dname=?,
loc=?
where
deptno=?
hibernate先插入再更新gz1
可以看到无效语句并没有被提交。
如果一个对象以及是持久化状态了,那么此时对该对象进行各种修改,或者调用多次update、save方法时,hibernate都不会发送sql语句,只有当事物提交的时候,此时hibernate才会拿当前这个对象与之前保存在session中的持久化对象进行比较,如果不相同就发送一条update的sql语句,否则就不会发送update语句
例三:
Dept dept = new Dept(60, "gz", "123");//对象刚被new出来,瞬时状态
try {
session.save(dept);//经过save方法转换为持久状态
dept.setDname("gz1");
session.save(dept);
dept.setDname("gz2");
session.save(dept);
transaction.commit();//提交事务,转换为游离状态
}
这次又将提交几条sql呢?
答案是:1(第一次save)+1(commit次数)
当session调用load、get方法时,此时如果数据库中有该对象,则该对象也变成了一个持久化对象,被session所托管。
但是无论dept怎么千变万化,若dept无数据改变,session毫无反应,若有,改变的都只是session(持久化)中的dept,只有事务的commit才会先比较再发送update sql。