MyBatis學習筆記

一、MyBatis介紹java

二、MyBatis架構mysql

三、MyBatis簡單入門實例web

四、傳統Dao開發與MyBatis的Mapper動態代理開發spring

五、sqlMapConfig.xml配置文件sql

六、輸入映射和輸出映射數據庫

  6.1 parameterTypeexpress

  6.2 resultTypeapache

  6.3 resultMap編程

七、動態sql數組

  7.1 if標籤

   7.2 where標籤

  7.3 sql片斷

  7.4 foreach標籤

八、關聯查詢

  8.1 一對一查詢

  8.2 一對多查詢

九、MyBatis整合Spring

  9.1 整合思路

  9.2 整合所需的jar包

  9.3 建立配置文件

  9.4 建立pojo

  9.5 Dao開發方式簡單使用

  9.6 Mapper代理形式 

 

結尾

一、MyBatis介紹

MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,而且更名爲MyBatis 。2013年11月遷移到Github。

MyBatis是一個優秀的持久層框架,它對jdbc的操做數據庫的過程進行封裝,使開發者只須要關注 SQL 自己,而不須要花費精力去處理例如註冊驅動、建立connection、建立statement、手動設置參數、結果集檢索等jdbc繁雜的過程代碼。

Mybatis經過xml或註解的方式將要執行的各類statement(statement、preparedStatemnt、CallableStatement)配置起來,並經過java對象和statement中的sql進行映射生成最終執行的sql語句,最後由mybatis框架執行sql並將結果映射成java對象並返回。

二、MyBatis架構

一、mybatis配置的sqlMapConfig.xml,此文件做爲mybatis的全局配置文件,配置了mybatis的運行環境等信息。

mapper.xml文件即sql映射文件,文件中配置了操做數據庫的sql語句。此文件須要在sqlMapConfig.xml中加載。

二、經過mybatis環境等配置信息構造SqlSessionFactory即會話工廠

三、由會話工廠建立sqlSession即會話,操做數據庫須要經過sqlSession進行。

四、mybatis底層自定義了Executor執行器接口操做數據庫,Executor接口有兩個實現,一個是基本執行器、一個是緩存執行器。

五、Mapped Statement也是mybatis一個底層封裝對象,它包裝了mybatis配置信息及sql映射信息等。mapper.xml文件中一個sql對應一個Mapped Statement對象,sql的id便是Mapped statement的id。

六、Mapped Statement對sql執行輸入參數進行定義,包括HashMap、基本類型、pojo,Executor經過Mapped Statement在執行sql前將輸入的java對象映射至sql中,輸入參數映射就是jdbc編程中對preparedStatement設置參數。

七、Mapped Statement對sql執行輸出結果進行定義,包括HashMap、基本類型、pojo,Executor經過Mapped Statement在執行sql後將輸出結果映射至java對象中,輸出結果映射過程至關於jdbc編程中對結果的解析處理過程。

三、MyBatis簡單入門實例

 1)基本開發環境搭建:基於maven搭建MyBatis開發環境,而後進行測試數據庫建立以及相關jar包的引入

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>

2)建立配置文件:根據架構圖,首先建立sqlMapConfig.xml,因爲咱們是單獨開發的,須要在配置文件中進行數據庫鏈接的配置

<?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="jdbc.properties"/>
    <environments default="development">
        <environment id="development">
            <!-- 使用jdbc事務管理 -->
            <transactionManager type="JDBC" />
            <!-- 數據庫鏈接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
            </dataSource>
        </environment>
    </environments>
    
</configuration>

這裏咱們使用了jdbc.properties將數據庫的相關信息單獨提取出來

3)建立pojo:與數據庫中的表進行匹配,這裏以user表舉例

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable {

    private static final long serialVersionUID = 1L;
    private Integer id;
    private String username;// 用戶姓名
    private String sex;// 性別
    private Date birthday;// 生日
    private String address;// 地址


    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", sex=" + sex
                + ", birthday=" + birthday + ", address=" + address + "]";
    }
}

4)建立映射文件並集中到sqlMapConfig.xml:爲User.java建立映射文件User.xml,該文件中主要進行SQL語句的編寫

<?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">
<!-- 寫Sql語句   -->
<mapper namespace="user">
    <select id="findUserById" parameterType="Integer" resultType="com.panlei.pojo.User">
        select * from user where id = #{v}
    </select>
