spring整合mybatis的事務管理
阿新 • • 發佈:2019-01-30
<pre name="code" class="html"><?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.yihaomen.mybatis.inter.UserMapper"> <select id="selectUserByID" parameterType="int" resultType="User"> select * from `user` where id = #{id} </select> <!-- 為了返回list 型別而定義的returnMap --> <resultMap type="User" id="resultListUser"> <id column="id" property="id" /> <result column="userName" property="userName" /> <result column="userAge" property="userAge" /> <result column="userAddress" property="userAddress" /> </resultMap> <!-- 返回list 的select 語句,注意 resultMap 的值是指向前面定義好的 --> <select id="selectUsers" parameterType="string" resultMap="resultListUser"> select * from user where userName like #{userName} </select> <!-- User 聯合文章進行查詢 方法之一的配置 (多對一的方式) --> <resultMap id="resultUserArticleList" type="Article"> <id property="id" column="aid" /> <result property="title" column="title" /> <result property="content" column="content" /> <association property="user" javaType="User"> <id property="id" column="id" /> <result property="userName" column="userName" /> <result property="userAddress" column="userAddress" /> </association> </resultMap> <!-- User 聯合文章進行查詢 方法之二的配置 (多對一的方式) --> <resultMap id="resultUserArticleList-2" type="Article"> <id property="id" column="aid" /> <result property="title" column="title" /> <result property="content" column="content" /> <association property="user" javaType="User" resultMap="resultListUser" /> </resultMap> <select id="getUserArticles" parameterType="int" resultMap="resultUserArticleList"> select user.id,user.userName,user.userAddress,article.id aid,article.title,article.content from user,article where user.id=article.userid and user.id=#{id} </select> <!--執行增加操作的SQL語句。id和parameterType 分別與IUserOperation介面中的addUser方法的名字和 引數型別一致。以#{name}的形式引用Student引數 的name屬性,MyBatis將使用反射讀取Student引數 的此屬性。#{name}中name大小寫敏感。引用其他 的gender等屬性與此一致。seGeneratedKeys設定 為"true"表明要MyBatis獲取由資料庫自動生成的主 鍵;keyProperty="id"指定把獲取到的主鍵值注入 到Student的id屬性--> <insert id="addUser" parameterType="User" useGeneratedKeys="true" keyProperty="id"> insert into user(userName,userAge,userAddress) values(#{userName},#{userAge},#{userAddress}) </insert> <update id="updateUser" parameterType="User" > update user set userName=#{userName},userAge=#{userAge},userAddress=#{userAddress} where id=#{id} </update> <delete id="deleteUser" parameterType="int"> delete from user where id=#{id} </delete> </mapper>
整體的spring配置檔案,application.xml如下:
<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd" default-autowire="byName" default-lazy-init="false"> <!--本示例採用DBCP連線池,應預先把DBCP的jar包複製到工程的lib目錄下。 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8" /> <property name="username" value="root" /> <property name="password" value="123456" /> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--dataSource屬性指定要用到的連線池 --> <property name="dataSource" ref="dataSource" /> <!--configLocation屬性指定mybatis的核心配置檔案 --> <property name="configLocation" value="config/Configuration.xml" /> </bean> <!-- 開啟註解配置 --> <context:annotation-config /> <context:component-scan base-package="com.yihaomen.test" /> <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.yihaomen.mybatis.inter" /> </bean> --> <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <!--sqlSessionFactory屬性指定要用到的SqlSessionFactory例項--> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> <!--mapperInterface屬性指定對映器介面,用於實現此介面並生成對映器物件--> <property name="mapperInterface" value="com.yihaomen.mybatis.inter.UserMapper" /> </bean> <!-- 使用annotation定義事務 --> <tx:annotation-driven proxy-target-class="true"/> </beans>
首先,配置資料來源dataSource。這裡採用dbpc連線池來管理資料來源
然後配置sqlSessionFactory,sql會話工廠需要注入資料來源、mybatis的配置xml檔案
下面是mybatis的配置檔案,Configuration.xml
這個檔案裡主要聲明瞭兩個對映表的實體類和一個mapper資原始檔的位置。<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <typeAliases> <typeAlias alias="User" type="com.yihaomen.mybatis.model.User"/> <typeAlias alias="Article" type="com.yihaomen.mybatis.model.Article"/> </typeAliases> <!-- 與spring 整合之後,這些可以完全刪除,資料庫連線的管理交給 spring 去管理 --> <!-- <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=utf8" /> <property name="username" value="root"/> <property name="password" value="password"/> </dataSource> </environment> </environments> --> <mappers> <mapper resource="com/yihaomen/mybatis/model/User.xml"/> </mappers> </configuration>
我們在配置檔案裡給這兩個實體類分別起了別名,那麼在後續的返回值型別上我們就可以直接引用別名了,而不是寫包名.類名。
這個mapper資原始檔中定義了sql語句,以及名稱空間。
下面是mapper檔案:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yihaomen.mybatis.inter.UserMapper">
<select id="selectUserByID" parameterType="int" resultType="User">
select * from `user` where id = #{id}
</select>
<!-- 為了返回list 型別而定義的returnMap -->
<resultMap type="User" id="resultListUser">
<id column="id" property="id" />
<result column="userName" property="userName" />
<result column="userAge" property="userAge" />
<result column="userAddress" property="userAddress" />
</resultMap>
<!-- 返回list 的select 語句,注意 resultMap 的值是指向前面定義好的 -->
<select id="selectUsers" parameterType="string" resultMap="resultListUser">
select * from user where userName like #{userName}
</select>
<!-- User 聯合文章進行查詢 方法之一的配置 (多對一的方式) -->
<resultMap id="resultUserArticleList" type="Article">
<id property="id" column="aid" />
<result property="title" column="title" />
<result property="content" column="content" />
<association property="user" javaType="User">
<id property="id" column="id" />
<result property="userName" column="userName" />
<result property="userAddress" column="userAddress" />
</association>
</resultMap>
<!-- User 聯合文章進行查詢 方法之二的配置 (多對一的方式) -->
<resultMap id="resultUserArticleList-2" type="Article">
<id property="id" column="aid" />
<result property="title" column="title" />
<result property="content" column="content" />
<association property="user" javaType="User" resultMap="resultListUser" />
</resultMap>
<select id="getUserArticles" parameterType="int" resultMap="resultUserArticleList">
select user.id,user.userName,user.userAddress,article.id aid,article.title,article.content from user,article
where user.id=article.userid and user.id=#{id}
</select>
<!--執行增加操作的SQL語句。id和parameterType
分別與IUserOperation介面中的addUser方法的名字和
引數型別一致。以#{name}的形式引用Student引數
的name屬性,MyBatis將使用反射讀取Student引數
的此屬性。#{name}中name大小寫敏感。引用其他
的gender等屬性與此一致。seGeneratedKeys設定
為"true"表明要MyBatis獲取由資料庫自動生成的主
鍵;keyProperty="id"指定把獲取到的主鍵值注入
到Student的id屬性-->
<insert id="addUser" parameterType="User"
useGeneratedKeys="true" keyProperty="id">
insert into user(userName,userAge,userAddress)
values(#{userName},#{userAge},#{userAddress})
</insert>
<update id="updateUser" parameterType="User" >
update user set userName=#{userName},userAge=#{userAge},userAddress=#{userAddress} where id=#{id}
</update>
<delete id="deleteUser" parameterType="int">
delete from user where id=#{id}
</delete>
</mapper>
這裡我們介紹一種比較方便的查詢方法,介面式查詢。
首先我們定義一個介面,包名.類名和mapper的namespace屬性相同,裡面定義一些增刪改查的方法,方法名要和mapper中的sql語句的id相同,這樣我們就可以使用介面式方法來做資料庫操作了。
下面是介面的程式碼
package com.yihaomen.mybatis.inter;
import java.util.List;
import com.yihaomen.mybatis.model.*;
public interface UserMapper {
public User selectUserByID(int id);
public List<User> selectUsers(String userName);
public void addUser(User user);
public void updateUser(User user);
public void deleteUser(int id);
public List<Article> getUserArticles(int id);
}
下面是呼叫方法:
package com.yihaomen.test;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.yihaomen.mybatis.inter.UserMapper;
import com.yihaomen.mybatis.model.Article;
import com.yihaomen.mybatis.model.User;
@Service("mybatisSprintTest")
public class MybatisSprintTest{
@Autowired
private UserMapper mapper;
@Transactional(propagation = Propagation.REQUIRED)
public void insert() {
// 測試id=1的使用者查詢,根據資料庫中的情況,可以改成你自己的.
System.out.println("得到使用者id=1的使用者資訊");
System.out.println(mapper);
User user = mapper.selectUserByID(1);
System.out.println(user.getUserAddress());
// 得到文章列表測試
System.out.println("得到使用者id為1的所有文章列表");
List<Article> articles = mapper.getUserArticles(1);
for (Article article : articles) {
System.out.println(article.getContent() + "--" + article.getTitle());
}
User newUser = new User();
newUser.setUserAddress("a");
newUser.setUserAge(5);
newUser.setUserName("zhangyang");
// 插入使用者
mapper.addUser(newUser);
// 插入後返回自增長ID
System.out.println(newUser.getId()+"insert success");
// 插入使用者
mapper.addUser(newUser);
// 插入後返回自增長ID
System.out.println(newUser.getId()+"insert success");
// 丟擲異常,@Transactional做事務回滾(兩條資料都不會插入)
throwException();
}
private static void throwException() {
throw new RuntimeException();
}
public UserMapper getMapper() {
return mapper;
}
public void setMapper(UserMapper mapper) {
this.mapper = mapper;
}
}
首先我們需要用spring注入mapper屬性,檢視spring配置檔案中這段配置
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!--sqlSessionFactory屬性指定要用到的SqlSessionFactory例項-->
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
<!--mapperInterface屬性指定對映器介面,用於實現此介面並生成對映器物件-->
<property name="mapperInterface" value="com.yihaomen.mybatis.inter.UserMapper" />
</bean>
這裡配置了一個mapper工廠,用於生產一個com.yihaomen.mybatis.inter.UserMapper的實現類,這個實現類實現了介面中定義的方法。
這裡應該使用的是proxy動態代理技術,用一個類來實現該介面,然後根據介面的包名.類名(名稱空間)+方法名(sql的id)去xml檔案中獲取對應的sql語句,
之後我們呼叫這個實現類的方法,傳入引數後獲取查詢結果。
到此就結束了。本文中的配置已經實現了業務層的事務管理,可以做到業務層事務回滾。
另外推薦一篇很好的帖子:http://blog.csdn.net/kutejava/article/details/9164353#t4
裡面講的mybatis很詳細,全部掌握後就是mybatis的大神了。
本工程程式碼在我的資原始檔裡有上傳,下載後匯入即可執行。環境:tomcat7,jdk7