Struts Spring Hibernate 事务管理的例子

Struts Spring Hibernate 事务管理的例子。
关键词: Struts Spring Hibernate 事务管理

这两天比较清闲,试着配置了一下Struts Spring Hibernate 。由Spring来接管Struts的Action和Hibernate的事务管理。现做一下笔记。

1. Struts配置文件struts-config.xml

首先加上Spring的Context Loader插件

<plug-in
className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation"
value="/WEB-INF/beans.xml" />
</plug-in>

其中beans.xml是Spring的配置文件。

添加一个Action

<action path="/sample"
type="org.springframework.web.struts.DelegatingActionProxy">
</action>
注意type变成了Spring的代理类,当然这儿可以加入一些Forward

2. Spring的配置文件 beans.xml

添加action的对应bean,由于struts已经把这个bean委托给spring来管了,所以当然应该在spring中配置对应的class

<bean name="/sample" class="com.windrift.action.SampleAction">
<property name="sampleManager" ref="sampleManager" />
</bean>

对 sampleManager的配置,实际上对应的是 com.windrift.manager.SampleManager,由于需要对这个 manager配置事务,所以给他指定了一个模板parent="baseService",注意这个parent并不是指继承关系,稍后我们会对这个模板指定事务的策略。

<bean id="sampleManager" parent="baseService">
<property name="target">
<bean class="com.windrift.manager.SampleManager" autowire="byName">
<property name="sampleDAO" ref="sampleDAO" />
</bean>
</property>
</bean>

配置sampleDAO,这里的模板baseDao我们不关心,这儿不详述。

<bean id="sampleDAO" parent="baseDao">
<property name="target">
<bean class="com.windrift.dao.imp.SampleDAOImp" autowire="byName"></bean>
</property>
</bean>

下面配置Hibernate的数据源,这儿用的是MySQL数据库,由于数据库的处理等已经交由Spring处理,因此不再需要Hibernate的配置文件。除了表和PO的映射文件外(如Sample.hbm.xml)

<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost/shop</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>root</value>
</property>
</bean>

sessionFactory依据数据源创建Session链接

<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource" />
</property>
<property name="mappingResources">
<list>
<value>SystemInfo.hbm.xml</value>
<value>Ad.hbm.xml</value>
<value>Good.hbm.xml</value>
<value>Logo.hbm.xml</value>
<value>Member.hbm.xml</value>
<value>News.hbm.xml</value>
<value>NSort.hbm.xml</value>
<value>Pub.hbm.xml</value>
<value>Sort.hbm.xml</value>
<value>Sub.hbm.xml</value>
<value>Basket.hbm.xml</value>
<value>Sample.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.connection.characterEncoding">
UTF-8
</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">
false
</prop>
<prop key="hibernate.connection.pool.size">2</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="jdbc.fetch_size">50</prop>
<prop key="jdbc.batch_size">25</prop>
<prop key="jdbc.use_scrollable_resultset">false</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
</props>
</property>
</bean>

事务管理类,通过SessionFactory来获取session
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>

配置一个切入器,它依据配置的一些事务策略,会调用 transactionManager来进行事务管理。

这个例子中需要进行事务管理的类(所有parent是baseService的类)的所有以Get开头的方法会在一个只读事务环境中运行。其余方法需要进行事务传递,并且一旦这个方法抛出BaseException异常则回滚事务。(如果希望强制commit事务,则把BaseException前面的-改成+)

<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="*">
PROPAGATION_REQUIRED,-BaseException
</prop>
</props>
</property>
</bean>

这个就是前面提到的模板,它说明所有应用此模板的类(parent=baseService的 类)都会被 置于transactionInterceptor中配置的事务环境中。

<bean id="baseService" abstract="true"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>

3. SampleAction.java

只是简单的调用了一下manager的方法

package com.windrift.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.windrift.manager.SampleManager;

public class SampleAction extends Action{
private SampleManager sampleManager;
public ActionForward execute(ActionMapping aMapping, ActionForm aForm,
HttpServletRequest aRequest, HttpServletResponse aResponse)
throws Exception {
sampleManager.doSomething();
return null;

}
public void setSampleManager(SampleManager sampleManager) {
this.sampleManager = sampleManager;
}
}

4. SampleManager.java

方法doSomething中我们往数据库里加了两个记录Sample1和Sample2