</mapper>

這裏的不一樣的聲明用不一樣的id進行區別,parameterType是傳參的類型,resultType是返回值類型,要與後面講到的方法調用進行匹配。namespace是爲了區分不一樣的映射mapper文件集中到sqlMapConfig.xml中可能id衝突的問題,後面還會具體講解。

5)具體測試1:根據id查詢用戶信息,仍是建立SqlSessionFactory,而後獲取SqlSession,再調用selectOne(..)方法,根據傳遞的"user.findUserById"定位到具體的映射文件的具體sql語句,這裏傳遞的參數即是前面定義的所需參數

import com.panlei.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;

public class TestMyBatis {
    @Test
    public void test1() {
        try {
            String resource = "sqlMapConfig.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            User o = sqlSession.selectOne("user.findUserById", 10);
            System.out.println(o);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

6)具體測試2:根據用戶名模糊匹配查詢

具體的sql語句格式:select * from user where username like '%五%'

這裏傳遞的參數就是String類型,而後返回值多是一個用戶列表,這裏用的是${value},不是前面的#{},後面具體講解區別

<select id="findUserByUsername" parameterType="String" resultType="com.panlei.pojo.User">
        select * from user where username like '%${value}%'
</select>
    // 根據用戶名模糊匹配
    @Test
    public void test2() {
        try {
            String resource = "sqlMapConfig.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            List<User> users = sqlSession.selectList("user.findUserByUsername", "五");
            for(User u:users) {
                System.out.println(u);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

7)#{}與${}的區別

#{}表示一個佔位符號,經過#{}能夠實現preparedStatement向佔位符中設置值,自動進行java類型和jdbc類型轉換。#{}能夠有效防止sql注入。 #{}能夠接收簡單類型值或pojo屬性值。 若是parameterType傳輸單個簡單類型值,#{}括號中能夠是value或其它名稱。

${}表示拼接sql串,經過${}能夠將parameterType 傳入的內容拼接在sql中且不進行jdbc類型轉換, ${}能夠接收簡單類型值或pojo屬性值,若是parameterType傳輸單個簡單類型值,${}括號中只能是value。

8)具體實例3:添加用戶,這裏直接傳遞的參數是自定義的User對象實例,直接進行映射,其屬性要與pojo中的屬性名一致

<!-- 保存用戶 -->
<insert id="saveUser" parameterType="com.panlei.pojo.User">
  INSERT INTO `user` (username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address})
</insert>

這裏在實際應用中可能須要當即獲取新添加用戶的id來進行後續操做,下面演示如何編碼:

<insert id="saveUser" parameterType="com.panlei.pojo.User">
<!-- selectKey 標籤實現主鍵返回 -->
<!-- keyColumn:主鍵對應的表中的哪一列 -->
<!-- keyProperty:主鍵對應的pojo中的哪個屬性 -->
<!-- order:設置在執行insert語句前執行查詢id的sql,仍是在執行insert語句以後執行查詢id的sql -->
<!-- resultType:設置返回的id的類型 -->
<selectKey keyColumn="id" keyProperty="id" order="AFTER"
    resultType="int">
    SELECT LAST_INSERT_ID()
</selectKey>
    INSERT INTO `user` (username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address})
</insert>

LAST_INSERT_ID():是mysql的函數,返回auto_increment自增列新記錄id值。

而後在測試代碼中能夠直接打印插入用戶的id,發現是最新的自增id。不須要額外的代碼。

Mybatis解決jdbc編程的問題

一、數據庫鏈接建立、釋放頻繁形成系統資源浪費從而影響系統性能,若是使用數據庫鏈接池可解決此問題。

解決:在SqlMapConfig.xml中配置數據鏈接池,使用鏈接池管理數據庫連接。

二、Sql語句寫在代碼中形成代碼不易維護,實際應用sql變化的可能較大,sql變更須要改變java代碼。

解決:將Sql語句配置在XXXXmapper.xml文件中與java代碼分離。

三、向sql語句傳參數麻煩,由於sql語句的where條件不必定,可能多也可能少,佔位符須要和參數一一對應。

解決:Mybatis自動將java對象映射至sql語句,經過statement中的parameterType定義輸入參數的類型。

四、對結果集解析麻煩,sql變化致使解析代碼變化,且解析前須要遍歷,若是能將數據庫記錄封裝成pojo對象解析比較方便。

解決:Mybatis自動將sql執行結果映射至java對象,經過statement中的resultType定義輸出結果的類型。

 

四、傳統Dao開發與MyBatis的Mapper動態代理開發

傳統的Dao開發,就是建立Dao,而後建立Dao的實現類,而後在Service中使用便可,仍是須要針對具體的pojo,建立具體的mapper.xml文件。具體實現就再也不詳述。

MyBatis中官方推薦使用編寫Mapper接口(至關於Dao接口),而後交給Mybatis進行處理,根據該接口自動建立該接口的動態代理對象。爲實現這一目標,事先定義了Mapper接口的開發規範:

1.Mapper.xml文件中的namespace與mapper接口的類路徑相同;

2.Mapper接口方法名和Mapper.xml中定義的每一個statement的id相同;

3.Mapper接口方法的輸入參數類型和mapper.xml中定義的每一個sql 的parameterType的類型相同;

4.Mapper接口方法的輸出參數類型和mapper.xml中定義的每一個sql的resultType的類型相同。

下面結合具體實例解釋上述規範:

 

 

這樣咱們在具體執行時,會自動生成接口的代理類對象,而後執行接口的具體方法時,會根據規範找到對應mapper文件下的相應方法

package com.panlei.mybatisdemo;

import com.panlei.mapper.UserMapper;
import com.panlei.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.Date;

public class TestMapper {
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void init() throws Exception {
        // 建立SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 加載SqlMapConfig.xml配置文件
        InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        // 建立SqlsessionFactory
        this.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    }

