Spring 框架與 MyBatis 的集成詳解

前言

MyBatis 是支持定制化 SQL、存儲過程以及高級映射的優秀的持久層框架。MyBatis 避免了幾乎所有的 JDBC 代碼和手動設置參數以及獲取結果集。MyBatis 可以對配置和原生Map使用簡單的 XML 或注解,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄。
—— 摘自 MyBatis 中文官網,http://www.mybatis.org/mybatis-3/zh/

Spring 與 MyBatis 集成

MyBatis 與 Spring 的集成思路,總共有以下幾個步驟:

  1. 引入 MyBatis 與 Spring 框架相關的包,數據庫驅動的包,可引入數據庫連接池、日志、測試相關包
  2. 配置XML,包括數據源 DataSource (用于指定數據庫連接地址、賬號、密碼等數據庫配置)和 SqlSessionFactory (用于指定 MyBatis 自動載入的 *Mapper.xml)
  3. 編寫 Entity 類,用來存儲數據庫查詢返回數據,一般而言,成員變量對應數據庫表字段名,僅提供 getter/setter 方法
  4. 編寫 Mapper 接口 與 Mapper.xml ,Mapper 接口 指定操作名,并規定好傳入參數,Mapper.xml 為數據庫操作的 SQL ,id 需要與 Mapper 接口 一致
  5. 創建數據庫,編寫服務,測試

一、Maven 引入 jar 包

在 Maven 項目中的 pom.xml 文件增加以下依賴。項目一般還需要增加 log 日志模塊、junit 測試模塊等,在此 pom.xml 不再贅述。

<dependencies>
    <!-- Maven Lib -->
    <!-- Spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- Spring AOP -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.9</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spri
    <!-- Servlet -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
    </dependency>

    <!-- MyBatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.1</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.0</version>
    </dependency>

    <!-- 連接池 -->
    <dependency>
        <groupId>c3p0</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.1.2</version>
    </dependency>

    <!--  mysql driver -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.39</version>
    </dependency>
</dependencies>

二、創建數據庫環境

因為 MyBatis 框架是解決持久化或者說數據庫的問題,因此我們需要配置一下數據庫環境。

DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
    `id` INT(12) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(255) NOT NULL,
    `age` INT(4) DEFAULT 0,
    `gender` INT(2),
    PRIMARY KEY(`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

三、配置 sqlSessionFactory 與 DataSource

要使用 MyBatis ,至少需要一個 SqlSessionFactoryBean 是用于創建 SqlSessionFactory 的。要配置這個 Factory bean ,放置下面的代碼在 Spring 的 XML 配置文件中。我在配置時,將數據庫相關的配置都創建了一個獨立的 XML 配置文件,然后在 Spring 主配置文件中通過 import 引用。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/sc    ma/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSc    ma-instance"
       xsi:sc    maLocation="http://www.springframework.org/sc    ma/beans http://www.springframework.org/sc    ma/beans/spring-beans.xsd">

    <!-- mysql data source -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" lazy-init="false">
        <property name="driverClass" value="${jdbc.driverclass}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="idleConnectionTestPeriod" value="60"/>
        <property name="testConnectionOnC    ckout" value="false"/>
        <property name="initialPoolSize" value="2"/>
        <property name="minPoolSize" value="5"/>
        <property name="maxPoolSize" value="50"/>
        <property name="acquireIncrement" value="1"/>
        <property name="acquireRetryAttempts" value="1"/>
        <property name="maxIdleTime" value="6000"/>
        <property name="maxStatements" value="0"/>
    </bean>

    <!-- SqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- Mapper文件存放的位置,當Mapper文件跟對應的Mapper接口處于同一位置的時候可以不用指定該屬性的值 -->
        <property name="mapperLocations" value="classpath*:sqlmap/*.xml"/>
    </bean>

    <!-- DAO Mapper -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="annotationClass" value="org.springframework.stereotype.Repository" />
        <!-- 掃描器開始掃描的基礎包名,支持嵌套掃描 -->
        <property name="basePackage" value="com.test.dao.mapper" />
    </bean>
</beans>

以上是 my-db.xml 配置文件,主要分為三部分:

  1. datasource ,數據源,與數據庫連接相關,配置數據庫的地址、賬戶、密碼,一些配置等等,從 jdbc.properties 文件中載入。關于 Spring 如何載入 properties 文件如何實現,不在這篇文章贅述了。
  2. sqlSessionFactory ,數據庫會話工廠。從 *Mapper.xml 中文件自動載入 <mapper>
  3. Mapper 類 ,在此配置中采用 Scanner 方式,自動從 mapper 包內載入 mapper 類。

四、調用 MyBatis 框架

創建 Entity,映射 Database 表(或有)

在 entity 包中創建實體,對應 t_user 表 的返回。成員變量一般與數據庫表字段名一一對應,成員方法僅提供 getter/setter 方法。
實體類不是必須的,MyBatis 提供將數據庫返回簡單的映射到 Map 或 HashMap 結構中,而非 POJO 中。

/**
 * t_user 表實體
 */
public class User  implements Serializable {
    private int id;
    private String name;
    private int age;
    private int gender;

    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    public int getGender() { return gender; }
    public void setGender(int gender) { this.gender = gender; }
}

創建 DAO/Mapper

dao.mapper 包內創建 UserMapper 接口 ,并添加 @Repository 注解

@Repository
public interface UserMapper {
    public List<User> findUserById(int id);
    public Integer insertUser(User user);
}

對應具體數據庫的方法,例如插入用戶、通過 id 查找用戶。每次需要定義一個數據庫操作,就在 Mapper 類中定義一個接口。

注意,因為在三、配置 sqlSessionFactory 與 DataSource ,定義了自動載入 Mapper 類 。因此,需要加入了 @Repository 的注解,用于標注數據訪問組件,即DAO 組件。否則不需要 @Repository 注解,但需要在 *Mapper.xml 中增加 <mapper> 配置。

配置 Mapper.xml

Mapper.xml 中編寫具體的數據庫操作的 SQL。
其中,tag 有 insert, select, update 等
id 與 Mapper 接口方法名一一對應;
parameterType 為傳入參數,可以是 POJO,也可以是 int、String 這種基本類型,SQL 中的參數用 #{id} 的形式表示;
resultType 或者 resultMap ,都是存儲返回的結果集,其中 resultMap 比較強大,靈活;resultType 可以簡單指定為 map 或者 POJO。

<?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.test.dao.mapper.UserMapper">
    <!--配置一個resultMap 指定返回的類型 -->
    <resultMap id="userInfo" type="com.test.entity.User">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="age" property="age"/>
        <result column="gender" property="gender"/>
    </resultMap>

    <select id="queryUserInfos" resultMap="userInfo" parameterType="java.lang.Integer">
        SELECT * FROM t_user W    RE age = #{age} ORDER BY id DESC;
    </select>

    <insert id="insertUserInfo" parameterType="com.test.entity.User">
        INSERT INTO t_user(name, age, gender) VALUES (#{userName},#{age},#{gender})
        <selectKey resultType="int" keyProperty="id">
            SELECT LAST_INSERT_ID();
        </selectKey>
    </insert>
</mapper>

關于 *Mapper.xml 文件的配置,詳情參考官方文檔 http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html

通過服務調用

已經完成上述配置和接口等編寫后,就可以在服務中調用了。

@Service(value = "userService")
public class UserServiceImpl implements UserService{
    @Autowired
    private UserMapper userMapper;

    @Override
    public List<User> getUser(Integer id) {
        List x =  userMapper.findUserById(id);
        return x;
    }

    @Override
    public Integer addUser(User user) {
        return userMapper.insertUser(user);
    }
}

在系統設計時,不會讓服務直接就去調用如此底層的操作,往往會增加一個 model 層或者 controller 層。調用方法還是一致的,都是先注入 Mapper 接口,然后調用接口方法就可以了。

參考資料

  1. MyBatis 與 Spring 集成,官網 http://www.mybatis.org/spring/zh/getting-started.html
  2. MyBatis 官網,配置和使用介紹,http://www.mybatis.org/mybatis-3/zh/configuration.html
  3. SSM框架——詳細整合教程(Spring+SpringMVC+MyBatis),作者 shu_lin,http://blog.csdn.net/zhshulin/article/details/37956105
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,247評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,520評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,362評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,805評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,541評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,896評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,887評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,062評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,608評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,356評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,555評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,077評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,769評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,175評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,489評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,289評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,516評論 2 379

推薦閱讀更多精彩內容

  • 1. 簡介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存儲過程以及高級映射的優秀的...
    笨鳥慢飛閱讀 5,571評論 0 4
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,826評論 18 139
  • 單獨使用mybatis是有很多限制的(比如無法實現跨越多個session的事務),而且很多業務系統本來就是使用sp...
    七寸知架構閱讀 3,474評論 0 53
  • Spring 技術筆記Day 1 預熱知識一、 基本術語Blob類型,二進制對象Object Graph:對象圖...
    OchardBird閱讀 991評論 0 2
  • 前不久,我在查看朋友圈,發現有人給我留了一則留言:糾結7年的婚姻,最終還是逃不過七年之癢,我還是選擇離婚。不知為何...
    彭小汐閱讀 401評論 0 0