一、编写Hibernate的Dao
在该封装好的类中,并没有事务的处理,事务的处理交给AOP来处理,代码如下:
package cn.com.bochy.dao;
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;
public class HibernateUntil<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 HibernateUntil() {
}
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;
}
}
二、定义一个接口
package cn.com.bochy.istu;
import java.util.List;
import cn.com.bochy.entity.Stu;
public interface IStuBiz {
public List<Stu> getAll();
public boolean save(Stu s);
public boolean update(Stu s);
public boolean delete(int id);
public Stu getStuByID(int id);
}
三、接口的实现类
在这个实现类中,也没有对事务进行处理
package cn.com.bochy.istuImpl;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import cn.com.bochy.dao.HibernateUntil;
import cn.com.bochy.entity.Stu;
import cn.com.bochy.istu.IStuBiz;
public class StuBizImpl implements IStuBiz {
HibernateUntil<Stu> util=new HibernateUntil<>();
private Session session=util.getSession();
@SuppressWarnings("unchecked")
@Override
public List<Stu> getAll() {
Query query=session.createQuery("from Stu");
return query.list();
}
@Override
public boolean save(Stu s) {
System.out.println("save a stu....");
session.save(s);
return true;
}
@Override
public boolean update(Stu s) {
session.saveOrUpdate(s);
return true;
}
@Override
public boolean delete(int id) {
Stu s=(Stu)session.get(Stu.class, id);
session.delete(s);
return true;
}
@Override
public Stu getStuByID(int id) {
Stu s=(Stu)session.get(Stu.class, id);
return s;
}
}
四、使用环绕通知管理事务
需要注意的是,以get方法开头的所有方法,属于查询方法,没有加入事务管理。
package cn.com.bochy.advices;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.hibernate.Session;
import org.hibernate.Transaction;
import cn.com.bochy.dao.HibernateUntil;
import cn.com.bochy.entity.Stu;
public class aroundAdvice implements MethodInterceptor{
HibernateUntil<Stu> util=new HibernateUntil<>();
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
Object result=null;
Transaction tx=null;
String methodName=arg0.getMethod().getName();
if(methodName.startsWith("get")){
result=arg0.proceed();//调用主业务逻辑
return result;
}
try {
Session session=util.getSession();
tx=session.beginTransaction();
System.out.println("开启事务....");
result=arg0.proceed();//调用主业务逻辑
tx.commit();
result=true;
System.out.println("事务提交");
} catch (Exception e) {
tx.rollback();
result=false;
System.out.println("事务回滚");
}
return result;
}
}
五、配置ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd" >
<beans>
<bean id="stu" class="cn.com.bochy.entity.Stu"></bean>
<bean id="stuBiz" class="cn.com.bochy.istuImpl.StuBizImpl"></bean>
<bean id="around" class="cn.com.bochy.advices.aroundAdvice"></bean>
<!-- 把横切业务逻辑织入主业务逻辑 -->
<bean id="aop" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 指定代理类和被代理类共同的接口 -->
<property name="interfaces" value="cn.com.bochy.istu.IStuBiz"></property>
<!-- 指定所有的拦截器(织入横切业务逻辑) -->
<property name="interceptorNames">
<list>
<value>around</value>
</list>
</property>
<!-- 指定横切业务逻辑在哪里执行 ,执行的目标 -->
<property name="target" >
<ref bean="stuBiz"/>
</property>
</bean>
</beans>
六、测试代码
package cn.com.bochy.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.com.bochy.entity.Stu;
import cn.com.bochy.istu.IStuBiz;
public class TestAOP {
public static void main(String[] args) {
@SuppressWarnings("resource")
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
IStuBiz biz=(IStuBiz)ac.getBean("aop");
Stu s=new Stu();
s.setName("aop5");
System.out.println(biz.save(s));
}
}
测试结果:
开启事务....
save a stu....
Hibernate:
select
stu_seq.nextval
from
dual
Hibernate:
insert
into
Stu
(name, id)
values
(?, ?)
事务提交
true