首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

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

2012-09-22 
使用代理实现Hibernate Dao层自动事务都说spring利用AOP实现自动事务处理机制非常好,但在只有hibernate这

使用代理实现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{//关闭sessionif(session!=null){session.close();}}}

?

?

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

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

public class BaseDaoImpl implements BaseDao {public Session session = null;public Transaction tran = null;@Overridepublic void delete(Class clazz, Serializable id) throws Exception {// TODO Auto-generated method stubObject 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);}// 拦截关联的这个实现类的方法被调用时将被执行@Overridepublic 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();}}}

?

?

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

热点排行