MyBatis-Spring 會幫助你將 MyBatis 代碼無縫地整合到 Spring 中。 使用這個類庫中的類, Spring 將會加載必要的MyBatis工廠類和 session 類。 這個類庫也提供一個簡單的方式來注入MyBatis數據映射器和SqlSession到業務層的bean中。 而且它也會處理事務, 翻譯MyBatis的異常到Spring的 DataAccessException異常(數據訪問異常,譯者注)中。最終它並不會依賴於MyBatis,Spring或MyBatis-Spring來構建應用程序代碼。
一、 使用Maven創建一個Web項目
為了完成Spring4.x與MyBatis3.X的整合更加順利,先回顧在Maven環境下創建Web項目並使用MyBatis3.X,第一、二點內容多數是回顧過去的內容 。完成第一階段與第二階段的項目結構如下所示:

下載階段一與階段二示例
1.2、點擊“File”->“New”->"Other"->輸入“Maven”,新建一個“Maven Project”,如下圖所示:

1.2、請勾選“Create a simple project”,創建一個簡單的項目,不使用模板。也可以使用模板,選擇WebApp,不過這裡就不應該勾選。如下圖所示:

1.3、填寫好包名、項目名,選擇打包類型為:war,如下圖所示:

1.4、項目創建好後可能會發現有錯誤,選擇項目,右鍵“屬性properties”->"層面Project Facets"->"Java"修改版本號為1.7,默認為1.5;點擊“Ok”保存後關閉。如下圖所示:

1.5、重復上一個步驟,反勾Dynamic Web Module,將項目暫時變成非Web項目。點擊“Ok”保存後關閉。

1.6、重復上一步驟,再進層面屬性,勾選“Dynamic Web Module”選擇Version為3.0。點擊左下角的超鏈接“Further Configuration available...“。

1.7、勾選“Generate web.xml deployment descriptor”生成web.xml部署描述文件。點擊“Ok”保存後關閉。

1.8、將生成的WebContent目錄下的兩個文件夾“META-INF”與“WEB-INF”復制到src/main/webapp目錄下。

1.9、刪除WebContent目錄。

1.10、刪除後會發現項目的pom.xml文件報錯,是因為找不到指定位置的web.xml文件引起的。再進入項目的屬性,選擇“Deployment Assembly”項目部署項,刪除“src/test/java”、“src/test/resources”與“WebContent”目錄,因為這三項不需要部署出去。

1.11、點擊“Add添加”後選擇“Folder文件夾”為項目的最終部署結果指定Web內容根文件夾。

1.12、選擇src\main\webapp目錄為目標目錄,點擊“Finish完成”保存並關閉。

1.13、如果此時項目還報錯,隨便修改pom.xml文件後保存後應該錯誤會消失。

1.14、在src\main\webapp目錄下新建一個index.jsp文件,作為測試使用。

1.15、新建完成後發現有錯誤,是因為沒有JavaEE Server Runtime引起的,在項目上右鍵屬性選擇“Java Build Path”項,點擊“Add Library...”添加引用。

1.16、選擇Server Runtime項,點擊“Next下一步”,再選擇“Apache Tomcat v7.0”,這裡可能要根據自己的運行環境選擇了,如果還沒Server,則應該先整合Tomcat。


1.17、在index.jsp文件中寫上測試內容。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello World!</title>
</head>
<body>
Hello World!
<p>
<%=new java.util.Date().toLocaleString() %>
</p>
</body>
</html>
1.18、在項目上右鍵選擇“Run as”-> “Run on Server”運行項目,運行結果如下。

二、使用MyBatis完成MySQL數據庫訪問
2.1、添加依賴
要完成使用MyBatis訪問MySQL數據庫,需要添加一些依賴包,包含MyBatis3,連接驅動,JUnit,Log4j2等。可以去共享資源庫中搜索,第一個網站地址是:http://mvnrepository.com/, 這裡以搜索連接驅動為示例,搜索後的結果有5.xx版許多,也有6.xx版,但不建議使用6.xx版,因為MyBatis3不支持。

