使用代理实现Hibernate Dao层自动事务
编程技术  /  houtizong 发布于 3年前   96
都说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();}}}
请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!
技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成
网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];
文章归档
文章标签
友情链接