Hibernate4生命周期和Session核心方法

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();
		}
	}

}
相关文章
相关标签/搜索