SpringBoot2 | 第八篇:整合Mybatis

springboot终于迎来了2.0版本,很多新的特性让springboot更加强大,之前使用1.5.6版本整合了Mybatis,现在2.0版本就已经不适用了,所以,在摸索中搭建了2.0版本整合Mybatis

[TOC]

环境/版本一览:

  • 开发工具:Intellij IDEA 2018.2.2
  • springboot: 2.0.5.RELEASE
  • jdk:1.8.0_171
  • maven:3.3.9
  • mybatis:1.3.2
  • pagehelper:1.2.5

额外功能:

  • PageHelper 分页插件

开始搭建:

1、创建项目:

1538643571840

1538643610385

添加基础的依赖:

1538643637531

2、依赖文件:

按照pom文件补齐需要的依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?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.fatal</groupId>
<artifactId>chapter8</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>chapter8</name>
<description>Spring Boot2 | 第八篇: 整合 Mybatis</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.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.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
</dependencies>

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

3、项目启动类:(加上Mapper扫描)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.fatal;

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

@SpringBootApplication
@MapperScan("com.fatal.mapper") // 扫描指定包下的所有mapper接口
public class Chapter8Application {

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

注意:@MapperScan("com.fatal.mapper") 这个注解非常的关键,这个对应了项目中 mapper(dao)所对应的包路径,很多同学就是这里忘了加导致异常的

4、application.yml:

可以根据个人使用习惯选择使用properties或者yml文件,本项目使用的是yml配置文件,所以把原本application.properties删除,创建一个application.yml文件

在resource文件夹下创建application.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
server:
port: 8080

spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
# 基本属性 allowMultiQueries:设置为true后,数据库那边才允许你批量更新。编码属性设置了存储数据到数据库才不会是乱码
url: jdbc:mysql://localhost:3306/chapter8?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=UTC&useSSL=false
username: root
password: 123456
# 下面为连接池的补充设置,应用到上面所有数据源中
hikari:
# 表示连接池的用户定义名称,主要显示在日志记录和JMX管理控制台中,以标识池和池配置。
pool-name: HikariPool
# 控制客户端(即您)等待池中连接的最大毫秒数。如果在没有连接可用的情况下超过此时间,则将抛出SQLException。最低可接受的连接超时为250毫秒。 默认值:30000(30秒)
connection-timeout: 3000
# 控制允许连接在池中空闲的最长时间。默认值:600000(10分钟)
idle-timeout: 600000
# 控制池中连接的最长生命周期。默认值:1800000(30分钟)
max-lifetime: 1800000

mybatis:
mapper-locations: classpath:mapper/*.xml # 注意:一定要对应 mapper 映射xml文件的所在路径
type-aliases-package: com.fatal.entity # 注意:对应实体类的路径
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 可以自控制台上输出 sql 语句

#pagehelper
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql

5、创建数据库和数据表

1
2
3
4
5
6
7
8
9
10
11
12
13
DROP TABLE IF EXISTS `user`;`chapter8`

CREATE TABLE `user` (
`userId` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(255) NOT NULL,
`password` VARCHAR(255) NOT NULL,
`phone` VARCHAR(255) NOT NULL,
PRIMARY KEY (`userId`)
) ENGINE=INNODB AUTO_INCREMENT=1003 DEFAULT CHARSET=utf8;

/*Data for the table `user` */

INSERT INTO `user`(`userId`,`userName`,`password`,`phone`) VALUES (1000,'石原里美','123456','132123123');

6、创建实体类:User.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.fatal.entity;

import lombok.Data;

/**
* @author: Fatal
* @date: 2018/10/4 0004 17:05
*/
@Data
public class User {

private Integer id;

private String username;

private String password;

private String phone;

}

7、创建 Mapper 接口:IUserMapper.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.fatal.mapper;

import com.fatal.entity.User;

import java.util.List;

/**
* User 映射接口
* @author: Fatal
* @date: 2018/10/4 0004 17:05
*/
public interface IUserMapper {

Integer insert(User record);

List<User> selectUsers();

}

8、创建mybatis映射文件: UserMapper.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?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.fatal.mapper.IUserMapper">

<sql id="BASE_TABLE">
user
</sql>

<sql id="BASE_COLUMN">
id,username,password,phone
</sql>

<insert id="insert" parameterType="com.fatal.entity.User">
INSERT INTO
<include refid="BASE_TABLE"/>
<trim prefix="(" suffix=")" suffixOverrides=",">
username,password,
<if test="phone != null">
phone,
</if>
</trim>
<trim prefix="VALUES(" suffix=")" suffixOverrides=",">
#{username, jdbcType=VARCHAR},#{password, jdbcType=VARCHAR},
<if test="phone != null">
#{phone, jdbcType=VARCHAR},
</if>
</trim>
</insert>

<select id="selectUsers" resultType="com.fatal.entity.User">
SELECT
<include refid="BASE_COLUMN"/>
FROM
<include refid="BASE_TABLE"/>
</select>

</mapper>

注意: 一定要对应自己mapper所在的包路径

9、创建Service

IUserService:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.fatal.service;

import com.fatal.entity.User;
import com.github.pagehelper.PageInfo;

/**
* User 服务
* @author: Fatal
* @date: 2018/10/4 0004 17:09
*/
public interface IUserService {

Integer addUser(User user);

PageInfo<User> findAllUser(int pageNum, int pageSize);

}

UserServiceImpl:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.fatal.service.impl;

import com.fatal.entity.User;
import com.fatal.mapper.IUserMapper;
import com.fatal.service.IUserService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
* User 服务实现
* @author: Fatal
* @date: 2018/10/4 0004 17:10
*/
@Service
public class UserServiceImpl implements IUserService {

@Autowired
private IUserMapper userMapper; // 这里会报错,但并不会影响

@Override
public Integer addUser(User user) {
// 进行校验...
return userMapper.insert(user);
}

/*
* 这个方法中用到了我们开头配置依赖的分页插件 pagehelper
* 很简单,只需要在service层传入参数,然后将参数传递给一个插件的一个静态方法即可;
* pageNum 开始页数
* pageSize 每页显示的数据条数
* */
@Override
public PageInfo<User> findAllUser(int pageNum, int pageSize) {
// 进行校验...
// 将参数传进这个方法就可以实现物理分页了,非常简单
PageHelper.startPage(pageNum,pageSize);
// 查询出整个 List
List<User> users = userMapper.selectUsers();
// 把查询结果给 PageInfo,它会帮我们取出当前页的数据
PageInfo result = new PageInfo(users);
return result;
}

}

10、创建Controller:UserController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.fatal.controller;

import com.fatal.entity.User;
import com.fatal.service.IUserService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
* User 控制器
* @author: Fatal
* @date: 2018/10/4 0004 17:12
*/
@RestController
@RequestMapping("/user")
public class UserController {

@Autowired
private IUserService userService;

/**
* 添加
* @param user
*/
@PostMapping("/")
public int addUser (User user){
// 进行校验...
return userService.addUser(user);
}

/**
* 分页查询
* @param pageNum
* @param pageSize
*/
@GetMapping("/")
public Object finAllUser(
@RequestParam(name = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
// 当前页的详细信息
PageInfo<User> data = userService.findAllUser(pageNum, pageSize);
return data;
}

}

项目最终的结构

1538645543114

到这里如果项目就成功搭建完成了,如果还是报错的话,请仔细看看配置,后面会给出源码地址,程序员就是要不断和bug进行斗争,加油。

测试

启动项目

12341235215312351

这样就表示启动成功了

然后,开始测试吧,这里使用的是postMan,一个进行http请求的测试工具

添加数据

12341235215312351

查询数据

1243213421341

思考

为什么 SpringBoot 整合 Mybatis 不用书写配置类呢?

答:因为 SpringBoot 已经帮我们写好配置类了。

