Hibernate第03课:Session生命周期测试

本文介绍Hibernate中Session的不同状态及其转换过程,并通过JUnit进行单元测试的方法。文章详细解释了Transient、Persistent和Detached三种状态的特点及如何在测试中利用这些状态进行数据操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为SessionFactory是一个重量级对象,最好是只创建一次,所以,将SessionFactory做一个封装,先建立一个工具类把它封装起来.工具类名称设置为HibernateUtils 

package net.knight.hibernate.utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

/**
 * 从hibernate.cfg.xml获取配置文件
 * getSessionFactory():获得Session工厂
 * getSession():从SessionFactory获得Session
 * getTransaction():从Session中获得Transaction
 * closeSession():关闭Session
 */
public class HibernateUtils {

	private static SessionFactory factory;
	
	/**
	 * 建立一个static块可以写多条语句.
	 */
	static {
		try {
			Configuration cfg = new Configuration().configure();
			factory = cfg.buildSessionFactory();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static SessionFactory getSessionFactory() {
		return factory;
	}
	
	public static Session getSession() {
		return factory.openSession();
	}
	
	public static Transaction getTransaction(Session session) {
		return session.beginTransaction();
	}
	
	public static void closeSession(Session session) {
		if(session != null) {
			if(session.isOpen()){
				session.close();
			}
		}
	}
	
	
}

 
第一课中是使用的Client类来测试Hibernate_first项目,考虑到如果要测试多个类的时候测试不方便,这个改用junit单元测试工具来测试,也可以学习一下junit的使用方法.步骤如下

 

1.因为测试类最终发布的时候不会打包,所以把这个测试包文件放在项目外面是一个比较明智的选择.也便于管理.首先在项目中建立一个源码目录,目录名称我建立成test.这个目录和src目录平级.


2.在目录中建立测试类路径,我这里设置的类路径和src中的一致.是否一致都可以,没有什么要求.


3.建立测试类,因为是测试Session,所以建立成SessionTest

package net.knight.hibernate.test;

import junit.framework.TestCase;

/**
 * junit单元测试,主要对方法进行测试 
 * 1.继承TestCase方法 
 * 2.方法名称要以test开头 
 * 3.测试方法不能含有参数和返回值
 */
public class SessionTest extends TestCase {

	// 公共信息初始化可以放到这个方法里.
	@Override
	protected void setUp() throws Exception {
		super.setUp();
	}

	public void testHello() {
		System.out.println("==========SessionTest.testHello===========");

		// 断言的使用方法,前面的参数是预期值,后面的参数是实际值,如果预期值不等于实际值就失败了.
		this.assertEquals("", "");
	}

	// 需要销毁的信息放到这里,类似于C中间的析构函数.
	@Override
	protected void tearDown() throws Exception {
		super.tearDown();
	}

}

 
Session有三种状态
1.Transient,new一个对象的时候就是Transient对象,最显著的特点就是在数据库中还没有与之对应的记录.还没有纳入到Session的管理,随时可以被垃圾回收器回收.


2.Persistent,当Transient对象调用save()方法后就成了Persistent对象,这个对象在数据库中是有与之对应的记录的.它纳入的Session的管理,这个对象是不能被垃圾回收器回收的.


3.Detached,当Persistent对象调用了close()等方法的时候就是Detached对象,调用close()方法后,这个对象只是从缓存里被清除掉了,数据库中的记录是不会被清除的.所以这个对象也没有纳入到Session的管理,但是数据库中是有与之对应的记录的,这个对象也随时可以被垃圾回收处理掉.因为没有任何对象引用它了.


4.因为数据库中有与之对应的记录,所以可以调用update()等方法,当Detached对象调用该类方法时,这个对象又变成了Persistent对象了.当Persistent对象再调用delete()方法时这个对象又变成Transient对象了.
Transient--save()-->Persistent--close()-->Detached--update()-->Persistent--delete()-->Transient

 

package net.knight.hibernate.test;

import java.util.Date;

import net.knight.hibernate.User;
import net.knight.hibernate.utils.HibernateUtils;

import org.hibernate.Session;
import org.hibernate.Transaction;

import junit.framework.TestCase;

/**
 * junit单元测试
 * 1.继承TestCase方法
 * 2.方法名称要以test开头
 *
 */
public class SessionTest extends TestCase {

	public void testSession() {
		Session session = null;
		Transaction ts = null;
		User user = null;
		
		try {
			session = HibernateUtils.getSession();
			ts = HibernateUtils.getTransaction(session);
			
			// Transient状态
			user = new User();
			user.setName("李四");
			user.setPassword("123");
			user.setCreateTime(new Date());
			user.setExpireTime(new Date());
			
			// Persistent状态.当属性发生改变的时候,hibernate会自动同步数据库
			// 生成并执行insert into,此时的数据在缓存中,只是一个快照.
			session.save(user);
			
			// 修改user对象后,发生脏数据对比,对数据进行修改
			// 生成并执行update,存入数据库.清理缓存
			user.setName("王五");
			ts.commit();
		} catch (RuntimeException e) {
			e.printStackTrace();
			ts.rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
		
		// 再修改username,此时就是Detached状态
		user.setName("赵六");
		try {
			// 因为Session已经关闭,则需要重新获取
			session = HibernateUtils.getSession();
			ts = HibernateUtils.getTransaction(session);
			
			// 获取到session后又转换成Persistent
			session.update(user);
			ts.commit();
		}catch(Exception e) {
			e.printStackTrace();
			ts.rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值