1. 瞬时对象(Transient Objects):使用new操作符初始化的对象不是立刻就持久的。它们的状态是瞬时的,也就是说它们没有任何跟数据库表相关联的行为,只要应用不再引用这些对象(不再被任何其它对象所引用),它们的状态将会丢失,并由垃圾回收机制回收。
2.持久化对象(Persist Objects):持久实例是任何具有数据库标识的实例,它由持久化管理器Session统一管理,持久实例是在事务中进行操作的,它们的状态在事务结束时同数据库进行同步。当事务提交时,通过执行SQL的insert,update和delete语句把内存中的状态同步到数据库中。
3.离线/脱管对象(Detached Objects):Session关闭之后,持久化对象就变成了离线对象,离线表示这个对象不能再与数据库保持同步,它们不再受Hibernate管理。
下面用具体代码说,加深理解:
public void test1(){
Configuration config=new Configuration().configure(); //读取hibernate配置文件
SessionFactory factory=config.buildSessionFactory(); //创建session工厂
Session session=factory.openSession();
Student stu=new Student(); //瞬时对象
try {
session.beginTransaction();
stu.setName("王五");
stu.setPassword("123");
stu.setAge(20);
stu.setAddress("吉林");
stu.setBirthday(new Date());
session.save(stu); //持久化对象
session.getTransaction().commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
session.getTransaction().rollback();
}finally{
session.close(); //离线对象
}
}
一. 瞬时对象:也就是上面的代码,如果我们没有对stu对象进行数据库插入工作(session.save(stu);),那么,当程序执行完毕,stu这个对象就不存在了,我们没有任何办法找到它(会被java 的垃圾回收机制,回收)。
二. 持久化对象:(1). 处于持久化的对象一定会有数据库标识
(2). 它必须与某个hibernate Session对象绑定。
以上两点缺一不可,否则它就不持久化对象。
上述代码中,当我们session.save(stu);之后,stu就变成了持久化对象,因为此时的它被session管理,同时也拥有了数据库标识。
持久化对象的特点:处于持久化状态的对象,如果它的状态发生了变化,hibernate将自动同步到数据库,看如下代码:
public void test2(){
Configuration config=new Configuration().configure(); //读取hibernate配置文件
SessionFactory factory=config.buildSessionFactory(); //创建session工厂
Session session=factory.openSession();
Student stu=new Student(); //瞬时对象
try {
session.beginTransaction();
stu.setName("王五");
stu.setPassword("123");
stu.setAge(20);
stu.setAddress("吉林");
stu.setBirthday(new Date());
session.save(stu); //持久化对象
stu.setName("王五一"); //当持久化对象的状态发生改变时,hibernate会将改变后的状态自动同步到数据库
session.getTransaction().commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
session.getTransaction().rollback();
}finally{
session.close(); //离线对象
}
}
上面代码运行后的结果:
ID | NAME | PASSWORD | AGE | ADDRESS | BIRTHDAY |
237511 | 王五一 | 123 | 20 | 吉林 | 17-8月 -11 02.01.27.421000 下午 |
三. 离线对象:持久化对象脱离了hibernate Session的管理,或者,一个对象只数据库标识。
自动同步,当离线对象的状态发生变化时,hibernate不会自动同步到数据库,因为它脱离了hibernate Session,hibernate自然也不会检测到它的状态变化。
如下代码:
public void test3(){
Configuration config=new Configuration().configure(); //读取hibernate配置文件
SessionFactory factory=config.buildSessionFactory(); //创建session工厂
Session session=factory.openSession();
Student stu=new Student(); //瞬时对象
try {
session.beginTransaction();
stu.setName("王五");
stu.setPassword("123");
stu.setAge(20);
stu.setAddress("吉林");
stu.setBirthday(new Date());
session.save(stu); //持久化对象
session.getTransaction().commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
session.getTransaction().rollback();
}finally{
session.close(); //离线对象
stu.setName("王五一"); //由于此时,stu处离线状态,当它的状态发生变化时,hibernate不会自动同步。
}
}
上面代码运行后的结果:
ID | NAME | PASSWORD | AGE | ADDRESS | BIRTHDAY |
237511 | 王五 | 123 | 20 | 吉林 | 17-8月 -11 02.01.27.421000 下午 |
当对象处于离线状态时,我们怎样让它变成持久化状态呢,很简单,如下代码:
public void test4(){
Configuration config=new Configuration().configure();
SessionFactory factory=config.buildSessionFactory();
Session session=null;
Student stu = null;
try {
session=factory.openSession();
stu=(Student)session.get(Student.class, 237511); //通过get方法得到stu对象
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
session.getTransaction().rollback();
}finally{
session.close();
//此时的stu为离线状态
}
try {
session=factory.openSession();
session.beginTransaction(); //开启事务
session.update(stu); //把stu从离线状态,变为持久化状态
stu.setName("王五二");
session.getTransaction().commit(); //提交事务
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
session.getTransaction().rollback();
}finally{
session.close();
}
}
上面代码运行后的结果:
ID | NAME | PASSWORD | AGE | ADDRESS | BIRTHDAY |
237511 | 王五二 | 123 | 20 | 吉林 | 17-8月 -11 02.01.27.421000 下午 |
思考:你可能会发现,stu.setName("王五二"); 在 session.update(stu); 之后,但数据确实是同步到数据库了,这就是我们上面所说的持久化对象的状态发生变化时,hibernate会自动将它同步到数据库。其实这里的update方法并不是发出upate语句,而是将stu从离线状态,变成持久化状态。