  1. 它使用 MybatisProperties 配置类与 application.yml 映射从而接受到用户配置的数据

1538627919484

  1. 将用户的配置数据填充到 MybatisAutoConfiguration 配置类中,这样我们只需写配置数据就行了

    1538628768244

参考链接

HikariCP连接池属性_哪些HikariCP属性建议使用

springboot Mybatis 整合

总结

总共就几步:

1、properties、yml配置

1
2
3
4
5
6
# yml为例
mybatis:
mapper-locations: classpath:mapper/*.xml # 注意:一定要对应 mapper 映射xml文件的所在路径
type-aliases-package: com.example.entity # 注意:对应实体类的路径
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 可以自控制台上输出 sql 语句

2、Mapper 配置文件扫描

@MapperScan(“Mapper接口所在的包的路径”)

作用:扫描指定包下的所有 Mapper 接口 ,并将其交给 Spring 容器管理

要求:一般放在启动类 的位置

3、模板:

yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
# 基本属性 allowMultiQueries:设置为true后,数据库那边才允许你批量更新。编码属性设置了存储数据到数据库才不会是乱码
url: jdbc:mysql://localhost:3306/chapter8?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=UTC&useSSL=false
username: root
password: 123456

# 整合 mybatis
mybatis:
mapper-locations: classpath:mapper/*.xml # 注意:一定要对应 mapper 映射xml文件的所在路径
type-aliases-package: com.fatal.entity # 注意:对应实体类的路径
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


#pagehelper分页插件
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
#returnPageInfo: check

mapper.xml

1
2
<?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" >

SpringBoot的知识已经有前辈在我们之前探索了。比较喜欢的博主有:唐亚峰 | Battcn方志朋的专栏程序猿DD纯洁的微笑。对这门技术感兴趣的可以去他们的博客逛逛。谢谢他们的分享~~

以上文章是我用来学习的Demo,都是基于 SpringBoot2.x 版本。

源码地址:https://github.com/ynfatal/springboot2-learning/tree/master/chapter8

学习 LuisChen 前辈的经验