hibernate4生命周期一共有三个:分别是瞬时状态、持久化状态和游离状态,下面介绍一下这三种状态:
1、瞬时状态(Transient):
使用new操作符初始化的对象就是瞬时状态,他们没有任何和数据库表相关联的行为,只要应用不在引用这些对象(不在被其他对象所引用),他们的状态将会丢失,并由垃圾回收机制回收。
2、持久化状态(Persist):
1)持久化状态的对象是具有数据库标识的实例,由持久化管理器Session统一管理;
2)持久化状态的实例实在事务中进行操作,在事务结束时同数据库进行同步。当事务提交时,通过执行SQL的insert,update和delete语句把内存中的状态同步到数据库中。
3、游离状态(detached):
1)Session关闭之后,持久化状态的对象就变为离线状态。
2)离线状态表示,这个对象不能再与数据库保持同步,他们不再受Hibernate的Session管理器管理。
hibernate4生命周期中三种状态的转化图如下:
下面是我新建了一个hibernate项目,用来测试常见的集中状态转化以及注意的地方,都在注释中。
项目架构如图:
HibernateUtil封装了hibernate的获取Session对象和关闭的代码,代码如下:
package com.robert.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static Configuration cfg = null;
private static SessionFactory factory = null;
private static Session session = null ;
static {
init();
}
public static void init() {
cfg = new Configuration().configure();
factory = cfg.buildSessionFactory(new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build());
}
public static Session getSession() {
if (factory != null)
return factory.openSession();
init();
return factory.openSession();
}
public static void closeSession() {
if(session!=null && session.isOpen())
session.close();
}
}
HibernateTest类是测试类,测试使用的是Junit4,测试代码以及注释如下:
package com.robert.test;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.robert.pojo.User;
import com.robert.util.HibernateUtil;
public class HibernateTest {
/**
* session的save方法,保存数据 session中状态改变:瞬时-->持久-->游离
*/
@Test
public void testSave() {
Session session = null;
Transaction tx = null;
User user = null;
try {
session = HibernateUtil.getSession();
tx = session.beginTransaction();
// 构造对象--瞬时状态
user = new User();
user.setName("小明");
user.setPwd("2222");
// 持久状态,user被session管理,并且id有值--oid
session.save(user);
// 在持久化状态下:hibernate会执行脏数据检查(之前的数据成为脏数据)
// 当提交事务,或清理缓存时,发现session中数据和之前要放入数据库中数据(此时数据仍然在session中,并未真正在数据库中)不一致时,
// 将会把session中的数据更新到数据库中。
user.setName("小友");
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
throw new HibernateException(e.getCause());
} finally {
HibernateUtil.closeSession();
}
// user处于游离状态,但是在内存中仍然存在
System.out.println("name=" + user.getName());
}
/**
* session.get方法,获取数据
*/
@Test
public void testGet() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtil.getSession();
tx = session.beginTransaction();
//get后变为持久化状态,get方法查询数据的顺序为:session-->sessionFacroty-->数据库中
User user = (User) session.get(User.class, 2);
System.out.println("name=" + user.getName());
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
HibernateUtil.closeSession();
}
}
@Test
public void testGet2() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtil.getSession();
tx = session.beginTransaction();
//get后变为持久化状态,get方法查询数据的顺序为:session-->sessionFacroty-->数据库中
//get方法如果根据id找不到对象(此时数据库中并没有id=17的数据),不会抛出异常,返回null
User user = (User) session.get(User.class, 17);
System.out.println("name=" + user.getName());
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
HibernateUtil.closeSession();
}
}
/**
* load和get的区别:
* load和get都会立即查询对象,get找不到对象时,返回null,load找不到对象时,抛异常
*/
@Test
public void testLoad1() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtil.getSession();
tx = session.beginTransaction();
//load后变为持久化状态,load方法查询数据的顺序为:session-->sessionFacroty-->数据库中
//在3.x版本中,load不会立即查询对象,等到使用的时候才会查询。
// 在4.3中立即查询了对象,当对象不存在时,会抛出异常,
User user = (User) session.load(User.class, 2);
System.out.println("name=" + user.getName());
//clear和evict区别:
// clear清除session缓存中所有对象,evict清除指定对象、
session.clear();
tx.commit();
// user游离状态,不被session管理,数据库中不会被更改
user.setName("司马懿") ;
System.out.println("clear后:name="+user.getName());
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
HibernateUtil.closeSession();
}
}
/**
* delete方法:持久化状态-->瞬时状态
*/
@Test
public void testDelete() {
Session session = null;
Transaction tx = null;
User user = null ;
try {
session = HibernateUtil.getSession();
tx = session.beginTransaction();
// 手动构造一个对象,指定其主键是可以删除该对象的,但是不建议这么使用
// user = new User() ;
// user.setId(2) ;
// user.setName("李四") ;
//通过从数据库中加载该对象,然后删除,可以进行判断,进而避免异常,提高程序的健壮性
user = (User) session.get(User.class, 2) ;
if(user!=null)
session.delete(user) ;
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
HibernateUtil.closeSession();
}
}
@Test
public void testUpdate() {
Session session = null;
Transaction tx = null;
User user = null ;
try {
session = HibernateUtil.getSession();
tx = session.beginTransaction();
//手动构造的瞬时状态的对象,可以修改,但是需要指定所有的属性,不建议使用
// user = new User() ;
// user.setId(3) ;
// user.setName("李四") ;
user = (User)session.get(User.class, 2);
user.setName("后卫") ;
session.update(user);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
HibernateUtil.closeSession();
}
}
}