MyBatis初級實戰之一:Spring Boot整合

程式設計師欣宸發表於2021-01-15

歡迎訪問我的GitHub

https://github.com/zq2599/blog_demos

內容:所有原創文章分類彙總及配套原始碼,涉及Java、Docker、Kubernetes、DevOPS等;

MyBatis初級實戰

《MyBatis初級實戰》系列旨在通過一系列編碼實戰,和讀者一起掌握MyBatis的基本用法,幫助初學者快速運用MyBatis參與實際開發;

聚焦MyBatis

《MyBatis初級實戰》面向的是對MyBatis有興趣的讀者,向讀者們提供可用的方案和程式碼,這裡不是比較Hibernate、sqltoy-orm的地方,作者也十分認可這些ORM框架,但《MyBatis初級實戰》不參與比較;

關於MyBatis

引自官方:MyBatis 是一款優秀的持久層框架,它支援自定義 SQL、儲存過程以及高階對映。MyBatis 免除了幾乎所有的 JDBC 程式碼以及設定引數和獲取結果集的工作。MyBatis 可以通過簡單的 XML 或註解來配置和對映原始型別、介面和 Java POJO(Plain Old Java Objects,普通老式 Java 物件)為資料庫中的記錄。

實戰環境

《MyBatis初級實戰》系列的環境資訊如下:

  1. JDK:1.8.0_181
  2. mybatis-spring-boot-starter:2.1.3(對應的MyBatis:3.5.5)
  3. Spring Boot:2.3.2.RELEASE
  4. MySQL:5.7.29
  5. 實戰環境:win10
  6. 開發工具:IntelliJ IDEA 2019.2.1 (Ultimate Edition)

Spring Boot整合MyBatis常規步驟概覽

Spring Boot整合MyBatis的常規步驟如下:

  1. maven中新增mybatis-spring-boot-starter的依賴;
  2. Spring Boot的配置中指定MyBatis配置檔案的位置;
  3. Spring Boot的配置中指定MyBatis對映檔案的位置;
  4. 新增MyBatis配置檔案,後續MyBatis的常規配置集中在此;
  5. 對映檔案xxxMapper.xml及其對應的介面檔案;
  6. 業務程式碼中,Autowired註解修飾介面檔案並使用;
  • 接下來開始實戰,我們們先把資料準備好;

準備資料

  1. 請您自行準備好MySQL服務,我這邊MySQL是部署在docker上的,可以參考《群暉DS218+部署mysql》
  2. 建立名為mybatis的資料庫;
  3. mybatis資料庫下執行以下SQL,即可建立本次實戰所需資料:
USE mybatis;

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
  `id` int(32) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL,
  `age` int(32) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `log`;

