天天看點

spring boot 和 mybatis 整合

1、前言

        之前有寫過 SSM(spring+springMVC+mybatis) 的整合文章,而如今随着微服務架構的盛行,并且 spring boot 這種約定大于配置的架構開發比 springMVC 更加簡潔和高效,是以趁着手頭有點空閑時間進行了 Spring Boot  和 MyBatis 的整合,期間也踩了不少坑,在此将過程記錄下來以可以幫助後來的同學。

2、環境

       · 開發工具:Intellij IDEA 2017

       · Spring Boot:1.5.7.RELEASE

       · JDK:1.8.0_161

       · Maven:3.3.9

       · MySQL:5.7系列

3、資料準備

CREATE TABLE `userinfo` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` varchar(32) NOT NULL,
  `user_name` varchar(130) NOT NULL,
  `age` int(11) NOT NULL,
  `gender` varchar(11) NOT NULL,
  `address` varchar(100) NOT NULL,
  `user_pass` varchar(132) NOT NULL COMMENT '使用者秘銀,進行md5加鹽處理',
  PRIMARY KEY (`id`),
  KEY `uid` (`user_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of userinfo
-- ----------------------------
INSERT INTO `userinfo` VALUES ('1', 'b6866b572db34900a75a57697f16fc01', '張三', '10', '男', 'string1', 'string1');
INSERT INTO `userinfo` VALUES ('2', '231a454d01f24cd292ed4b0a401233f2', '李四', '20', '男', 'string2', 'string2');
INSERT INTO `userinfo` VALUES ('3', '2831089e21634fb9b744475999a28bbe', '王五', '30', '女', 'string3', 'string3');
INSERT INTO `userinfo` VALUES ('4', '55677286ba754605ac585cdedc6bd943', '馬六', '40', '女', 'string4', 'string4');
INSERT INTO `userinfo` VALUES ('5', '8ea709e95d64472da917cc5916240ae8', '趙七', '50', '男', 'string5', 'string5');
INSERT INTO `userinfo` VALUES ('6', 'e793646a8b1745709f036e0ee2ed869e', '三八', '60', '男', 'string6', 'string6');
           

4、建立項目

      依次點選 File > New > Project....

spring boot 和 mybatis 整合

      點選 next 輸入 groupId 和 artifactId,然後選擇初始依賴配置,這裡選擇 web,mysql,Mybatis 三個:

spring boot 和 mybatis 整合

        建立完成的項目,我們在基礎上建立如下 package(bean,mapper,service,service.impl,controller,utils),配置檔案可以使用 properties 和 yml 兩種檔案,我們這裡删除自帶的 application.properties 檔案,建立 application.yml 檔案,這樣整個項目目錄結構以及初始 pom.xml 内容如下圖所示:

spring boot 和 mybatis 整合

