JDK动态代理结合ThreadLocal实现Hibernate的事务管理

一、简单介绍ThreadLocal
   ThreadLocal不是为了解决多线程访问共享变量,而是为每个线程创建一个单独的变量副本,提供了保持对象的方法和避免参数传递的复杂性。官方定义如下:
   This class provides thread-local variables. These variables differ from their normal counterparts in hat each thread that accesses one (via its {@code get} or {@code set} method) has its own, independently initialized copy of the variable.  {@code ThreadLocal} instances are typically private static fields in classes that wish to associate state with a thread (e.g.,a user ID or Transaction ID).大体翻译如下:
ThreadLocal类用来提供线程内部的局部变量。这些变量在多线程环境下访问(通过get或set方法访问)时能保证各个线程里的变量相对独立于其他线程内的变量,ThreadLocal实例通常来说都是private static类型。
ThreadLocal类的基本方法: 
(1) void set(Object value)设置当前线程的线程局部变量的值。 
(2) public Object get()该方法返回当前线程所对应的线程局部变量。 
(3) public void remove()将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。
需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。
(4) protected Object initialValue()返回该线程局部变量的初始值。
二、Hibernate的事务处理
  在Hibernate中,如果使用openSession()方法获取的session,每次创建的session都是不一样的,为了保证线程从创建Session到业务的彻底完成之前,自始至终都是同一个session,可以把session对象保存到ThreadLocal中。使用该方法openSession()在查询时,可以使用事务管理,也可以不使用事务管理,但是在添加、删除、修改时,必须使用事务管理,代码类似如下:
public List<T> getList(String hql){
Session session = getSession() ;
Transaction tx=session.beginTransaction();
 Query query=session.createQuery(hql);
    List<T> lis=null;
try {
lis = query.list();
tx.commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
tx.rollback();;
}
      
return lis;  
 } 
 public boolean Save(T obj){
 Session session = getSession() ;
 Transaction tx=session.beginTransaction();
 boolean mark=true;
 try {
session.save(obj);
tx.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
mark=false;
e.printStackTrace();
tx.rollback();
}  
return mark;  
 }
 
 public boolean update(T obj){
 Session session = getSession() ;
 Transaction tx=session.beginTransaction();
 boolean mark=true;
 try {
session.saveOrUpdate(obj);
tx.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
mark=false;
e.printStackTrace();
tx.rollback();
}  
return mark;  
 }
 @SuppressWarnings("unchecked")
 public T getObjectById(int id,Class<T> c){
 Session session = getSession() ;
 Transaction tx=session.beginTransaction();
T obj=null;
try {
obj = (T) session.get(c, id);
tx.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
tx.rollback();
}
return obj ;  
 }
 public boolean delete(T obj){
 Session session = getSession() ;
 Transaction tx=session.beginTransaction();
 boolean mark=true;
 try {
session.delete(obj);
tx.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
mark=false;
e.printStackTrace();
tx.rollback();
}  
return mark;  
 }
三、使用JDK动态代理实现Hibernate的事务管理
    需要注意的是,只有是同一个Session对象,事务管理才是有效的,这也说明,为什么在本例中,使用ThreadLocal来装载Session对象。
  3.1 先定义一个接口
  package cn.com.bochy.iuntil;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.cfg.Configuration;
public interface IHibernate<T> {
public void rebuildSessionFactory() ;
   public void closeSession() throws HibernateException ;
public  org.hibernate.SessionFactory getSessionFactory() ;
public  Configuration getConfiguration() ;
public List<T> getList(String hql);
public boolean Save(T obj);  
public boolean update(T obj);
public T getObjectById(int id,Class<T> c);
public boolean delete(T obj);  
public List<T> Page(String hql,int pageIndex,int pageSize);
}
这个接口就是说明代理类和被代理类之间共同的“任务”,是他们之间规范和协议。
3.2 接口的实现类
  package cn.com.bochy.until;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import cn.com.bochy.iuntil.IHibernate;
