当前位置:首页 > 开发 > 编程语言 > Hibernate > 正文

使用代理实现Hibernate Dao层自动事务

发表于: 2010-11-06   作者:白糖_   来源:转载   浏览:
摘要: 都说spring利用AOP实现自动事务处理机制非常好,但在只有hibernate这个框架情况下,我们开启session、管理事务就往往很麻烦。 public void save(Object obj){ Session session = this.getSession(); Transaction tran = session.beginTransaction(); try

都说spring利用AOP实现自动事务处理机制非常好,但在只有hibernate这个框架情况下,我们开启session、管理事务就往往很麻烦。

public void save(Object obj){
		Session session = this.getSession();
		Transaction tran = session.beginTransaction();
		try {
			session.save(obj);
			tran.commit();
		} catch (Exception e) {
			//事务回滚
			if(tran.isActive()){
				tran.rollback();
			}
		}finally{
			//关闭session
			if(session!=null){
				session.close();
			}
		}
	}

 

 

最近也刚学会动态代理和反射,我就在想,是否可以用代理+反射实现session自动创建销毁,事务自动提交。

BaseDaoImpl需要有两个公共变量session和transaction,每个方法体里只需要写CRUD代码即可:

public class BaseDaoImpl implements BaseDao {
	public Session session = null;
	public Transaction tran = null;

	@Override
	public void delete(Class clazz, Serializable id) throws Exception {
		// TODO Auto-generated method stub
		Object obj = session.load(clazz, id);
		session.delete(obj);
	}
}

 

最后看最重要的部分,实现session和transaction的动态代理类:

package com.bless.hibernatedemo.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

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

public class DaoProxy implements InvocationHandler {

	private Object obj;

	// 绑定关系,也就是关联到哪个接口(与具体的实现类绑定)的哪些方法将被调用时,执行invoke方法。
	// Proxy.newProxyInstance的第三个参数是表明这些被拦截的方法执行时需要执行哪个InvocationHandler的invoke方法
	public Object bindRelation(Object obj) {
		this.obj = obj;
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
				.getClass().getInterfaces(), this);
	}

	// 拦截关联的这个实现类的方法被调用时将被执行
	@Override
	public Object invoke(Object arg0, Method arg1, Object[] arg2)
			throws Throwable {
		Class clazz = obj.getClass();

		// 反射获取session和tran两个属性对象
		Field fSession = clazz.getField("session");
		Field fTran = clazz.getField("tran");

		Session session = HibernateUtils.currentSession();
		// 给Dao中的session赋值
		fSession.set(obj, session);
		// 然后通过session打开事务
		Transaction tran = session.beginTransaction();
		// 再将事务对象set到对象中
		fTran.set(obj, tran);
		
		try {
			// 哇咔咔,执行dao方法
			Object result = arg1.invoke(obj, arg2);
			// 当然事务是要提交滴
			tran.commit();

			return result;
		} catch (Exception e) {
			// 发生异常,事务回滚
			if (tran.isActive()) {
				tran.rollback();
			}
			throw e;
		} finally {
			// session关闭操作
			if (session != null) {
				HibernateUtils.colseSession();
			}
		}
	}
}

 

 

最后测试一下:

public class HibernateTest extends TestCase {
	public void testSave(){
		BaseDaoImpl baseDaoImpl = new BaseDaoImpl();
		DaoProxy proxy = new DaoProxy();
		BaseDao baseDao = (BaseDao) proxy.bindRelation(baseDaoImpl);
		
		try {
			//删除User表中id为1的字段
			baseDao.delete(User.class,1);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

 

使用代理实现Hibernate Dao层自动事务

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
环境搭建成功后就进入了Hibernate的dao层的修改,将之前的使用MySQL的dao层修改成使用hibernate的da
package com.mallnav.platform.dao; import java.io.Serializable; import java.math.BigDecimal; i
上一篇用线程实现的自动办理,这一篇用SQL Server代理中的作业来实现。 数据库版本:MS SQL Server2
DefaultAdvisorAutoProxyCreator这个类功能更为强大,这个类的奇妙之处是他实现了BeanProcessor接口
DAO数据库操作类实现在配置文件中的工厂化管理 一、搭建 Hibernate 环境 二、创建数据库操作接口
1、事务的定义 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元。 事务由事
1、事务的定义 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元。 事务由事
Spring 的测试框架为我们提供一个强大的测试环境,解决日常单元测试中遇到的大部分测试难题:如运行
Spring 的测试框架为我们提供一个强大的测试环境,解决日常单元测试中遇到的大部分测试难题:如运行
引述 :Spring 的测试框架为我们提供一个强大的测试环境,解决日常单元测试中遇到的大部分测试难题
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号