    @Test
    public void testSaveUser() {
        // 獲取sqlSession,和spring整合後由spring管理
        SqlSession sqlSession = this.sqlSessionFactory.openSession();

        // 從sqlSession中獲取Mapper接口的代理對象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setUsername("薩其馬");
        user.setSex("2");
        user.setBirthday(new Date());
        user.setAddress("北京");
        // 執行查詢方法
 userMapper.saveUser(user);    // 至關於 sqlSession.insert("namespace.saveUser", user) //        System.out.println(user);

        sqlSession.commit();
        // 和spring整合後由spring管理
        sqlSession.close();
    }


}

關於selectOne仍是selectList

動態代理對象調用sqlSession.selectOne()和sqlSession.selectList()是根據mapper接口方法的返回值決定,若是返回list則調用selectList方法,若是返回單個對象則調用selectOne方法。

五、sqlMapConfig.xml配置文件

SqlMapConfig.xml中配置的內容和順序以下:

   properties(屬性)

   settings(全局配置參數)

   typeAliases(類型別名)

   typeHandlers(類型處理器)

   objectFactory(對象工廠)

   plugins(插件)

   environments(環境集合屬性對象)

   environment(環境子屬性對象)

   transactionManager(事務管理)

   dataSource(數據源)

   mappers(映射器)

 

1) properties(屬性)

能夠引用java屬性文件中的配置信息,好比前面用到的jdbc.properties

2) typeAliases(類型別名)

咱們前面在傳遞參數,設置類型的時候,都是使用的 包名+類名,這樣比較費勁,那麼能不能像配置基本數據類型或者String同樣來進行配置呢?答案是能夠的,須要利用類型別名。

<typeAliases>
   <!-- 單個別名定義 -->
   <typeAlias alias="user" type="com.panlei.pojo.User" />
   <!-- 批量別名定義,掃描整個包下的類,別名爲類名(大小寫不敏感) -->
  <package name="com.panlei.pojo" />
</typeAliases>

sqlMapConfig.xml中利用<typeAliases>的<typeAlias>進行單個別名的定義。當有特別多的類須要定義的時候,一個一個的定義一樣很繁瑣,這就能夠利用<package>來進行統一的配置。

3) mappers(映射器)

<mapper resource=" " />

使用相對於類路徑的資源(如今的使用方式),如:<mapper resource="sqlmap/User.xml" />

<mapper class=" " />

使用mapper接口類路徑,如:<mapper class="com.panlei.mybatis.mapper.UserMapper"/>

注意:此種方法要求mapper接口名稱和mapper映射文件名稱相同,且放在同一個目錄中。

<package name=""/>  

