集成mybatis官方代码生成器
# 集成 Mybatis 官方代码生成器
测试数据和数据表
drop table if exists `demo`;
create table `demo` (
`id` bigint not null comment 'id',
`name` varchar(50) comment '名称',
primary key (`id`)
)engine=innodb default charset=utf8mb4 comment '测试代码生成器';
1
2
3
4
5
6
2
3
4
5
6
导入依赖
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.4.RELEASE</version>
</plugin>
<!-- mybatis generator 自动生成代码插件 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<configurationFile>src/main/resources/generator/generator-config.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
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
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
resrouces/generator/generator-config.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>
<context id="Mysql" targetRuntime="MyBatis3" defaultModelType="flat">
<!-- 自动检查关键字,为关键字增加反引号 -->
<property name="autoDelimitKeywords" value="true"/>
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<!--覆盖生成XML文件-->
<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/>
<!-- 生成的实体类添加toString()方法 -->
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
<!-- 不生成注释 -->
<commentGenerator>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/wiki?serverTimezone=Asia/Shanghai"
userId="root"
password="1">
</jdbcConnection>
<!-- domain类的位置 -->
<javaModelGenerator targetProject="src\main\java"
targetPackage="com.xxx.wiki.domain"/>
<!-- resources目录下的 mapper xml的位置 -->
<sqlMapGenerator targetProject="src\main\resources"
targetPackage="mapper"/>
<!-- mapper类的位置 -->
<javaClientGenerator targetProject="src\main\java"
targetPackage="com.xxx.wiki.mapper"
type="XMLMAPPER"/>
<!--<table tableName="demo" domainObjectName="Demo"/>-->
<!--<table tableName="ebook"/>-->
<!--<table tableName="category"/>-->
<!--<table tableName="doc"/>-->
<!--<table tableName="content"/>-->
<!--<table tableName="user"/>-->
<table tableName="ebook_snapshot"/>
</context>
</generatorConfiguration>
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
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
# 配置 IDEA 生成运行
# mybatis 生成器的问题和解决
mac m1
电脑的targetProject
的目录不能写\
要写/
<?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>
<context id="Mysql" targetRuntime="MyBatis3" defaultModelType="flat">
<!-- 自动检查关键字,为关键字增加反引号 -->
<property name="autoDelimitKeywords" value="true"/>
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<!--覆盖生成XML文件-->
<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/>
<!-- 生成的实体类添加toString()方法 -->
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
<!-- 不生成注释 -->
<commentGenerator>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/wiki?serverTimezone=Asia/Shanghai"
userId="root"
password="root">
</jdbcConnection>
<!-- domain类的位置 -->
<javaModelGenerator targetProject="src/main/java"
targetPackage="com.Xxx.wiki.domain"/>
<!-- resources目录下的 mapper xml的位置 -->
<sqlMapGenerator targetProject="src/main/resources"
targetPackage="mapper"/>
<!-- mapper类的位置 -->
<javaClientGenerator targetProject="src/main/java"
targetPackage="com.Xxx.wiki.mapper"
type="XMLMAPPER"/>
<table tableName="demo" domainObjectName="Demo"/>
<!--<table tableName="ebook"/>-->
<!--<table tableName="category"/>-->
<!--<table tableName="doc"/>-->
<!--<table tableName="content"/>-->
<!--<table tableName="user"/>-->
<table tableName="ebook_snapshot"/>
</context>
</generatorConfiguration>
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
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
不然使用生成器的时候会提示:src/main/java
目录找不到
还有就是,有的人生成器,没有生成代码,感觉也没啥问题,创建demo
的表也执行了,表也存在但是就是没有生成类,因为你没有定义你要生成的表的内容。
<table tableName="demo" domainObjectName="Demo"/>
1
是注释状态,以及下面都是注释状态,我们需要在生成某个表的代码的时候进行取消注释即可。
# 代码测试
DemoService.java
import com.wx.wiki.domain.Demo;
import com.wx.wiki.domain.DemoExample;
import com.wx.wiki.mapper.DemoMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class DemoService {
@Resource
private DemoMapper demoMapper;
public List<Demo> list() {
// 注意生成的代码,这个是要传入一个搜索的参数的,这边查询所有就传递一个对象或者null即可
return demoMapper.selectByExample(new DemoExample());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
DemoController.java
import com.wx.wiki.domain.Demo;
import com.wx.wiki.service.DemoService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
public class DemoController {
@Resource
private DemoService demoService;
@GetMapping("/demo/list")
public List<Demo> list() {
return demoService.list();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
demo.http
测试代码
GET http://localhost:8880/demo/list
#Accept: application/json
###
1
2
3
4
2
3
4
测试结果
GET http://localhost:8880/demo/list
HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Date: Sun, 12 Dec 2021 08:48:31 GMT
Keep-Alive: timeout=60
Connection: keep-alive
[]
Response code: 200; Time: 348ms; Content length: 2 bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
因为表里暂无数据,就是空列表。
# 规范请求和响应内容
定义包名:req
和resp
,用于给前端进行请求和获取返回内容的,因为后端的实体类中的字段不会所有都传给前端,必须对一些字段做隐藏。
EbookReq.java
public class EbookReq {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
这里简略的省略了一些字段内容,到实践的时候,具体而定。
EbookResp.java
public class EbookResp {
private Long id;
private String name;
private Long category1Id;
private Long category2Id;
private String description;
private String cover;
private Integer docCount;
private Integer viewCount;
private Integer voteCount;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getCategory1Id() {
return category1Id;
}
public void setCategory1Id(Long category1Id) {
this.category1Id = category1Id;
}
public Long getCategory2Id() {
return category2Id;
}
public void setCategory2Id(Long category2Id) {
this.category2Id = category2Id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCover() {
return cover;
}
public void setCover(String cover) {
this.cover = cover;
}
public Integer getDocCount() {
return docCount;
}
public void setDocCount(Integer docCount) {
this.docCount = docCount;
}
public Integer getViewCount() {
return viewCount;
}
public void setViewCount(Integer viewCount) {
this.viewCount = viewCount;
}
public Integer getVoteCount() {
return voteCount;
}
public void setVoteCount(Integer voteCount) {
this.voteCount = voteCount;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", name=").append(name);
sb.append(", category1Id=").append(category1Id);
sb.append(", category2Id=").append(category2Id);
sb.append(", description=").append(description);
sb.append(", cover=").append(cover);
sb.append(", docCount=").append(docCount);
sb.append(", viewCount=").append(viewCount);
sb.append(", voteCount=").append(voteCount);
sb.append("]");
return sb.toString();
}
}
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
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
响应的我暂时没去掉,应该要去掉一点,在实践中,不可能所有字段都返回给前端。
下面就是对控制器和服务进行重构
import com.wx.wiki.req.EbookReq;
import com.wx.wiki.resp.CommonResp;
import com.wx.wiki.resp.EbookResp;
import com.wx.wiki.service.EbookService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/ebook") // 提取请求地址前缀
public class EbookController {
@Resource
private EbookService ebookService;
@GetMapping("/list")
public CommonResp<List<EbookResp>> list(EbookReq req) {
CommonResp<List<EbookResp>> resp = new CommonResp<>();
List<EbookResp> list = ebookService.list(req);
resp.setContent(list);
return resp;
}
}
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
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
import com.wx.wiki.domain.Ebook;
import com.wx.wiki.domain.EbookExample;
import com.wx.wiki.mapper.EbookMapper;
import com.wx.wiki.req.EbookReq;
import com.wx.wiki.resp.EbookResp;
import com.wx.wiki.util.CopyUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class EbookService {
@Resource
private EbookMapper ebookMapper;
public List<EbookResp> list(EbookReq req) {
EbookExample ebookExample = new EbookExample();
EbookExample.Criteria criteria = ebookExample.createCriteria();
criteria.andNameLike("%" + req.getName() + "%");
List<Ebook> ebookList = ebookMapper.selectByExample(ebookExample);
// List<EbookResp> respList = new ArrayList<>();
// for (Ebook ebook : ebookList) {
//// EbookResp ebookResp = new EbookResp();
// // 一个一个写,就比较麻烦
//// ebookResp.setId(ebook.getId());
//// BeanUtils.copyProperties(ebook, ebookResp); // 从哪里拷贝到哪里 实现对象的复制
//
// // 工具类的复制
// EbookResp ebookResp = CopyUtil.copy(ebook, EbookResp.class);
//
// respList.add(ebookResp);
// }
// 列表复制 => 工具类的列表复制
List<EbookResp> list = CopyUtil.copyList(ebookList, EbookResp.class);
return list;
}
}
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
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
这里有一个复制对象的工具类
CopyUtil.java
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
public class CopyUtil {
/**
* 单体复制
*/
public static <T> T copy(Object source, Class<T> clazz) {
if (source == null) {
return null;
}
T obj = null;
try {
obj = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
return null;
}
BeanUtils.copyProperties(source, obj);
return obj;
}
/**
* 列表复制
*/
public static <T> List<T> copyList(List source, Class<T> clazz) {
List<T> target = new ArrayList<>();
if (!CollectionUtils.isEmpty(source)) {
for (Object c : source) {
T obj = copy(c, clazz);
target.add(obj);
}
}
return target;
}
}
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
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
编辑 (opens new window)
上次更新: 2021/12/13, 22:18:43