Mybatis Plus学习笔记

Mybatis Plus网上的资料很多,这里关于基本的使用方法就不再记录了,只记录我自己用的过程中遇到的一些问题和感触。

解决我们什么问题?

之前用Mybatis,哪怕只是简单的写一个查询,也要编写对应的Mapper.java类、在mapper.xml中添加SQL语句、设置参数类型、返回对象类型、编写对应的Service类,开发效率很低。我们项目中大部分功能其实都是简单的CRUD数据库操作,需要想一个办法来简化开发。

偶然在网上了解到Mybatis Plus可以不用写SQL,因此准备尝试下。

构建一个最简单的应用,需要编写哪些内容?

要想最简化构建应用,推荐使用Mybatis Plus的代码生成器。

官方文档:http://mp.baomidou.com/guide/generator.html#%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE

0、pom.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
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<?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.myhexin.mybatis</groupId>
<artifactId>plus</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>plus</name>
<description>Demo project for Spring Boot</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-services</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>

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

1、照着官方文档的例子,写一个类,执行后输入数据库的信息,生成对应文件;

2、配置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
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
69
70
71
72
server:
port: 10007

spring:
application:
name: api
jmx:
default-domain: api

mybatis:
type-aliases-package: com.myhexin.mybatis.plus.entity
mapper-locations: classpath:mapping/*.xml

---
#######################################本地Windows环境的配置#####################################
spring:
profiles: local
datasource:
name: api
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://172.19.80.195:3306/ThisIsDBName?characterEncoding=utf8&autoReconnect=true
username: ThisIsDBAccount
password: ThisIsDBPassword
#连接池配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
#filters: stat,wall,log4j
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

#mybatis
mybatis-plus:
mapper-locations: classpath:mapping/*.xml
#实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: com.myhexin.mybatis.plus.entity
global-config:
#主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
id-type: 2
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
field-strategy: 2
#驼峰下划线转换
db-column-underline: true
#刷新mapper 调试神器
refresh-mapper: true
#数据库大写下划线转换
#capital-mode: true
#序列接口实现类配置
#key-generator: com.baomidou.springboot.xxx
#逻辑删除配置(下面3个配置)
logic-delete-value: 0
logic-not-delete-value: 1
#自定义SQL注入器
#sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
#自定义填充策略接口实现
#meta-object-handler: com.baomidou.springboot.xxx
configuration:
map-underscore-to-camel-case: true
cache-enabled: false

logging:
config: classpath:logback-development.xml
path: logs

2、编写配置类,即MybatisPlusConfig.java,注入到Spring中:

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
package com.myhexin.mybatis.plus.config;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class MybatisPlusConfig {

/***
* plus 的性能优化
* @return
*/
@Bean
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
/*<!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 -->*/
performanceInterceptor.setMaxTime(1000);
/*<!--SQL是否格式化 默认false-->*/
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}

/**
* @Description : mybatis-plus分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}


/**
* @Description : druid注入
*/
@Bean
@ConfigurationProperties("spring.datasource" )
public DataSource dataSource() {
return DruidDataSourceBuilder
.create()
.build();
}

}

3、编写一个控制器方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RestController
@RequestMapping("/plus/wms-project")
public class WmsProjectController {

@Autowired
IWmsProjectService iWmsProjectService;

@RequestMapping("/test")
public void test()
{
QueryWrapper<WmsProject> ew = new QueryWrapper<WmsProject>();
ew.eq("id", 485);
WmsProject project = iWmsProjectService.getOne(ew);
System.out.println(project);
}
}

至此,一个最简单的数据库操作应用就完成了。

如何理解Wrapper?

官方文档的中文译名为条件构造器,可以简单理解为对SQL语句中的条件逻辑的封装。

官方文档:http://mp.baomidou.com/guide/wrapper.html#abstractwrapper

注意:条件构造器可以用lambda表达式,这个还没尝试。

如何进行复杂查询?

联表查询

可以尝试下通过SQL注入器来实现自定义的复杂查询,这个待验证。

http://mp.baomidou.com/guide/sql-injector.html

如何设置读写分离?

通过dynamic-datasource-spring-boot-starter实现。这个工具也是Mybatis Plus的团队开发的。

github:https://github.com/baomidou/dynamic-datasource-spring-boot-starter

注意:关于@DS这个注解,github的文档说是可以加在类和方法上;但是我自己测试,添加到类上时,会报错:

@DS not applicable to type

而添加在方法上时,可以正常使用。

BUT:我发现一旦这个结合Druid,就出错了,尚未解决。。。

网上有别人自己实现读写分离的方式,根据AOP来实现:

https://www.cnblogs.com/pier2/p/spring-boot-read-write-split.html (Good)

https://blog.csdn.net/yunzhaji3762/article/details/79750343

我可以参考这个文章,通过AOP+自定义注解来实现读写分离。

先参考网上的一个文章试试:

https://blog.csdn.net/FJeKin/article/details/79583744

发现可以操作数据库,但是并没有自动识别读写操作,去连接不同的主从数据库。

常见报错

‘url’ attribute is not specified and no embedded datasource could be configured.

1
2
3
4
5
6
7
8
9
10
11
12
Description:

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class


Action:

Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).

原因是我在application.yml中增加了对环境变量的支持:

1
2
spring:
profiles: local

但是在启动程序的时候,VM条件里面忘记了加上环境变量,导致配置没读到。

只需要在VM options里面指定环境变量即可:

-Dspring.profiles.active=local

另外,如果你的application.yml中针对数据源有多层级配置,那么有可能配置正确,但是因为在Mybatis Plus的配置config类中指定的@ConfigurationProperties不对,也会报上面的这个错误:

@ConfigurationProperties(“spring.datasource.dynamic.datasource.master” )

java.lang.IllegalStateException: dbType not support : null, url null

我发现只要pom.xml中引入下面的内容,就会报这个错误:

1
2
3
4
5
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>

dbType看起来是mybatis plus的一个配置,但是我已经配置了,还是报错。