Hibernate 事务统一管理

这里是利用 cglib 的代理功能实现业务类的统一事务管理,以达到在业务类的每个方法上自动开启与关闭事务,而免区在每个业务方法里写事务代码的烦恼。且业务类既可以实现接口使代理返回接口,或不实现接口使代理返回对象。

 

在这里用到了 Hibernate 的 getCurrentSession() ,因此需要在 hibernate.cfg.xml 里加上下面这句,仅示例:

 

<property name="hibernate.current_session_context_class">thread</property>

 

实体 Student 定义如下:

 

public class Student {	
	private Integer id;
	private String name;
	private String phone;
        // 。。。。
}

 

hibernate.cfg.xml 如下:

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory> 
        <property name="show_sql">true</property>    
        <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property> 
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>    
        <property name="connection.url"> 
            jdbc:mysql://localhost:3306/tthibernate?useUnicode=true&amp;characterEncoding=utf8
        </property>
        <property name="connection.username">root</property> 
        <property name="connection.password">sa</property>        
        <property name="hibernate.current_session_context_class">thread</property>
		 <mapping resource="test1/vo/Student.hbm.xml"/>  
     </session-factory> 
</hibernate-configuration>

 

获取 hibernate factory 的工具类:

 

public class HibernateUtil {
	
	private static SessionFactory sessionFactory;
	
	static{
		sessionFactory = new Configuration().configure().buildSessionFactory();
	}
	
	public static SessionFactory getSessionFactory(){
		if(sessionFactory==null){
			Configuration conf = new Configuration().configure();
			sessionFactory = conf.buildSessionFactory();
		}
		return sessionFactory;
	}
}

 

动态添加事务的拦截器:

 

public class TransctionInterceptor implements MethodInterceptor {
	
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy mp) throws Throwable {
		// TODO Auto-generated method stub
		
		SessionFactory sf = HibernateUtil.getSessionFactory();
		Session ss = sf.getCurrentSession();
		Transaction ts = ss.beginTransaction();
		Object rObj = null;
		try{
			rObj = mp.invokeSuper(obj, args);
			ts.commit();
		}
		catch(Exception e){
			e.printStackTrace();
			ts.rollback();
		}
		
		return rObj;
	}
}

 

实现业务类代理的类:

 

public class HibernateBusiness {

	// 返回需要业务代理对象
	public static Object getBusiness(Class clazz){		
		Enhancer eh = new Enhancer();
		eh.setSuperclass(clazz);
		eh.setCallback(new TransctionInterceptor());
		return eh.create();		
	}
}

 

数据库操作层:

public class StudentDao {
	
	private SessionFactory sf;
	
	public StudentDao(){
		sf = HibernateUtil.getSessionFactory();
	}
	
	public void insertRightStudent()throws Exception{
		Student stu = new Student();
		stu.setName("b");
		stu.setPhone("22");		
		try {
			Session ss = sf.getCurrentSession();
			ss.save(stu);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new Exception("exception 1");
		}
	}
	
	public void insertErrorStudent()throws Exception{
		Student stu = new Student();
		stu.setName("a");
		stu.setPhone("11");
		Session ss = sf.getCurrentSession();
		try {
			// 前提数据库中不存在 id 为 99 的学生,这样下面语句会报错,从而达到事务回滚
			Student stus = (Student)ss.load(Student.class, new Integer(99));
			stus.getName();
			// 数据为插入
			ss.save(stu);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			throw new Exception("exception 2");
		}
	}
}

 

业务接口与实现,在这里也可以不实现该接口,以避免每个业务类都需要继承接口:

 

public interface StudentBusinessIf {
	public void testRightStudent()throws Exception;	
	public void testErrorStudent()throws Exception;
}

public class StudentBusiness implements StudentBusinessIf{
	
	private StudentDao studao;
	
	public StudentBusiness(){
		studao = new StudentDao();
	}
	
	public void testRightStudent()throws Exception{
		// 将成功插入数据
		studao.insertRightStudent();
	}

	public void testErrorStudent()throws Exception{
		// 插入数据将失败
		studao.insertErrorStudent();
	}
}

 

最后是测试类,实际中可为action 等:

 

public class StudentAction {
	
	public static void main(String[] args){
		// TODO Auto-generated method stub
		/*
		 * 下面两种代理均可
		 */
		// 得到业务代理对象,接口代理, 
		StudentBusinessIf sb = (StudentBusinessIf)HibernateBusiness.getBusiness(StudentBusiness.class);
		
		// 得到业务代理对象, 实际对象代理
		//StudentBusiness sb = (StudentBusiness)HibernateBusiness.getBusiness(StudentBusiness.class);
		
		try {
			// 正确插入数据测试
			sb.testRightStudent();
			// 错误插入数据测试
			sb.testErrorStudent();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
}

 

这样就完成了统一事务管理的整个过程,所以如果想让自己的业务类或其他类的方法具有事务自动开启与关闭功能,只需要象下面这样返回代理即可:

 

// 得到业务代理对象,接口代理, 用于实现接口的业务类等
		StudentBusinessIf sb = (StudentBusinessIf)HibernateBusiness.getBusiness(StudentBusiness.class);
// 或是下面这样		
		 // 得到业务代理对象, 实际对象代理,用于未实现接口的业务类等
		StudentBusiness sb = (StudentBusiness)HibernateBusiness.getBusiness(StudentBusiness.class);
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值