但是在最后我们强制抛出了一个BaseException,根据前面设置的事务环境和策略,这两条插入的记录都会被回滚。

package com.windrift.manager;

import com.windrift.dao.SampleDAO;
import com.windrift.dao.persist.Sample;
import com.windrift.exception.BaseException;

public class SampleManager {
private SampleDAO sampleDAO;

public void setSampleDAO(SampleDAO sampleDAO) {
this.sampleDAO = sampleDAO;
}

public void doSomething() throws BaseException{
Sample sample1 = new Sample();
sample1.setSample("sample1");
sampleDAO.addSample(sample1);
Sample sample2 = new Sample();
sample2.setSample("sample2");
sampleDAO.addSample(sample2);
throw new BaseException();
}

}

5. SampleDAOImp.java

简单的调用了父类的方法。

package com.windrift.dao.imp;

import com.windrift.dao.SampleDAO;
import com.windrift.dao.persist.Sample;

public class SampleDAOImp extends BaseDAOImp implements SampleDAO {

public void addSample(Sample sample) {
this.save(sample);
}
}

补充一个需要使用回调函数的方法。由于我们的session的管理(包括事务)都交给spring来处理了。所以通常情况下我们是无法访问session的。但是有时候我们又需要使用session,这时候就需要使用回调函数,以取得session。

public List getAllSortASC() {
return getHibernateTemplate().executeFind(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Query query = session.createQuery("from Sort order by sort_id asc");
List sorts = query.list();
return sorts;
}});}

public Sort getSortById(final int id) {
List list = getHibernateTemplate().executeFind(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Query query = session
.createQuery("from Sort where sort_ID = ?");
query.setInteger(0, id);
return query.list();
}
});
if (list != null && list.isEmpty() == false) {
return (Sort) list.get(0);
} else {
return null;
}
}

6. DAO的基类

注意由于所有dao都需要继承自HibernateDaoSupport ,所以我们在基类中做这个动作。

package com.windrift.dao.imp;

import java.io.Serializable;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.windrift.dao.BaseDAO;

public class BaseDAOImp extends HibernateDaoSupport implements BaseDAO {
/* (non-Javadoc)
* @see com.windrift.dao.imp.BaseDAO#delete(java.lang.Object)
*/
public void delete(Object o) {
getHibernateTemplate().delete(o);
}

/* (non-Javadoc)
* @see com.windrift.dao.imp.BaseDAO#flush()
*/
public void flush() {
getHibernateTemplate().flush();
}

/* (non-Javadoc)
* @see com.windrift.dao.imp.BaseDAO#get(java.lang.Class, java.io.Serializable)
*/
public Object get(Class clazz, Serializable id) {
return getHibernateTemplate().get(clazz, id);
}

/* (non-Javadoc)
* @see com.windrift.dao.imp.BaseDAO#load(java.lang.Class, java.io.Serializable)
*/
public Object load(Class clazz, Serializable id) {
return getHibernateTemplate().load(clazz, id);
}

/* (non-Javadoc)
* @see com.windrift.dao.imp.BaseDAO#refresh(java.lang.Object)
*/
public void refresh(Object o) {
getHibernateTemplate().refresh(o);
}

/* (non-Javadoc)
* @see com.windrift.dao.imp.BaseDAO#remove(java.lang.Class, java.io.Serializable)
*/
public void remove(Class clazz, Serializable id) {
getHibernateTemplate().delete(get(clazz, id));
}

/* (non-Javadoc)
* @see com.windrift.dao.imp.BaseDAO#save(java.lang.Object)
*/
public void save(Object o) {
getHibernateTemplate().save(o);
}

/* (non-Javadoc)
* @see com.windrift.dao.imp.BaseDAO#saveOrUpdate(java.lang.Object)
*/
public void saveOrUpdate(Object o) {
getHibernateTemplate().saveOrUpdate(o);
}

/* (non-Javadoc)
* @see com.windrift.dao.imp.BaseDAO#update(java.lang.Object)
*/
public void update(Object o) {
getHibernateTemplate().update(o);
}
}

自此圆满完成这个小例子。最后说一点,由于hibernate进行了一次版本更新,因此存在hibernate3和hibernate两个包(如:import org.springframework.orm.hibernate3.support.HibernateDaoSupport;)。大家一定都使用 hibernate3,不然出错比较难找。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值