註冊指定包下的全部mapper接口,如:<package name="com.panlei.mybatis.mapper"/>。注意:此種方法要求mapper接口名稱和mapper映射文件名稱相同,且放在同一個目錄中。

六、輸入映射和輸出映射

 6.1 parameterType(輸入類型)

在配置文件的編寫具體語句時,咱們須要傳入一些參數,前面的例子,咱們已經使用了簡單的類型,例如Integer,還有本身定義的POJO的類型,好比咱們自定義的User類型。

還有另一種狀況,就是自定義的類型中有另外一個自定義類型的屬性,好比User中有一個自定義Order類型的屬性,這時咱們須要傳遞POJO包裝對象。下面以一個例子來具體講解:

1)根據用戶名模糊查詢用戶信息,這裏虛設一個只有一個User屬性的包裝類,而後傳遞該包裝類,利用其User屬性的username模糊查詢用戶信息

包裝類

在UserMapper.java中編寫查詢接口方法:

在UserMapper.xml中編寫具體的數據庫查詢代碼,注意四條對應規則(namespace,id,傳參,返回類型):這裏咱們看到傳遞參數的名稱並未使用,而是直接使用了TestUser中的user屬性中的username屬性

 

編寫測試代碼:

 

 

 6.2 resultType(輸出類型)

1)輸出簡單類型

測試例子:SELECT COUNT(*) FROM ‘user’

先是在UserMapper接口中定義查詢方法

而後在UserMapper.xml文件中具體編寫查詢語句

 

測試輸出

2)此外還能夠輸出POJO對象以及POJO的對象列表,這咱們前面已經使用了,再也不詳述

 6.3  resultMap(輸出映射)

resultType能夠指定將查詢結果映射爲pojo,但須要pojo的屬性名和sql查詢的列名一致方可映射成功。

若是sql查詢字段名和pojo的屬性名不一致,能夠經過resultMap將字段名和屬性名做一個對應關係 ,resultMap實質上還須要將查詢結果映射到pojo對象中。

resultMap能夠實現將查詢結果映射爲複雜類型的pojo,好比在查詢結果映射對象中包括pojo和list實現一對一查詢和一對多查詢。

下面咱們以具體的例子演示:

1) 查詢order表的全部數據

order表的字段及數據以下:這裏的user_id不爲空

 

而後咱們定義相應的POJO類型,這裏咱們將表中的user_id定義爲userId屬性,模擬字段與屬性不一致的狀況。

   

爲更好的演示,咱們第一次查詢仍然使用resultType,看一下運行結果,而後再使用resultMap

具體的步驟仍然是建立OrderMapper接口,定義查詢方法,而後在OrderMapper.xml中編寫具體的查詢語句,並設置resultType類型

最終查詢結果輸出以下:能夠看到userId爲null

 

上面的結果產生緣由就是由於字段與屬性沒有一一對應的緣由。下面咱們使用resultMap進行演示:

只須要修改OrderMapper.xml便可,爲其添加<resultMap>,而後在具體的語句中利用resultMap屬性進行關聯便可,注意裏面的各個屬性的含義。

這裏由於只須要進行user_id與userId的映射,因此其餘屬性能夠不用處理。

 

而後咱們運行測試,發現userId已經有值了。

 

 

 七、動態sql

 經過mybatis提供的各類標籤方法實現動態拼接sql。

 7.1 if 標籤 

 需求:根據性別和名字查詢用戶,有時候條件可能爲空,須要進行判斷,爲空就再也不做爲條件

<select id="queryUserByWhere" parameterType="user" resultType="user">
    SELECT id, username, birthday, sex, address FROM `user`
    WHERE 1=1
    <if test="sex != null and sex != ''"> AND sex = #{sex} </if> <if test="username != null and username != ''"> AND username LIKE '%${username}%' </if>
</select>

 

 7.2 where 標籤

上面的sql還有where 1=1 這樣的語句,很麻煩

可使用where標籤進行改造

<select id="queryUserByWhere" parameterType="user" resultType="user">
    SELECT id, username, birthday, sex, address FROM `user`
 <!-- where標籤能夠自動添加where,同時處理sql語句中第一個and關鍵字,也就是刪除 -->
    <where>
        <if test="sex != null"> AND sex = #{sex} </if>
        <if test="username != null and username != ''"> AND username LIKE '%${username}%' </if>
    </where>