public class HibernateUtilImpl<T> implements IHibernate<T> {
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
    private static org.hibernate.SessionFactory sessionFactory;
    private static Configuration configuration = new Configuration();
    private static ServiceRegistry serviceRegistry; 
static {
    try {
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder().applySettings


(configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
    }
    public  HibernateUtilImpl() {
   
    }

    public  Session getSession() throws HibernateException {
        Session session =  threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession()
: null;
threadLocal.set(session);
}
        return session;
    }
public void rebuildSessionFactory() {
try {
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder().applySettings


(configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
    public void closeSession() throws HibernateException {
        Session session = getSession() ;
        threadLocal.set(null);


        if (session != null) {
            session.close();
        }
    }
public org.hibernate.SessionFactory getSessionFactory() {
return sessionFactory;
}
public Configuration getConfiguration() {
return configuration;
}
@SuppressWarnings("unchecked")
public List<T> getList(String hql){
Session session = getSession() ;
 Query query=session.createQuery(hql);
    List<T> lis=null;
lis = query.list();
return lis;  
 } 
 public boolean Save(T obj){
 Session session = getSession() ;
 
 boolean mark=true;  
try {
session.save(obj);

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
mark=false;
}
return mark;  
 }
 
 public boolean update(T obj){
 Session session = getSession() ; 
 boolean mark=true;
 try {
session.saveOrUpdate(obj);
} catch (Exception e) {
// TODO Auto-generated catch block
mark=false;
e.printStackTrace();
}  
return mark;  
 }
 @SuppressWarnings("unchecked")
 public T getObjectById(int id,Class<T> c){
 Session session = getSession() ;
T obj=null;
try {
obj = (T) session.get(c, id);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();

}
return obj ;  
 }
 public boolean delete(T obj){
 Session session = getSession() ;
 boolean mark=true;
 try {
session.delete(obj);

} catch (Exception e) {
// TODO Auto-generated catch block
mark=false;
e.printStackTrace();
}  
return mark;  
 }
 /**
  * 分页
  */
 @SuppressWarnings("unchecked")
 public List<T> Page(String hql,int pageIndex,int pageSize){
 Session session = getSession() ;  
List<T> lis=null;
try {
Query query=session.createQuery(hql);
 query.setFirstResult((pageIndex-1)*pageSize);
 query.setMaxResults(pageSize);
 lis = query.list();  
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}  
return lis;  
 } 
}
在这个类中,封装了Hibernate的DAO中最常见的业务:查询、修改、添加、删除、分页等,但是在这个封装类中没有用到事务处理。
3.3 定义代理类相关的处理类
package cn.com.bochy.hander;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.hibernate.Session;
import org.hibernate.Transaction;
import cn.com.bochy.until.HibernateUtilImpl;
//与代理类相关的处理类
public class Hander implements InvocationHandler{
private HibernateUtilImpl<?> Util;//被代理类对象
public Hander(HibernateUtilImpl<?> o){
this.Util=o;//通过构造方法给被代理对象赋值
}
@Override
//Object proxy:代理对象
//Method method:被代理对象的主业务逻辑的方法
//Object[] args:上述方法的参数
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Session session = Util.getSession(); 
 Transaction tx=session.beginTransaction();  
 Object o1=null;
 try {
  o1=method.invoke(Util, args);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
}   
return o1;
}
//得到代理对象
public Object getProxy(){
//ClassLoader loader:类加载器
//Class<?>[] interfaces:代理类的实现接口 
//InvocationHandler h:与代理对象相关的处理对象 
//生成一个被代理对象object的代理对象
return Proxy.newProxyInstance(Util.getClass().getClassLoader(), 
Util.getClass().getInterfaces(), this);
}
}
在这个处理类中,统一对Hibernate的DAO中最常见的业务的进行了事务处理。
3.4 测试
package cn.com.bochy.test;
import cn.com.bochy.entity.Stu;
import cn.com.bochy.hander.Hander;
import cn.com.bochy.iuntil.IHibernate;
import cn.com.bochy.until.HibernateUtilImpl;
public class TestProxy {
     public static void main(String[] args) {
Hander hander=new Hander(new HibernateUtilImpl<Stu>());
Object proxy=hander.getProxy();
   @SuppressWarnings("unchecked")
IHibernate<Stu> s=(IHibernate<Stu>)proxy;    
   System.out.println(s.getList("from Stu").size());
     Stu s1=new Stu();
     s1.setName("chen2");
      s.Save(s1);
}
}
如果学生s1已经存入数据库,则说明事务管理有效。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值