5、使用Generator插件自動生成代碼

      mybatis 提供了自動生成與資料庫表對應實體、mapper、以及 xml檔案 的插件,這很大程度上節省了我們的開發時間,首先我們需要在 resources 檔案夾下建立 generatorConfig.xml,這是插件的核心配置,包含資料庫連接配接以及生成的實體、mapper存放位址等資訊,然後在 resources 檔案夾下建立 mapperXML 檔案夾(用來存放自動生成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>

    <!-- 資料庫驅動:選擇你的本地硬碟上面的資料庫驅動包-->
    <classPathEntry  location="D:\maven_repository\mysql\mysql-connector-java\5.1.44\mysql-connector-java-5.1.44.jar"/>
    <context id="DB2Tables"  targetRuntime="MyBatis3">

        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <!-- 是否去除自動生成的注釋 true:是 : false:否 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <!--資料庫連結URL,使用者名、密碼 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1/test"
                        userId="root" password="123456">
        </jdbcConnection>
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <!-- 生成模型的包名和位置-->
        <javaModelGenerator targetPackage="com.sailing.springbootmybatis.bean"
                            targetProject="D:\idea_workspace\springboot-mybatis\src\main\java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>

        <!-- 生成映射檔案的包名和位置-->
        <sqlMapGenerator targetPackage="mapperXML" targetProject="D:\idea_workspace\springboot-mybatis\src\main\resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>

        <!-- 生成DAO的包名和位置-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.sailing.springbootmybatis.mapper"
                             targetProject="D:\idea_workspace\springboot-mybatis\src\main\java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!-- 要生成的表 tableName是資料庫中的表名或視圖名 domainObjectName是實體類名-->
        <!-- 這裡用的通配符比對全部的表,另外所有表都有自動增長的id字段。如果不是所有表的配置都一樣,可以做針對性的配置。 -->
        <table tableName="%" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false"
               enableSelectByExample="false" selectByExampleQueryId="false">
            <generatedKey column="id" sqlStatement="Mysql"/>
        </table>
    </context>
</generatorConfiguration>
           

      然後在 pom.xml 檔案中找到 plugins節點,增加 mybatis generator 插件依賴,注意其中的 configurationFile 内容和上面建立的 generatorConfig.xml 路徑是對應的 。

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

      <!-- mybatis generator 自動生成代碼插件 -->
      <plugin>
         <groupId>org.mybatis.generator</groupId>
         <artifactId>mybatis-generator-maven-plugin</artifactId>
         <version>1.3.2</version>
         <configuration>
            <!-- 對應generator配置檔案的路徑 -->
            <configurationFile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile>
            <overwrite>true</overwrite>
            <verbose>true</verbose>
         </configuration>
      </plugin>
   </plugins>
</build>
           

      最後點選 Edit Configurations... 按鈕到添加指令視窗,點選左上角 + 按鈕找到 maven (如果沒有找到,點選最底下 xx items more...按鈕),輸入如下指令 Name:generator,Commond line:mybatis-generator:generate -e,點選 ok ,退出來以後點選運作就會自動生成代碼如下:

Userinfo.java

package com.sailing.springbootmybatis.bean;

public class Userinfo {
    private Integer id;

    private String userId;

    private String userName;

    private Integer age;

    private String gender;

    private String address;

    private String userPass;

    public Integer getId() {
        return id;
    }

    //setter getter ....
}
           

UserinfoMapper

package com.sailing.springbootmybatis.mapper;

import com.sailing.springbootmybatis.bean.Userinfo;

public interface UserinfoMapper {
    int deleteByPrimaryKey(Integer id);

    int insert(Userinfo record);

    int insertSelective(Userinfo record);

    Userinfo selectByPrimaryKey(Integer id);

    int updateByPrimaryKeySelective(Userinfo record);

    int updateByPrimaryKey(Userinfo record);
}
           

UserinfoMapper.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.sailing.springbootmybatis.mapper.UserinfoMapper" >
  <resultMap id="BaseResultMap" type="com.sailing.springbootmybatis.bean.Userinfo" >
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="user_id" property="userId" jdbcType="VARCHAR" />
    <result column="user_name" property="userName" jdbcType="VARCHAR" />
    <result column="age" property="age" jdbcType="INTEGER" />
    <result column="gender" property="gender" jdbcType="VARCHAR" />
    <result column="address" property="address" jdbcType="VARCHAR" />
    <result column="user_pass" property="userPass" jdbcType="VARCHAR" />
  </resultMap>
  <sql id="Base_Column_List" >
    id, user_id, user_name, age, gender, address, user_pass
  </sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    select 
    <include refid="Base_Column_List" />
    from userinfo
    where id = #{id,jdbcType=INTEGER}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
    delete from userinfo
    where id = #{id,jdbcType=INTEGER}
  </delete>
  <insert id="insert" parameterType="com.sailing.springbootmybatis.bean.Userinfo" >
    <selectKey resultType="java.lang.Integer" keyProperty="id" order="BEFORE" >
      SELECT LAST_INSERT_ID()
    </selectKey>
    insert into userinfo (id, user_id, user_name, 
      age, gender, address, 
      user_pass)
    values (#{id,jdbcType=INTEGER}, #{userId,jdbcType=VARCHAR}, #{userName,jdbcType=VARCHAR}, 
      #{age,jdbcType=INTEGER}, #{gender,jdbcType=VARCHAR}, #{address,jdbcType=VARCHAR}, 
      #{userPass,jdbcType=VARCHAR})
  </insert>
  <insert id="insertSelective" parameterType="com.sailing.springbootmybatis.bean.Userinfo" >
    <selectKey resultType="java.lang.Integer" keyProperty="id" order="BEFORE" >
      SELECT LAST_INSERT_ID()
    </selectKey>
    insert into userinfo
    <trim prefix="(" suffix=")" suffixOverrides="," >
      id,
      <if test="userId != null" >
        user_id,
      </if>
      <if test="userName != null" >
        user_name,
      </if>
      <if test="age != null" >
        age,
      </if>
      <if test="gender != null" >
        gender,
      </if>
      <if test="address != null" >
        address,
      </if>
      <if test="userPass != null" >
        user_pass,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      #{id,jdbcType=INTEGER},
      <if test="userId != null" >
        #{userId,jdbcType=VARCHAR},
      </if>
      <if test="userName != null" >
        #{userName,jdbcType=VARCHAR},
      </if>
      <if test="age != null" >
        #{age,jdbcType=INTEGER},
      </if>
      <if test="gender != null" >
        #{gender,jdbcType=VARCHAR},
      </if>
      <if test="address != null" >
        #{address,jdbcType=VARCHAR},
      </if>
      <if test="userPass != null" >
        #{userPass,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.sailing.springbootmybatis.bean.Userinfo" >
    update userinfo
    <set >
      <if test="userId != null" >
        user_id = #{userId,jdbcType=VARCHAR},
      </if>
      <if test="userName != null" >
        user_name = #{userName,jdbcType=VARCHAR},
      </if>
      <if test="age != null" >
        age = #{age,jdbcType=INTEGER},
      </if>
      <if test="gender != null" >
        gender = #{gender,jdbcType=VARCHAR},
      </if>
      <if test="address != null" >
        address = #{address,jdbcType=VARCHAR},
      </if>
      <if test="userPass != null" >
        user_pass = #{userPass,jdbcType=VARCHAR},
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.sailing.springbootmybatis.bean.Userinfo" >
    update userinfo
    set user_id = #{userId,jdbcType=VARCHAR},
      user_name = #{userName,jdbcType=VARCHAR},
      age = #{age,jdbcType=INTEGER},
      gender = #{gender,jdbcType=VARCHAR},
      address = #{address,jdbcType=VARCHAR},
      user_pass = #{userPass,jdbcType=VARCHAR}
    where id = #{id,jdbcType=INTEGER}
  </update>
</mapper>
           

6、配置檔案

       這裡我們沒有采用 spring boot 1.x 版本預設使用的 org.apache.tomcat.jdbc.pool.DataSource 資料源(spring boot 2.0 以後預設采用性能更好的 HikariCP 資料源 ),而是采用阿裡巴巴的 Druid 資料源-----官方文檔,是以需要在 pom.xml 中添加如下依賴 :

<!-- alibaba的druid資料庫連接配接池 -->
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid-spring-boot-starter</artifactId>
   <version>1.1.5</version>
</dependency> 
           

然後打開建立的 application.yml 檔案,配置如下内容:

server:
  port: 8088
  context-path: /sm
## 配置資料源相關資訊
spring:
  datasource:
    name: DBconfig
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql//127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
    druid:
      filters: stat
      maxActive: 20
      initialSize: 1
      maxWait: 60000
      minIdle: 1
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 300000
      validationQuery: select 'x'
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      poolPreparedStatements: true
      maxOpenPreparedStatements: 20

## 該配置節點為獨立的節點,有很多同學容易将這個配置放在spring的節點下,導緻配置無法被識别
mybatis:
  mapper-locations: classpath:mapperXML/*.xml  #注意:一定要對應mapper映射xml檔案的所在路徑
  config-location: classpath:MybatisConfig.xml # 注意: mybatis的配置檔案
  type-aliases-package: com.sailing.springbootmybatis.bean  # 注意:對應實體類的路徑
           

貼出 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>

   <groupId>com.sailing</groupId>
   <artifactId>springboot-mybatis</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>

   <name>springboot-mybatis</name>
   <description>Demo project for springboot-mybatis</description>

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

   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <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>1.3.2</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>
      </dependency>

      <!-- ps: 以下依賴是手動添加的 -->

      <!-- alibaba的druid資料庫連接配接池 -->
      <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>druid-spring-boot-starter</artifactId>
         <version>1.1.5</version>
      </dependency>

   </dependencies>

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

         <!-- mybatis generator 自動生成代碼插件 -->
         <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.2</version>
            <configuration>
               <!-- 對應generator配置檔案的路徑 -->
               <configurationFile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile>
               <overwrite>true</overwrite>
               <verbose>true</verbose>
            </configuration>
         </plugin>
      </plugins>
   </build>


</project>
           

7、編寫代碼

      接着來完善代碼,編寫如下 UserinfoService  UserinfoServiceImpl 和 UserinfoController 檔案,就寫了兩個業務層接口,一個根據id查找使用者,一個查詢所有使用者,内容如下:

package com.sailing.springbootmybatis.service;

import com.sailing.springbootmybatis.bean.Userinfo;

import java.util.List;

/**
 * @author baibing
 * @project: springboot-mybatis
 * @package: com.sailing.springbootmybatis.service
 * @Description: service 業務接口
 * @date 2018/9/12 09:52
 */
public interface UserinfoService {

    Userinfo findById(Integer id);

    List<Userinfo> findAllUsers();
}
           
package com.sailing.springbootmybatis.service.impl;

import com.sailing.springbootmybatis.bean.Userinfo;
import com.sailing.springbootmybatis.mapper.UserinfoMapper;
import com.sailing.springbootmybatis.service.UserinfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author baibing
 * @project: springboot-mybatis
 * @package: com.sailing.springbootmybatis.service.impl
 * @Description: service實作類
 * @date 2018/9/12 10:03
 */
@Service
@Transactional
public class UserinfoServiceImpl implements UserinfoService {

    @Autowired
    private UserinfoMapper userinfoMapper;

    @Override
    public Userinfo findById(Integer id) {
        return userinfoMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<Userinfo> findAllUsers() {
        return userinfoMapper.selectAllUsers();
    }
}
           
package com.sailing.springbootmybatis.controller;

import com.sailing.springbootmybatis.bean.Userinfo;
import com.sailing.springbootmybatis.service.UserinfoService;
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.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author baibing
 * @project: springboot-mybatis
 * @package: com.sailing.springbootmybatis.controller
 * @Description: Userinfo controller 控制層
 * @date 2018/9/12 10:07
 */
@RestController
public class UserinfoController {

    @Autowired
    private UserinfoService userinfoService;

    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    public Userinfo getUser(@PathVariable(value = "id") Integer id){
        return userinfoService.findById(id);
    }

    @RequestMapping(value = "/users", method = RequestMethod.GET)
    public List<Userinfo> getAllUsers(){
        return userinfoService.findAllUsers();
    }
}
           

此處需要注意的是,需要在 serviceImpl 中注入 mapper 接口,在 controller 層中注入 service 接口。

8、啟動類

        啟動類需要注意的是,官方建議放到根目錄,以便于可以自動掃描所有的 mapper、service、controller(這樣我們可以不用寫 @ComponentScan  和 @MapperScan 注解)。如果和我一樣建立一個application包存放啟動類的話,需要添加注解 @ComponentScan 和 @MapperScan 來手動指定要掃描的包,前一個是掃描 service 和 controller 的,後一個掃描 mapper 檔案的:

package com.sailing.springbootmybatis.application;

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

/**
 * @author baibing
 * @project: springboot-mybatis
 * @package: com.sailing.springbootmybatis
 * @Description: 主項目的啟動類    注意:1.官方建議将此類放到主目錄下,以便能掃描到 mapper、service 和 controller
 *                                     2.如果沒有按照上面配置,啟動項目會報注解找不到相關class錯誤,解決方法:是在
 *                                       啟動類上面增加 @ComponentScan(掃描所有controller和 service 以及 Component)
 *                                       和 @MapperScan(掃描所有mapper) 兩個注解也可以解決,但還是建議按照第一種方式。
 * @date 2018/9/12 10:07
 */
@ComponentScan(value = {"com.sailing.springbootmybatis.*"})
@MapperScan(value = {"com.sailing.springbootmybatis.mapper"})
@SpringBootApplication
public class SpringbootMybatisApplication {

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

}
           

       完成後我們運作項目,這裡使用 Postman 進行測試,輸入 localhost:8088/sm/users 通路查找所有使用者接口,可以看到接口正常運作并傳回結果集:

spring boot 和 mybatis 整合

        也可以通路:http://127.0.0.1:8088/sm/druid/webapp.html 可以檢視Druid 監控資訊,包含資料源以及sql監控等資訊。

spring boot 和 mybatis 整合

9、結束

       到這裡,Spring boot 整合 Mybatis 完成!不足之處,歡迎大家留言指正~~~,

       項目下載下傳位址:https://download.csdn.net/download/white_ice/10662376

繼續閱讀