Spring Boot整合MyBatis連接數據庫

Java EE 目錄:https://blog.csdn.net/dkbnull/article/details/87932809
Spring Boot 專欄:https://blog.csdn.net/dkbnull/category_9278145.html
Spring Cloud 專欄:https://blog.csdn.net/dkbnull/category_9287932.html

0. 開發環境

  • IDE:IntelliJ IDEA 2017.1 x64
  • jdk:1.8.0_91
  • Spring Boot:2.1.1.RELEASE
  • Maven:3.3.9
  • MySQL:5.7.13

1. 引入依賴

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

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>8.0.15</version>
	<scope>runtime</scope>
</dependency>

這裏,如果使用的 MySQL 是 8.X版本的話,mysql-connector-java 版本必須是 8.0以上,否則會報錯:

java.sql.SQLException: Unable to load authentication plugin 'caching_sha2_password'.

2. 引入數據源

這裏根據個人習慣使用 properties 或 yml 文件配置,本項目使用的是更爲簡潔的 yml 配置文件。
刪除原來的 application.properties ,新建 application.yml。

application.yml 增加如下配置信息

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/test?serverTimezone=GMT%2B8
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

這裏,如果使用的 mysql-connector-java 是5.X版本的話,driver-class-name 可以直接省略使用默認,或者配置爲 com.mysql.jdbc.Driver

到這裏,Spring Boot就可以訪問數據庫了,我們來做下測試。


3. 測試

3.1 新建數據庫表

CREATE SCHEMA `test` ;

CREATE TABLE `test`.`test` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`id`));

INSERT INTO `test`.`test` (`name`) VALUES ('張三');
INSERT INTO `test`.`test` (`name`) VALUES ('李四');
INSERT INTO `test`.`test` (`name`) VALUES ('王五');
INSERT INTO `test`.`test` (`name`) VALUES ('週六');

3.2 創建實體

package cn.wbnull.springbootdemo.model;

public class TestModel {

    private int id;
    private String name;

    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;
    }
}

3.3 DAO層

package cn.wbnull.springbootdemo.dao;

import cn.wbnull.springbootdemo.model.TestModel;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper
public interface TestMapper {

    @Select("select id,name from test")
    List<TestModel> select();

    @Insert("insert into test(name) values(#{name})")
    int insert(@Param("name") String name);
}

3.4 Service層

package cn.wbnull.springbootdemo.service;

import cn.wbnull.springbootdemo.dao.TestMapper;
import cn.wbnull.springbootdemo.model.TestModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class MySQLTestService {

    @Autowired
    private TestMapper testMapper;  //這裏會有報錯,不用管

    public List<TestModel> select() {
        return testMapper.select();
    }

    public int insert(String name) {
        return testMapper.insert(name);
    }
}

這裏使用 @Autowired 自動裝配TestMapper時會有報錯,原因是TestMapper使用了@Mapper註解,idea不能把@Mapper註解的TestMapper識別爲Bean,但實際運行時@Mapper會被Spring識別爲Bean,自動裝配不會出錯。所以這裏的報錯可以不用在意。
但如果看着代碼中有報錯很不順眼,可以在TestMapper類增加@Repository註解,標註該類爲DAO組件。


3.5 Controller層

package cn.wbnull.springbootdemo.controller;

import cn.wbnull.springbootdemo.model.TestModel;
import cn.wbnull.springbootdemo.service.MySQLTestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@Scope("prototype")
@RequestMapping("/mysql/test")
public class MySQLTestController {

    @Autowired
    private MySQLTestService mySQLTestService;

    @PostMapping(value = "/select")
    public List<TestModel> select() throws Exception {
        return mySQLTestService.select();
    }

    @PostMapping(value = "/insert")
    public int insert(@RequestParam(value = "name") String name) throws Exception {
        return mySQLTestService.insert(name);
    }
}

3.6 測試

使用Postman進行測試,輸出結果如下

3.6.1 select

在這裏插入圖片描述

3.6.2 insert

在這裏插入圖片描述
Postman接收到輸出爲1,表示成功,我們去查下數據庫
在這裏插入圖片描述
數據成功插入。


4. MyBatis映射文件

以上,我們訪問數據庫時,SQL語句還是寫死在代碼裏面,處理起來並沒有很方便。通常,我們把SQL語句與代碼分離,使用MyBatis映射文件方式來訪問數據庫。

4.1 MyBatis配置

我們在resources文件夾下新建mapper文件夾,用於存放MyBatis映射文件
在這裏插入圖片描述
application.yml 增加MyBatis配置信息

