Spring与Ibatis的整合
一、前言
基于ibatis的动态sql语句的配置,也是目前比较流行的orm框架。但目前,spring4.0以前的版本已经不在支持ibatis的开发。可能需要结合spring-ibatis开发包,同样mybatis-spring的包也被移出来了。spring-orm4.0的版本是支持hibernate4的开发。可以了解的是,如果spring4.0以上的版本想整合ibatis或者mybatis,则需要加载spring-ibatis和mybatis-spring的jar包。而spring3.0以上的版本是支持ibatis的,不需要加载其他包。此外,fastjson与springMVC配置使用,spring的版本需要在3.1.x及以上,fastjson不支持3.0.x的版本.
二、项目框架
本项目采用eclipse开发,使用Maven的项目构建。框架上采用SpringMVC+Spring+Ibatis。
三、配置文件
本文章重点在于spring与ibatis的整合,对于springMVC等配置,在本文中不介绍。
Maven的pom.xml的配置在项目中自行查看。
1.spring-bean的配置文件spring-one.xml
datasource的配置根据大家的需求进行配置。。。。。
<bean id="sqlMapClient"class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation"value="config/sqlMapConfig.xml" />
<propertyname="dataSource" ref="dataSource" />
</bean>
(注:ibatis的配置文件sqlMapConfig.xml下面介绍)
<beanid="ibsdbSqlMapExecutor"class="org.springframework.orm.ibatis.SqlMapClientTemplate">
<property name="dataSource"ref="dataSource" />
<propertyname="sqlMapClient" ref="sqlMapClient" />
</bean>
(注:SqlMapClientTemplate的bean的配置是为事务处理,sqlMapClient经本人测试,不提供事务的功能,只有执行sql语句的功能。)
<beanid="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="dataSource" ref="dataSource" />
</bean>
(这是事务管理器的配置)
2.这里我们需要对ibatis的事务管理进行配置,分三种方式进行配置(在执行事务的使用应当使用SqlMapClientTemplate来执行语句,SqlMapClient不支持事务)
2.1方式一
<beanname="transactionTemplate"class="org.springframework.transaction.support.TransactionTemplate">
<propertyname="transactionManager" ref="transactionManager"/>
<propertyname="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
<propertyname="isolationLevelName" value="ISOLATION_DEFAULT" />
<propertyname="readOnly" value="false" />
</bean>
(使用transactionTemplate模式)以下是java类的使用
public boolean registUser(final Useruser){
boolean result = false;
this.transactionTemplate.execute(newTransactionCallback() {
public ObjectdoInTransaction(TransactionStatus arg0) {
User u =new User();
u.setUserName("test1");
u.setPassword("123");
Object res= ibsdbSqlMapExecutor.insert("user.insertUser", user);
ibsdbSqlMapExecutor.insert("user.insertUser",u);
returnnull;
}
});
return result;
}
2.2方式二:@Transactional注解方式
开启事务注解
<tx:annotation-drivenproxy-target-class="true"/>
只要在方法中@Transactional即可
2.3方式三:aop事务配置(重点推荐)
<!--配置哪些方法,什么情况下需要回滚-->
<tx:adviceid="serviceAdvice"transaction-manager="transactionManager">
<tx:attributes>
<!--当代理的service层中的方法抛出异常的时候才回滚,必须加rollback-for参数-->
<tx:method name="insert*"propagation="REQUIRED" rollback-for="Throwable"/>
<tx:method name="del*"propagation="REQUIRED" rollback-for="Throwable"/>
<tx:method name="update*"propagation="REQUIRED" rollback-for="Throwable"/>
<!--除了上面标识的方法,其他方法全是只读方法
<tx:method name="*"read-only="true"/> -->
</tx:attributes>
</tx:advice>
<!-- 配置哪些类的方法需要进行事务管理-->
<aop:configproxy-target-class="true">
<aop:pointcutid="servicePointcut" expression="execution(*org.beadle.service..*.*(..))"/>
<aop:advisorpointcut-ref="servicePointcut" advice-ref="serviceAdvice"/>
</aop:config>
(需要配置事务的一个advice,可以用通配符设置某些方法需要事务的处理,通过aop对事务处理进行配置,可在service层进行事务的管理)
3.sqlMapConfig.xml的配置
<?xml version="1.0"encoding="UTF-8" ?>
<!DOCTYPEsqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD SQLMap Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<!-- 启动命名空间namespace-->
<settingsuseStatementNamespaces="true"/>
<!-- 使用spring之后,数据源的配置移植到了spring上,所以iBATIS本身的配置可以取消-->
<sqlMapresource="org/beadle/pojo/user/User.xml" />
</sqlMapConfig>
(暂时只配置了2个,一个启动命名空间,一个是orm映射文件的配置)
4.User.xml的配置
<?xml version="1.0"encoding="UTF-8" ?>
<!DOCTYPEsqlMap
PUBLIC "-//ibatis.apache.org//DTD SQLMap 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMapnamespace="user">
<parameterMap id="userMap"class="org.beadle.pojo.user.User" >
<parameter property="userName"javaType="java.lang.String" />
<parameter property="password"javaType="java.lang.String" />
</parameterMap>
<resultMapid="userResultMap" class="org.beadle.pojo.user.User" >
<resultproperty="userName" column="user_name"/>
<resultproperty="password" column="password"/>
</resultMap>
<select id="validateUser" parameterClass="org.beadle.pojo.user.User"resultMap="userResultMap">
SELECT
*
FROM
tb_user
WHERE
user_name =#userName# AND password = #password#
</select>
<insert id="insertUser"parameterClass="org.beadle.pojo.user.User">
INSERT INTO tb_user (
<dynamic prepend="">
<isNotEmptyproperty="userName"prepend=",">user_name</isNotEmpty>
<isNotEmptyproperty="password"prepend=",">password</isNotEmpty>
</dynamic>
<![CDATA[
) VALUES (
]]>
<dynamic prepend="">
<isNotEmptyproperty="userName"prepend=",">#userName#</isNotEmpty>
<isNotEmptyproperty="password"prepend=",">#password#</isNotEmpty>
</dynamic>
<![CDATA[
)
]]>
</insert>
</sqlMap>
值得注意的是事务的回滚是通过对异常判断,所以如果我们在Service层进行事务的处理,并且在dao层或者service层进行异常的捕获的情况下,事务将不起作用。因此,我们只能在C层进行异常的捕获并处理,在service层或者dao层只能是对执行的结果做一个判断。