</select>

 

 7.3 sql片斷

Sql中可將重複的sql提取出來,使用時用include引用便可,最終達到sql重用的目的。

把上面例子中的id, username, birthday, sex, address提取出來,做爲sql片斷,以下:

<!-- 聲明sql片斷 -->
<sql id="userFields">
    id, username, birthday, sex, address
</sql>

<select id="queryUserByWhere" parameterType="user" resultType="user">
    <!-- SELECT id, username, birthday, sex, address FROM `user` -->
    <!-- 使用include標籤加載sql片斷;refid是sql片斷id --> SELECT <include refid="userFields" /> FROM `user` <!-- where標籤能夠自動添加where關鍵字,同時處理sql語句中第一個and關鍵字 -->
    <where>
        <if test="sex != null">
            AND sex = #{sex}
        </if>
        <if test="username != null and username != ''">
            AND username LIKE
            '%${username}%'
        </if>
    </where>
</select>

若是要使用別的Mapper.xml配置的sql片斷,能夠在refid前面加上對應的Mapper.xml的namespace

<select id="queryUserByWhere" parameterType="user" resultType="user">    
    SELECT <include refid="com.panlei.mapper.OrderMapper.userFields" /> FROM `user`
    <!-- where標籤能夠自動添加where關鍵字,同時處理sql語句中第一個and關鍵字 -->
    <where>
        <if test="sex != null">
            AND sex = #{sex}
        </if>
        <if test="username != null and username != ''">
            AND username LIKE
            '%${username}%'
        </if>
    </where>
</select>

 

 7.4 foreach標籤

向sql傳遞數組或List,mybatis使用foreach解析,以下:

 根據多個id查詢用戶信息

查詢sql:

SELECT * FROM user WHERE id IN (1,10,24)

對上面用到包裝類添加一個 List<Integer> ids 屬性

UserMapper.xml以下

<!-- 根據ids查詢用戶 -->
<select id="queryUserByIds" parameterType="queryVo" resultType="user">
    SELECT * FROM `user`
    <where>
        <!-- foreach標籤,進行遍歷 -->
        <!-- collection:遍歷的集合,這裏是QueryVo的ids屬性 -->
        <!-- item:遍歷的項目,能夠隨便寫,,可是和後面的#{}裏面要一致 -->
        <!-- open:在前面添加的sql片斷 -->
        <!-- close:在結尾處添加的sql片斷 -->
        <!-- separator:指定遍歷的元素之間使用的分隔符 -->
        <foreach collection="ids" item="item" open="id IN (" close=")"
            separator=",">
            #{item}
        </foreach>
    </where>
</select>

測試代碼以下:

@Test
public void testQueryUserByIds() {
    // mybatis和spring整合,整合以後,交給spring管理
    SqlSession sqlSession = this.sqlSessionFactory.openSession();
    // 建立Mapper接口的動態代理對象,整合以後,交給spring管理
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    // 使用userMapper執行根據條件查詢用戶
    QueryVo queryVo = new QueryVo();
    List<Integer> ids = new ArrayList<>();
    ids.add(1);
    ids.add(10);
    ids.add(24);
    queryVo.setIds(ids);

    List<User> list = userMapper.queryUserByIds(queryVo);

    for (User u : list) {
        System.out.println(u);
    }

    // mybatis和spring整合,整合以後,交給spring管理
    sqlSession.close();
}

 

八、關聯查詢

 8.1 一對一查詢

需求:查詢全部訂單信息,關聯查詢下單用戶信息。

sql語句:

SELECT o.id, o.user_id userId, o.number, o.createtime, u.username, u.address  FROM `order` o LEFT JOIN `user` u ON o.user_id = u.id

方法一:使用resultType

這裏咱們,繼承Order類編寫Order2User類做爲新的pojo類,此pojo類中新增長了訂單信息和用戶信息。這樣返回對象的時候,mybatis自動把用戶信息也注入進來了。

使用OrderMapper接口,並在OrderMapper.xml中添加對應的查詢語句,最後測試。

這裏咱們在sql語句中對數據庫字段的uer_id使用了別名userId,這樣就不須要使用resultMap來進行映射了。

方法二:使用resultMap

這裏直接對Oeder.java進行修改,添加一個User屬性,而後在OrderMapper.xml中創建對應的映射。

 

  8.2 一對多查詢

 需求:查詢全部用戶信息及用戶關聯的訂單信息

