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

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

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

 

 

小弟初级程序员,才疏学浅,往各位指教.