CREATE TABLE `log` (
  `id` int(32) NOT NULL AUTO_INCREMENT,
  `user_id` int(32),
  `action` varchar(255) NOT NULL,
  `create_time` datetime not null,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

INSERT INTO mybatis.user (id, name, age) VALUES (3, 'tom', 11);
INSERT INTO mybatis.log (id, user_id, action, create_time) VALUES (3, 3, 'read book', '2020-08-07 08:18:16');

原始碼下載

  1. 如果您不想編碼,可以在GitHub下載所有原始碼,地址和連結資訊如下表所示(https://github.com/zq2599/blog_demos):
名稱 連結 備註
專案主頁 https://github.com/zq2599/blog_demos 該專案在GitHub上的主頁
git倉庫地址(https) https://github.com/zq2599/blog_demos.git 該專案原始碼的倉庫地址,https協議
git倉庫地址(ssh) git@github.com:zq2599/blog_demos.git 該專案原始碼的倉庫地址,ssh協議
  1. 這個git專案中有多個資料夾,本章的應用在mybatis資料夾下,如下圖紅框所示:
    在這裡插入圖片描述

關於父子工程

為了整個系列的程式碼好管理,我這邊用maven建立的是父子工程,如果您只要子工程,不需要父子結構,要對子工程的pom.xml做以下調整:

  1. parent節點原本如下:
<parent>
        <groupId>com.bolingcavalry</groupId>
        <artifactId>mybatis</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

請替換成以下內容(也就是直接用>spring-boot-starter-parent作為父工程):

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
  1. 子工程種的dependency節點中沒有version子節點,這些都放在父工程的dependencyManagement中統一管理了,請您將version新增到子工程的各個dependency節點:

在這裡插入圖片描述

  • 接下來開始編碼

建立父工程

建立名為mybatis的maven工程,pom.xml內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<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>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.bolingcavalry</groupId>
    <artifactId>mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <modules>
        <module>simple</module>
    </modules>

    <dependencyManagement>

        <dependencies>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.3</version>
            </dependency>
        </dependencies>

    </dependencyManagement>

</project>
  • 至此,準備工作算是全部完成了,接下來我們們開始建立一個典型的Spring Boot整合MyBatis的專案吧;

Spring Boot整合MyBatis

  1. 在父工程mybatis之下新建名為simple的Spring Boot子工程,其pom.xml內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.bolingcavalry</groupId>
        <artifactId>mybatis</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <groupId>com.bolingcavalry</groupId>
    <artifactId>simple</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>simple</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  1. Spring Boot配置檔案是simple/src/main/resources/application.yml,內容如下:
server:
  port: 8080

spring:
  # 資料來源
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://192.168.50.43:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver

# mybatis配置
mybatis:
  # 配置檔案所在位置
  config-location: classpath:mybatis-config.xml
  # 對映檔案所在位置
  mapper-locations: classpath:mappers/*Mapper.xml

# 日誌配置
logging:
  level:
    root: INFO
    com:
      bolingcavalry:
        simple:
          mapper: debug
  1. 新建user表對應的實體類User.java:
package com.bolingcavalry.simple.entity;

/**
 * @Description: 實體類
 * @author: willzhao E-mail: zq2599@gmail.com
 * @date: 2020/8/4 8:24
 */
public class User {
    private Integer id;
    private String name;
    private Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  1. 新建log表對應的實體類Log.java:
package com.bolingcavalry.simple.entity;

import java.sql.Date;

/**
 * @Description: 實體類
 * @author: willzhao E-mail: zq2599@gmail.com
 * @date: 2020/8/4 8:24
 */
public class Log {
    private Integer id;
    private Integer userId;
    private String action;
    private Date createTime;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getAction() {
        return action;
    }

    public void setAction(String action) {
        this.action = action;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return "Log{" +
                "id=" + id +
                ", userId=" + userId +
                ", action='" + action + '\'' +
                ", createTime=" + createTime +
                '}';
    }
}
  1. 接下來會新建三個配置檔案,先來看下它們的位置,以免後面放錯地方引起不必要的麻煩:

在這裡插入圖片描述
6. application.yml所在目錄下,新增名為mybatis-config.xml的檔案,這是mybatis的配置檔案,本例很簡單隻有一個配置,內容如下:

<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <!-- 對映檔案中的類不用寫全路徑了-->
        <package name="com.bolingcavalry.simple.entity"/>
    </typeAliases>
</configuration>
  1. resources/mappers目錄下,新增名為UserMapper.xml的檔案,和user表相關的查詢都在此,本文只有一個查詢user表的操作,注意下文中的resultType等於User,這裡沒有寫User類的完整路徑,是因為前面mybatis-config.xml檔案中配置了typeAliases的package節點的緣故:
<?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.bolingcavalry.simple.mapper.UserMapper">
    <select id="sel" parameterType="int" resultType="User">
        select * from user where id = #{id}
    </select>
</mapper>
  1. 再新增LogMapper.xml,如下所示,log表中的user_id欄位在Log.java中沒有同名的欄位,因此要新增resultMap來建立資料庫和實體類的欄位對映關係,再在select節點用上這個關係,注意要用resultMap屬性(UserMapper.xml中用的是resultType):
<?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.bolingcavalry.simple.mapper.LogMapper">

    <resultMap id="logResultMap" type="Log">
        <id property="id" column="id" />
        <result column="user_id" jdbcType="INTEGER" property="userId" />
        <result column="action" jdbcType="VARCHAR" property="action" />
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    </resultMap>

    <select id="sel" parameterType="int" resultMap="logResultMap">
        select * from log where id = #{id}
    </select>
</mapper>
  1. 接下來是業務要用到的介面檔案,第一個是UserMapper.java:
package com.bolingcavalry.simple.mapper;

import com.bolingcavalry.simple.entity.User;
import org.springframework.stereotype.Repository;

@Repository
public interface UserMapper {
    User sel(int id);
}
  1. 第二個是LogMapper.java:
package com.bolingcavalry.simple.mapper;

import com.bolingcavalry.simple.entity.Log;
import org.springframework.stereotype.Repository;

@Repository
public interface LogMapper {
    Log sel(int id);
}
  1. 上述兩個類都使用了Repository註解,作用是避免在編碼過程中,IDEA給出紅線提示,如下圖:

在這裡插入圖片描述
12. 對映配置完畢,接下來就可以在應用中使用了,先為user做一個service類UserService.java,裡面通過Autowired註解注入UserMapper的實現:

package com.bolingcavalry.simple.service;

import com.bolingcavalry.simple.entity.User;
import com.bolingcavalry.simple.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @Autowired
    UserMapper userMapper;

    public User sel(int id){
        return userMapper.sel(id);
    }
}
  1. 再為log做service類LogService.java:
package com.bolingcavalry.simple.service;

import com.bolingcavalry.simple.entity.Log;
import com.bolingcavalry.simple.mapper.LogMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class LogService {
    @Autowired
    LogMapper logMapper;

    public Log sel(int id){
        return logMapper.sel(id);
    }
}
  1. 最後是響應web請求的controller類,第一個是UserController.java:
package com.bolingcavalry.simple.controller;

import com.bolingcavalry.simple.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("user/{id}")
    public String GetUser(@PathVariable int id){
        return userService.sel(id).toString();
    }
}
  1. 然後是LogController.java:
package com.bolingcavalry.simple.controller;

import com.bolingcavalry.simple.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LogController {
    @Autowired
    private LogService logService;

    @RequestMapping("log/{id}")
    public String log(@PathVariable int id){
        return logService.sel(id).toString();
    }
}
  1. 最後是引導類SimpleApplication.java,注意MapperScan註解會自動掃描包路徑下的所有介面,這樣UserMapper和LogMapper就不用加Mapper註解了:
package com.bolingcavalry.simple;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.bolingcavalry.simple.mapper")
public class SimpleApplication {

    public static void main(String[] args) {
        SpringApplication.run(SimpleApplication.class, args);
    }
}
  • 至此,編碼完成,可以啟動驗證了;

驗證

  1. 啟動SpringBoot應用的方式有兩種,最簡單的辦法是再IDEA中直接啟動,如下圖:

在這裡插入圖片描述

  1. 第二種是simple的目錄下執行mvn clean package -U,就會在target目錄得到檔案simple-0.0.1-SNAPSHOT.jar,再執行java -jar simple-0.0.1-SNAPSHOT.jar即可啟動;
  2. 在瀏覽器訪問http://localhost:8080/user/3,可以得到user表的查詢結果:

在這裡插入圖片描述
4. 訪問http://localhost:8080/log/3,可以得到log表的查詢結果:

在這裡插入圖片描述
5. 在控制檯可以看到日誌如下所示,這是我們開發期間除錯問題的重要線索:

在這裡插入圖片描述
至此,入門級SpringBoot整合MyBatis的實戰就完成了,接下來的系列內容會有更多實戰,我們們一起來學習和掌握MyBatis的基本用法;

你不孤單,欣宸原創一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 資料庫+中介軟體系列
  6. DevOps系列

歡迎關注公眾號:程式設計師欣宸

微信搜尋「程式設計師欣宸」,我是欣宸,期待與您一同暢遊Java世界...

https://github.com/zq2599/blog_demos

相關文章