我們選擇5.0版中的5.1.38,將Maven的依賴信息復制到項目中的pom.xml的dependencies結點下

當然也可去另外一個網站:http://search.maven.org/,這裡以log4j為例子搜索如下:

有一些依賴也可以直接去官網查找,如MyBatis3:

項目的pom.xml文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zhangguo</groupId>
<artifactId>Spring061</artifactId>
<version>0.0.1</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
</project>
引用結果:

如果在網速不穩定的情況下,下載包很有可能失敗,可以試試強制項目重新下載;可以使用下載工具將jar包下載後手復制到本地資源庫中。


2.2、准備數據
打開MySQL數據庫,創建一個表,這裡以booktypes表為例。

sql腳本如下:
/*
Navicat MySQL Data Transfer
Source Server : localhost
Source Server Version : 50536
Source Host : localhost:3306
Source Database : db2
Target Server Type : MYSQL
Target Server Version : 50536
File Encoding : 65001
Date: 2016-07-04 10:49:56
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `booktypes`
-- ----------------------------
DROP TABLE IF EXISTS `booktypes`;
CREATE TABLE `booktypes` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '類型編號',
`typeName` varchar(100) NOT NULL COMMENT '類型名稱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=94 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of booktypes
-- ----------------------------
INSERT INTO `booktypes` VALUES ('1', '計算機軟件開發');
INSERT INTO `booktypes` VALUES ('2', '計算機網絡工程');
INSERT INTO `booktypes` VALUES ('3', '神話小說');
INSERT INTO `booktypes` VALUES ('4', '科幻小說');
INSERT INTO `booktypes` VALUES ('5', '外語');
INSERT INTO `booktypes` VALUES ('6', '測試類型');
INSERT INTO `booktypes` VALUES ('7', '91');
INSERT INTO `booktypes` VALUES ('8', '92');
INSERT INTO `booktypes` VALUES ('9', '93');
INSERT INTO `booktypes` VALUES ('91', '建築設計');
INSERT INTO `booktypes` VALUES ('92', '工業設計');
INSERT INTO `booktypes` VALUES ('93', '船舶制造');
2.3、創建java Bean
在包com.zhangguo.Spring61.entities下添加類BookType類型。
package com.zhangguo.Spring61.entities;
/**
* 圖書類型
*
*/
public class BookType {
/**
* 編號
*/
private int id;
/**
* 類型名
*/
private String typeName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
}
2.4、創建實例與表的映射文件
這裡用接口+XML的形式完成,BookType數據訪問接口如下:
package com.zhangguo.Spring61.mapping;
import java.util.List;
import com.zhangguo.Spring61.entities.BookType;
/**
* 圖書類型數據訪問接口
*
*/
public interface BookTypeDAO {
/*
* 獲得所有圖書類型
*/
public List<BookType> getAllBookTypes();
}
BookTypeMapper.xml文件如下:
<?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.zhangguo.Spring61.mapping.BookTypeDAO">
<!--id應該是接口中的方法,結果類型如沒有配置別名則應該使用全名稱 -->
<select id="getAllBookTypes" resultType="BookType">
select id,typeName from booktypes
</select>
</mapper>
2.5、創建MyBatisCfg.xml文件
MyBatisCfg.xml文件用於配置MyBatis的運行環境,內容如下:
<?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>
<!-- 指定數據庫連接信息的位置 -->
<properties resource="db.properties"></properties>
<!--類型別名,默認引入com.zhangguo.Spring61.entities下的所有類 -->
<typeAliases>
<package name="com.zhangguo.Spring61.entities"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<mappers>
<!--引入映射文件 -->
<mapper resource="com/zhangguo/Spring61/mapping/BookTypeMapper.xml" />
</mappers>
</configuration>
因為配置中依賴了db.properties文件,該文件用於指定數據庫的連接信息,內容如下:
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/db2 username=root password=root
2.6、實現數據訪問功能
為了更加方便的復用MyBatis實現數據訪問不需要頻繁的創建SQLSessionFactory和SQLSession對象,封裝一個MyBatisUtil工具類如下:
package com.zhangguo.Spring61.dao;
import java.io.InputStream;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public abstract class MyBatisUtil {
//GC不理static
private static SqlSessionFactory factory=null;
public static SqlSessionFactory getSqlSessionFactory(){
if(factory==null){
// 獲得環境配置文件流
InputStream config = MyBatisUtil.class.getClassLoader().getResourceAsStream("MyBatisCfg.xml");
// 創建sql會話工廠
factory = new SqlSessionFactoryBuilder().build(config);
}
return factory;
}
//獲得會話
public static SqlSession getSession(){
return getSqlSessionFactory().openSession(true);
}
/**
* 獲得得sql會話
* @param isAutoCommit 是否自動提交,如果為false則需要sqlSession.commit();rollback();
* @return sql會話
*/
public static SqlSession getSession(boolean isAutoCommit){
return getSqlSessionFactory().openSession(isAutoCommit);
}
}
創建類BookTypeDAOImpl實現接口BookTypeDAO,這裡要通過MyBatis實現數據訪問功能,內容如下:
package com.zhangguo.Spring61.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import com.zhangguo.Spring61.entities.BookType;
import com.zhangguo.Spring61.mapping.BookTypeDAO;
/**
* 實現圖書類型數據訪問
*
*/
public class BookTypeDAOImpl implements BookTypeDAO {
@Override
public List<BookType> getAllBookTypes() {
//獲得會話對象
SqlSession session=MyBatisUtil.getSession();
try {
//通過MyBatis實現接口BookTypeDAO,返回實例
BookTypeDAO bookTypeDAO=session.getMapper(BookTypeDAO.class);
return bookTypeDAO.getAllBookTypes();
} finally {
session.close();
}
}
}
2.7、測試運行
新建一個JUnit Test Case測試用例,如下所示:

