本文主要是使用Mybatis在Springboot中根据数据库表自动生成model以及mapper映射。两种方式,手动和自动。
方式一:手写Generator
1.application.yml
1
2
3
4
5
6
7
8
9
10
11
12 server:
port: 8080
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/person?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations:
- classpath:mapper/*.xml
- classpath*:com/**/mapper/*.xml
2.generator.properties
1
2
3
4 jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://localhost:3306/person?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
jdbc.userId=root
jdbc.password=123456
3.generatorConfig.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 <?xml version="1.0" encoding="UTF-8"?>
<generatorConfiguration>
<properties resource="generator.properties"/>
<context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<property name="javaFileEncoding" value="UTF-8"/>
<!--为模型生成序列化方法-->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<!--为生成的Java模型创建一个toString方法-->
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"></plugin>
<!--覆盖生成XML文件-->
<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />
<!--自定义生成model的代码注释-->
<commentGenerator type="com.zhaixin.mbg.CommentGenerator">
<!--是否去除自动生成的注释代码-->
<property name="suppressAllComments" value="true"/>
<property name="suppressDate" value="true"/>
<property name="addRemarkComments" value="true"/>
</commentGenerator>
<!--配置数据库连接-->
<jdbcConnection driverClass="${jdbc.driverClass}"
connectionURL="${jdbc.connectionURL}"
userId="${jdbc.userId}"
password="${jdbc.password}">
<!--解决mysql驱动升级到8.0后不生成指定数据库代码的问题-->
<property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>
<!--指定生成Model的路径-->
<javaModelGenerator targetPackage="com.zhaixin.mbg.model" targetProject="Mybatis-genertor\src\main\java"/>
<!--指定生成mapper.xml的路径-->
<sqlMapGenerator targetPackage="com.zhaixin.mbg.mapper" targetProject="Mybatis-genertor\src\main\resources" />
<!--指定生成Mapper接口的路径-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.zhaixin.mbg.mapper" targetProject="Mybatis-genertor\src\main\java"/>
<!--生成全部表,将tableName设置成% -->
<table tableName="user">
<generatedKey column="id" sqlStatement="Mysql" identity="true"/>
</table>
</context>
</generatorConfiguration>
4.Generator.class执行自动生成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 public class Generator {
public static void main(String[] args) throws Exception {
// 执行过程中的警告信息
List<String> warnings = new ArrayList<String>();
// 当生成的代码重复时,覆盖源代码
boolean overwrite = true;
// 读取bgm配置文件
InputStream is = Generator.class.getResourceAsStream("/generatorConfig.xml");
ConfigurationParser configurationParser = new ConfigurationParser(warnings);
Configuration configuration = configurationParser.parseConfiguration(is);
is.close();
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
// 创建bgm
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(configuration, callback, warnings);
// 执行生成代码
myBatisGenerator.generate(null);
// 输出警告信息
for (String warning : warnings) {
System.out.println(warning);
}
}
}
5.CommentGenerator.class有关自动生成注释的配置
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 public class CommentGenerator extends DefaultCommentGenerator {
private boolean addRemarkComments = false;
public void addConfigurationProperties(Properties properties) {
super.addConfigurationProperties(properties);
this.addRemarkComments = StringUtility.isTrue(properties.getProperty("addRemarkComments"));
}
public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
String remarks = introspectedColumn.getRemarks();
// 根据参数和备注信息判断是否添加备注信息
if(addRemarkComments&& StringUtility.stringHasValue(remarks)) {
addFieldJavaDoc(field, remarks);
}
}
// 给model的字段添加注释
private void addFieldJavaDoc(Field field, String remarks) {
// 文档注释开始
field.addJavaDocLine("/**");
// 获取数据库字段的备注信息
String[] remarkLines = remarks.split(System.getProperty("line.separator"));
for (String remarkLine : remarkLines) {
field.addJavaDocLine("*"+ remarkLine);
}
addJavadocTag(field, false);
field.addJavaDocLine("*/");
}
}
6.PageHelper的PageCommon,封装Page API
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 /*
* 分页数据封装类
* */
public class PageCommon<T> {
private Integer pageNum;
private Integer pageSize;
private Integer totalPage;
private Long total;
private List<T> list;
// 将PageHelper分页后的list转为分页信息
public static <T> PageCommon<T> restPage(List<T> list) {
PageCommon<T> result = new PageCommon<T>();
PageInfo<T> pageInfo = new PageInfo<T>(list);
result.setTotalPage(pageInfo.getPages());
result.setPageNum(pageInfo.getPageNum());
result.setPageSize(pageInfo.getPageSize());
result.setTotal(pageInfo.getTotal());
result.setList(pageInfo.getList());
return result;
}
public Integer getPageNum() {
return pageNum;
}
public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getTotalPage() {
return totalPage;
}
public void setTotalPage(Integer totalPage) {
this.totalPage = totalPage;
}
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
this.total = total;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
}
7.常用的返回结果封装类
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139 public interface ErrorCode {
long getCode();
String getMessage();
}
public enum ResultCode implements ErrorCode{
SUCCESS(200, "操作成功"),
FAILED(500, "操作失败"),
VALIDATE_FAILED(404, "参数检验失败"),
UNAUTHORIZED(401, "暂未登录或token已经过期"),
FORBIDDEN(403, "没有相关权限");
private long code;
private String message;
private ResultCode(long code, String message) {
this.code = code;
this.message = message;
}
public long getCode() {
return code;
}
public String getMessage() {
return message;
}
}
public class CommonResult<T> {
private long code;
private String message;
private T data;
protected CommonResult() {
}
protected CommonResult(long code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
/**
* 成功返回结果
*
* @param data 获取的数据
*/
public static <T> CommonResult<T> success(T data) {
return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
}
/**
* 成功返回结果
*
* @param data 获取的数据
* @param message 提示信息
*/
public static <T> CommonResult<T> success(T data, String message) {
return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data);
}
/**
* 失败返回结果
* @param errorCode 错误码
*/
public static <T> CommonResult<T> failed(ErrorCode errorCode) {
return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);
}
/**
* 失败返回结果
* @param message 提示信息
*/
public static <T> CommonResult<T> failed(String message) {
return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null);
}
/**
* 失败返回结果
*/
public static <T> CommonResult<T> failed() {
return failed(ResultCode.FAILED);
}
/**
* 参数验证失败返回结果
*/
public static <T> CommonResult<T> validateFailed() {
return failed(ResultCode.VALIDATE_FAILED);
}
/**
* 参数验证失败返回结果
* @param message 提示信息
*/
public static <T> CommonResult<T> validateFailed(String message) {
return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null);
}
/**
* 未登录返回结果
*/
public static <T> CommonResult<T> unauthorized(T data) {
return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);
}
/**
* 未授权返回结果
*/
public static <T> CommonResult<T> forbidden(T data) {
return new CommonResult<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);
}
public long getCode() {
return code;
}
public void setCode(long code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
8.service
1
2
3
4
5
6
7
8
9
10
11
12
13 public interface UserService {
List<User> findAll(int pageNum, int pageSize);
}
public class UserServiceImpl implements UserService {
UserMapper userMapper;
public List<User> findAll(int pageNum, int pageSize) {
PageHelper.startPage(pageNum,pageSize);
return userMapper.selectByExample(new UserExample());
}
}
9.Controller
1
2
3
4
5
6
7
8
9
10
11
12
public class UserController {
UserServiceImpl userService;
"/all") (
public CommonResult<PageCommon<User>> findAll( (value = "pageNum", defaultValue = "1") Integer pageNum,
"pageSize", defaultValue = "3") Integer pageSize) { (value =
List<User> list = userService.findAll(pageNum,pageSize);
return CommonResult.success(PageCommon.restPage(list));
}
}
方式二:pom.xml配置插件方式
1.generatorConfig.xml(注意写对,不要引用CommentGenerator.class)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<?xml version="1.0" encoding="UTF-8"?>
<generatorConfiguration>
<properties resource="generator.properties"/>
<context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<property name="javaFileEncoding" value="UTF-8"/>
<!--为模型生成序列化方法-->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<!--为生成的Java模型创建一个toString方法-->
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"></plugin>
<!--覆盖生成XML文件-->
<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />
<!-- <!–自定义生成model的代码注释–>-->
<!-- <commentGenerator type="com.zhaixin.mbg.CommentGenerator">-->
<!-- <!–是否去除自动生成的注释代码–>-->
<!-- <property name="suppressAllComments" value="true"/>-->
<!-- <property name="suppressDate" value="true"/>-->
<!-- <property name="addRemarkComments" value="true"/>-->
<!-- </commentGenerator>-->
<!-- 注释 -->
<commentGenerator >
<property name="suppressAllComments" value="false"/><!-- 是否取消注释 -->
<property name="suppressDate" value="true" /> <!-- 是否生成注释代时间戳-->
</commentGenerator>
<!--配置数据库连接-->
<jdbcConnection driverClass="${jdbc.driverClass}"
connectionURL="${jdbc.connectionURL}"
userId="${jdbc.userId}"
password="${jdbc.password}">
<!--解决mysql驱动升级到8.0后不生成指定数据库代码的问题-->
<property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>
<!--指定生成Model的路径-->
<javaModelGenerator targetPackage="com.zhaixin.mbg.model" targetProject="src\main\java"/>
<!--指定生成mapper.xml的路径-->
<sqlMapGenerator targetPackage="com.zhaixin.mbg.mapper" targetProject="src\main\resources" />
<!--指定生成Mapper接口的路径-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.zhaixin.mbg.mapper" targetProject="src\main\java"/>
<!--生成全部表,将tableName设置成% -->
<table tableName="user">
<generatedKey column="id" sqlStatement="Mysql" identity="true"/>
</table>
</context>
</generatorConfiguration>
2.pom.xml
在方式一的基础上多了这个配置1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<!-- mybatis generator 自动生成代码插件 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<configuration>
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
<!-- 配置数据库链接及mybatis generator core依赖 生成mapper时使用 -->
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
</dependencies>
</plugin>
直接在Maven Plugius中生成即可,但要去除方式一中的Generator.class和CommentGenerator.class
注意:
1.Mybatis-generator在使用时,如果多次生成,则XML会追加,为了防止追加,只是覆盖的话,则需要在generatorConfig.xml添加如下配置1
2<!--覆盖生成XML文件-->
<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />
2.在有分页插件的基础上,只需要多个action,在每次执行findAll方法时使得pageNum+1或-1就可以实现页面的切换。
3.在手动生成和自动生成中,对于GeneratorConfig.xml而言,其中的targetProject是有区别的,对于手动则需要带具体的Project(单项目除外),对于自动,则不需要带项目名称,因为你是去某个项目的插件中自动生成的。
参考:
https://github.com/macrozheng/mall-learning
https://www.cnblogs.com/xxoome/p/10068780.html
https://www.jianshu.com/p/a8bfc14a3534