mybatis:
  mapper-locations: classpath:mapper/*.xml  #對應mapper映射xml文件所在路徑
  type-aliases-package: cn.wbnull.springbootdemo.model  #對應實體類路徑

完整配置如下,注意spring與mybatis都是根節點

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/test?serverTimezone=GMT%2B8
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
#
mybatis:
  mapper-locations: classpath:mapper/*.xml  #對應mapper映射xml文件所在路徑
  type-aliases-package: cn.wbnull.springbootdemo.model  #對應實體類路徑

4.2 DAO層

我們創建一個新的DAO類

package cn.wbnull.springbootdemo.dao;

import cn.wbnull.springbootdemo.model.TestModel;

import java.util.List;

public interface TestMapperV2 {

    List<TestModel> select();

    int insert(TestModel testModel);
}

4.3 創建MyBatis映射文件

resources/mapper下新建映射文件 TestMapper.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="cn.wbnull.springbootdemo.dao.TestMapperV2">
    <resultMap id="BaseResultMap" type="cn.wbnull.springbootdemo.model.TestModel">
        <id column="id" property="id" jdbcType="INTEGER"/>
        <result column="name" property="name" jdbcType="VARCHAR"/>
    </resultMap>
    <sql id="Base_Column_List">
        id, name
    </sql>
    <select id="select" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from test
    </select>
    <insert id="insert" parameterType="cn.wbnull.springbootdemo.model.TestModel">
        insert into test (id, name
        )
        values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}
        )
    </insert>
</mapper>

這裏着重注意這幾點

1、<mapper namespace=“cn.wbnull.springbootdemo.dao.TestMapperV2”> namespace 一定要對應自己dao包所在的包路徑,對應我們需要匹配的dao層類

2、<resultMap id=“BaseResultMap” type=“cn.wbnull.springbootdemo.model.TestModel”> type 一定要對應我們需要匹配的實體類

3、 <id column=“id” property=“id” jdbcType=“INTEGER”/>

​ <result column=“name” property=“name” jdbcType=“VARCHAR”/>

對應數據庫表的字段

4、<select id=“select” resultMap=“BaseResultMap”>

​ select <include refid=“Base_Column_List”/> from test

​ </select>

<select> 表示這是一條查詢語句, id=“select” 一定要與dao層需要匹配的方法名一致,resultMap 表示對應的返回值類型

5、<insert id=“insert” parameterType=“cn.wbnull.springbootdemo.model.TestModel”> parameterType表示對應的輸入參數類型

4.4 Service層

創建一個新的Service類

package cn.wbnull.springbootdemo.service;

import cn.wbnull.springbootdemo.dao.TestMapperV2;
import cn.wbnull.springbootdemo.model.TestModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class MySQLTestServiceV2 {

    @Autowired
    private TestMapperV2 testMapperV2;  //這裏會有報錯,不用管

    public List<TestModel> select() {
        return testMapperV2.select();
    }

    public int insert(int id, String name) {
        TestModel testModel = new TestModel();
        testModel.setId(id);
        testModel.setName(name);

        return testMapperV2.insert(testModel);
    }
}

4.5 Controller層

創建一個新的Controller類

package cn.wbnull.springbootdemo.controller;

import cn.wbnull.springbootdemo.model.TestModel;
import cn.wbnull.springbootdemo.service.MySQLTestServiceV2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@Scope("prototype")
@RequestMapping("/mysql/test")
public class MySQLTestControllerV2 {

    @Autowired
    private MySQLTestServiceV2 mySQLTestServiceV2;

    @PostMapping(value = "/selectV2")
    public List<TestModel> select() throws Exception {
        return mySQLTestServiceV2.select();
    }

    @PostMapping(value = "/insertV2")
    public int insert(@RequestParam(value = "id") int id,
                      @RequestParam(value = "name") String name) throws Exception {
        return mySQLTestServiceV2.insert(id, name);
    }
}

4.6 項目啓動類

增加@MapperScan(“cn.wbnull.springbootdemo.dao”),對應DAO層的包名

package cn.wbnull.springbootdemo;

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

@SpringBootApplication
@MapperScan("cn.wbnull.springbootdemo.dao")
public class SpringBootDemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootDemoApplication.class, args);
	}
}

4.7 測試

4.7.1 select

在這裏插入圖片描述

4.7.2 insert

在這裏插入圖片描述
Postman接收到輸出爲1,表示成功,我們去查下數據庫
在這裏插入圖片描述
數據成功插入


截至這裏,Spring Boot已成功整合MyBatis並連接上了數據庫,且測試正常。

但我們實際開發過程中,如果存在大量數據庫表,那我們就需要創建大量的實體類、DAO層、映射文件,工作量較大。我們使用mybatis generator來自動生成代碼。

5. Generator

5.1 新建數據庫表

我們先新建一個數據庫表,便於一會自動生成代碼使用

CREATE TABLE `test`.`testv2` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(45) NOT NULL,
  `password` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`id`));

5.2 Generator配置文件

在resources文件夾下新建generator文件夾,新建generatorConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!--數據庫驅動,選擇本地硬盤上的數據庫驅動包,建議與pom.xml引入的jar包版本相同-->
    <classPathEntry
            location="D:\Program Files\Maven\repository\mysql\mysql-connector-java\8.0.15\mysql-connector-java-8.0.15.jar"/>
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <!--是否去除自動生成的註釋,true:是  false:否-->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <!--數據庫驅動類、鏈接url、用戶名、密碼,與application.yml配置相同即可-->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://127.0.0.1:3306/test?serverTimezone=GMT%2B8"
                        userId="root"
                        password="root">
        </jdbcConnection>

        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <!--生成實體類的包名和位置-->
        <javaModelGenerator targetPackage="cn.wbnull.springbootdemo.model"
                            targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>

        <!--生成映射文件的包名和位置-->
        <sqlMapGenerator targetPackage="mapper"
                         targetProject="src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>

        <!--生成DAO的包名和位置-->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="cn.wbnull.springbootdemo.dao"
                             targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!--需要自動生成代碼的數據庫表
         tableName表示數據庫中的表名或視圖名 domainObjectName表示實體類名-->
        <table tableName="testv2" domainObjectName="TestV2"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>
    </context>
</generatorConfiguration>

5.3 引入依賴

<plugin>
	<groupId>org.mybatis.generator</groupId>
	<artifactId>mybatis-generator-maven-plugin</artifactId>
	<version>1.3.2</version>
	<configuration>
		<configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
		<overwrite>true</overwrite>
		<verbose>true</verbose>
	</configuration>
</plugin>

5.4 Generator配置

1、Run --> Edit Configurations…
在這裏插入圖片描述
2、增加Maven配置
在這裏插入圖片描述
3、增加Generator配置 (mybatis-generator:generate -e),OK
在這裏插入圖片描述
4、運行
在這裏插入圖片描述
生成代碼如下。這裏我們運行成功後,同一個表,不要運行多次,否則mapper映射文件中會生成多次的代碼。
在這裏插入圖片描述

package cn.wbnull.springbootdemo.model;

public class TestV2 {
    private Integer id;

    private String username;

    private String password;

    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 == null ? null : username.trim();
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password == null ? null : password.trim();
    }
}
package cn.wbnull.springbootdemo.dao;

import cn.wbnull.springbootdemo.model.TestV2;

public interface TestV2Mapper {
    int insert(TestV2 record);

    int insertSelective(TestV2 record);
}
<?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="cn.wbnull.springbootdemo.dao.TestV2Mapper" >
  <resultMap id="BaseResultMap" type="cn.wbnull.springbootdemo.model.TestV2" >
    <result column="id" property="id" jdbcType="INTEGER" />
    <result column="username" property="username" jdbcType="VARCHAR" />
    <result column="password" property="password" jdbcType="VARCHAR" />
  </resultMap>
  <insert id="insert" parameterType="cn.wbnull.springbootdemo.model.TestV2" >
    insert into testv2 (id, username, password
      )
    values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}
      )
  </insert>
  <insert id="insertSelective" parameterType="cn.wbnull.springbootdemo.model.TestV2" >
    insert into testv2
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        id,
      </if>
      <if test="username != null" >
        username,
      </if>
      <if test="password != null" >
        password,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        #{id,jdbcType=INTEGER},
      </if>
      <if test="username != null" >
        #{username,jdbcType=VARCHAR},
      </if>
      <if test="password != null" >
        #{password,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>
</mapper>

5.5 測試

5.5.1 Service層

package cn.wbnull.springbootdemo.service;

import cn.wbnull.springbootdemo.dao.TestV2Mapper;
import cn.wbnull.springbootdemo.model.TestV2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MySQLTestV2Service {

    @Autowired
    private TestV2Mapper testV2Mapper;  //這裏會有報錯,不用管

    public int insert(int id, String username, String password) {
        TestV2 testV2 = new TestV2();
        testV2.setId(id);
        testV2.setUsername(username);
        testV2.setPassword(password);

        return testV2Mapper.insert(testV2);
    }
}

5.5.1 Controller層

package cn.wbnull.springbootdemo.controller;

import cn.wbnull.springbootdemo.service.MySQLTestV2Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Scope("prototype")
@RequestMapping("/mysql/testv2")
public class MySQLTestV2Controller {

    @Autowired
    private MySQLTestV2Service mySQLTestV2Service;

    @PostMapping(value = "/insert")
    public int insert(@RequestParam(value = "id") int id,
                      @RequestParam(value = "username") String username,
                      @RequestParam(value = "password") String password
    ) throws Exception {
        return mySQLTestV2Service.insert(id, username, password);
    }
}

5.5.2 insert

在這裏插入圖片描述
Postman接收到輸出爲1,表示成功,我們去查下數據庫
在這裏插入圖片描述
數據成功插入


這樣,對於大量的數據庫表,我們就可以使用Generator來生成基本的代碼,然後自己再添加其他所需要的代碼即可。




GitHub:https://github.com/dkbnull/SpringBootDemo
微信:https://mp.weixin.qq.com/s/TVtmbSBrctv9R9EucIggYg
微博:https://weibo.com/ttarticle/p/show?id=2309404339889012367676
知乎:https://zhuanlan.zhihu.com/p/95635187





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章