測試用例TestBookTypeDAOImpl.java文件如下:
package com.zhangguo.Spring61.test;
import static org.junit.Assert.*;
import java.util.List;
import org.junit.BeforeClass;
import org.junit.Test;
import com.zhangguo.Spring61.dao.BookTypeDAOImpl;
import com.zhangguo.Spring61.entities.BookType;
import com.zhangguo.Spring61.mapping.BookTypeDAO;
public class TestBookTypeDAOImpl {
static BookTypeDAO bookTypeDao;
@BeforeClass
public static void beforeClass()
{
bookTypeDao=new BookTypeDAOImpl();
}
@Test
public void testGetAllBookTypes() {
List<BookType> booktypes=bookTypeDao.getAllBookTypes();
for (BookType bookType : booktypes) {
System.out.println(bookType);
}
assertNotNull(booktypes);
}
}
測試結果:

2.8、整合log4j2
上面的測試雖然通過,但是有一個錯誤提示“ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.”,大意是:日志記錄器沒有找到log4j2的配置文件。在源碼的根目錄下創建一個log4j2.xml配置文件,文件內容如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="off" monitorInterval="1800">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
再運行就會發現log4j2已經在運行了,從控制台可以看到MyBatis的運行狀態信息:

程序向數據庫發送的SQL請求,及數據庫向程序響應的結果就清楚了。
下載階段一與階段二示例
三、使用Spring4.X整合MyBatis3.X初級版
在MyBatis的github官網(https://github.com/mybatis/spring)中有一個叫MyBatis Spring Adapter(MyBatis-Spring)的庫,暫且翻譯成:MyBatis Spring適配器,它的作用是:原話:“MyBatis-Spring adapter is an easy-to-use Spring3 bridge for MyBatis sql mapping framework.”,就是了為更容易的將MyBatis與Spring整合,充分發揮二兩結合的優勢,它相當於一個橋。
什麼是:MyBatis-Spring?
MyBatis-Spring會幫助你將MyBatis代碼無縫地整合到Spring中。使用這個類庫中的類,Spring將會加載必要的MyBatis工廠類和session類。這個類庫也提供一個簡單的方式來注入MyBatis數據映射器和SqlSession到業務層的bean中。而且它也會處理事務,翻譯MyBatis的異常到Spring的DataAccessException異常(數據訪問異常,譯者注)中。最終,它並不會依賴於MyBatis,Spring或MyBatis-Spring來構建應用程序代碼。
3.1、修改pom.xml添加依賴
為了將Spring與MyBatis整合完成,需要依賴MyBatis,因為在上面的示例中已依賴完成,這裡就不再需要,主要需依賴的是Spring核心,AOP,JDBC,MyBatis-Spring等jar包。具體的依賴結果pom.xml文件如下所示:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zhangguo</groupId>
<artifactId>Spring061</artifactId>
<version>0.0.1</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.3.0.RELEASE</spring.version>
</properties>
<dependencies>
<!--mysql數據庫驅動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!--log4j日志包 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6.1</version>
</dependency>
<!-- mybatis ORM框架 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<!-- JUnit單元測試工具 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<!--mybatis-spring適配器 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!--Spring框架核心庫 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- aspectJ AOP 織入器 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<!--Spring java數據庫訪問包,在本例中主要用於提供數據源 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</project>
3.2、創建Spring上下文初始化配置文件
該文件取名為ApplicationContext.xml主要原因是“約束優於配置”的理由,使用Web監聽器加載Spring時會默認找該名稱的文件。在文件中我們可像以前學習Spring一樣配置IOC與AOP,只不過這裡整合了一些MyBatis內容。文件內容如下:
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!--1定義一個jdbc數據源,創建一個驅動管理數據源的bean -->
<bean id="jdbcDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/db2" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<!--2創建一個sql會話工廠bean,指定數據源-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="jdbcDataSource" /><!-- 指定數據源 -->
<property name="configLocation" value="classpath:MyBatisCfg.xml"></property> <!-- 指定配置文件 -->
</bean>
<!--3創建一個booTypeDAO-->
<bean id="bookTypeDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!--指定映射文件 -->
<property name="mapperInterface" value="com.zhangguo.swd.mapping.BookTypeDAO"></property>
<!-- 指定sql會話工廠-->
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
<!--下面的配置暫時未使用 -->
<context:component-scan base-package="com.zhangguo">
</context:component-scan>
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
</beans>
從上面的代碼可以看到分別創建了一個驅動管理數據源的對象,會話工廠與實現數據訪問的對象通過Spring IOC完成,而不再是硬編碼。第2段配置與下面的代碼功能基本類似:
private static SqlSessionFactory factory=null;
public static SqlSessionFactory getSqlSessionFactory(){
if(factory==null){
// 獲得環境配置文件流
InputStream config = MyBatisUtil.class.getClassLoader().getResourceAsStream("MyBatisCfg.xml");
// 創建sql會話工廠
factory = new SqlSessionFactoryBuilder().build(config);
}
return factory;
}
第3段配置與下面的java代碼基本類似:
SqlSession session = MyBatisUtil.getSession();
try {
BookTypeDAO bookTypeDAO = session.getMapper(BookTypeDAO.class);
return bookTypeDAO.getAllBookTypes();
} finally {
session.close();
}
3.3、測試運行
package com.zhangguo.Spring61.test;
import static org.junit.Assert.assertNotNull;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zhangguo.Spring61.entities.BookType;
import com.zhangguo.Spring61.mapping.BookTypeDAO;
public class TestMyBatisSpring01 {
@Test
public void test01() {
//初始化容器
ApplicationContext ctx=new ClassPathXmlApplicationContext("ApplicationContext.xml");
//獲得bean
BookTypeDAO bookTypeDao=ctx.getBean("bookTypeDao",BookTypeDAO.class);
//訪問數據庫
List<BookType> booktypes=bookTypeDao.getAllBookTypes();
for (BookType bookType : booktypes) {
System.out.println(bookType);
}
assertNotNull(booktypes);
}
}
運行結果:

小結:此處的整合還是相對基礎,更完善的整合內容將在後面的章節實現。另外在MyBatisCfg.xml文件中可以刪除運行環境中數據源配置部分的內容,如下圖所示。我們當前的示例使用的是Spring提供的數據源,其實也可以使用一第三方的數據源管理,如C3P0,Druid(德魯伊,阿裡巴巴開發)等。

下載第三階段示例