sql語句:

SELECT u.id, u.username, u.birthday, u.sex, u.address, o.id oid, o.number, o.createtime, o.note FROM `user` u LEFT JOIN `order` o ON u.id = o.user_id

這裏相似於上面的方法二。修改User類,在UserMapper.xml的配置文件中添加<resultMap>,而後編寫相應查詢語句,最後測試。

 

 

九、MyBatis整合Spring

 9.1 整合思路

一、SqlSessionFactory對象應該放到spring容器中做爲單例存在;

二、傳統dao的開發方式中,應該從spring容器中得到sqlsession對象;

三、Mapper代理形式中,應該從spring容器中直接得到mapper的代理對象;

四、數據庫的鏈接以及數據庫鏈接池事務管理都交給spring容器來完成。

 

 9.2 整合所需的jar包

Spring相關jar包:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>4.3.1.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>4.3.1.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <version>5.1.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>5.1.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>5.1.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.1.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
  <version>5.1.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>5.1.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-expression</artifactId>
  <version>5.1.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jdbc</artifactId>
  <version>5.1.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jms -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jms</artifactId>
  <version>5.1.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-messaging -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-messaging</artifactId>
  <version>5.1.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-tx</artifactId>
  <version>5.1.4.RELEASE</version>
</dependency>
Spring

MyBatis相關jar包:

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis</artifactId>
  <version>3.4.6</version>
</dependency>

Spring+mybatis的整合包:

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
  <groupId>org.mybatis</groupId>
   <artifactId>mybatis-spring</artifactId>
   <version>1.3.2</version>
</dependency>

Mysql的數據庫驅動jar包:

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.13</version>
</dependency>

數據庫鏈接池的jar包:

<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
  <groupId>com.mchange</groupId>
  <artifactId>c3p0</artifactId>
  <version>0.9.5.2</version>
</dependency>

 

 9.3 建立配置文件

 1) applicationContext.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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 引入JDBC配置文件 -->
    <context:property-placeholder location="jdbc.properties"/>

    <!-- 配置數據庫鏈接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 配置數據源 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 配置mybatis核心配置文件 -->
        <property name="configLocation" value="sqlMapConfig.xml"/>
    </bean>

</beans>
View Code

2) sqlMapConfig.xml

<?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>
        <!-- 2. 指定掃描包,會把包內全部的類都設置別名,別名的名稱就是類名,大小寫不敏感 -->
        <package name="com.panlei.pojo" />
    </typeAliases>

</configuration>
View Code

3) jdbc.properties 

jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/webuser?serverTimezone=GMT%2B8
jdbc.user=root
jdbc.password=panlei
View Code

4) log4j.properties

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
View Code  

 9.4 建立pojo

 

 9.5 Dao開發方式簡單使用

這裏的內容前面有所涉及,本次只講解關鍵的內容。

Dao接口與實現類具體代碼再也不展現,注意一點,在dao實現類中由於須要調用對應mapper.xml中的具體sql語句,也就須要SqlSession對象,由於咱們是MyBatis與Spring整合,因此咱們不須要本身去new一個對象了,前面咱們已經在applicationContext.xml中對 SqlSessionFactoryBean 進行了配置,並且在spring與mybaits整合的jar包中對這種必然會使用的操做抽象爲一個類:SqlSessionDaoSupport,咱們須要在具體的Dao實現類中繼承該類,而後使用其中的方法便可,具體以下圖:

還有就是編寫對應的mapper.xml文件,並在sqlMapConfig.xml中加載該文件,最後在applicationContext.xml配置Dao

而後運行測試

 

 9.6 Mapper代理形式

 這一部分的基礎知識在第4節也有講解,本次也只是講解重要的部分或者沒有涉及的部分。

首先仍是UserMapper接口與UserMapper.xml按規則對應,而後仍是講解一下applicationContext.xml中的配置。

第一種方式是爲每個Mapper接口配置一個<bean>

  用到的MapperFactoryBean也是屬於mybatis-spring整合jar包

 

運行測試

第二種方式是用掃描包的形式配置。第一種方式須要爲每個mapper配置一個<bean>,當數量太多時,顯得太麻煩。這裏能夠不注入SqlSessionFactoryBean,能夠自動注入

相關文章
相關標籤/搜索