大佬新搭建的项目是mybatis—plus,因而自己学习使用下,对于这些固定的代码还是一键生成比较好。可根据模板自定义生成内容。

直接上代码了。整个项目我附上网盘地址链接: https://pan.baidu.com/s/1EhAa__HTcGJSYWBnvAuLNA 提取码: nd8a

maven依赖

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
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>

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

<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.2</version>
</dependency>

<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>

<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>

<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.36</version>
</dependency>

新建 GenerateMybatisPlus.java

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
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.test.context.TestPropertySource;

import java.util.ArrayList;
import java.util.Arrays;

/**
* @description:
* @author: liyh
* @time: 2020/12/21 21:20
*/

//配置文件位置
public class GenerateMybatisPlus {


/**
* @param dataSourceurl
* @param dataSourcename
* @param dataSourcepassword
* @param dataSourcedriver
* @param tables
* @param packageParent
* @param isNormalize
* @description:
* @return: void
* @author: liyh
* @time: 2020/12/21 21:21
*/
public void generate(String dataSourceurl, String dataSourcename, String dataSourcepassword, String dataSourcedriver, String tables, String packageParent, boolean isNormalize) {

AutoGenerator mpg = new AutoGenerator();
// 配置策略
// 1、全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");// 当前项目的路径
gc.setOutputDir(projectPath + "/src/main/java");// 生成文件输出根目录
gc.setAuthor("liyh");// 作者
gc.setOpen(false); // 生成完成后不弹出文件框
gc.setFileOverride(true); // 文件是否覆盖
gc.setIdType(IdType.ASSIGN_UUID); //主键策略 实体类主键ID类型
gc.setDateType(DateType.ONLY_DATE);
gc.setSwagger2(true); // 是否开启swagger
gc.setActiveRecord(true); //【不懂】 活动记录 不需要ActiveRecord特性的请改为false 是否支持AR模式
gc.setEnableCache(false);// XML 二级缓存
gc.setBaseResultMap(true);//【不懂】 XML ResultMap xml映射文件的配置
gc.setBaseColumnList(false);//【不懂】 XML columList xml映射文件的配置

// 自定义文件命名,注意 %s 会自动填充表实体属性!
gc.setControllerName("%sController");
gc.setServiceName("%sService");
gc.setServiceImplName("%sServiceImpl");
gc.setMapperName("%sMapper");
gc.setXmlName("%sMapper");
mpg.setGlobalConfig(gc);

//2、设置数据源
DataSourceConfig dsc = new DataSourceConfig();
dsc.setDbType(DbType.MYSQL);
dsc.setUrl(dataSourceurl);
dsc.setDriverName(dataSourcedriver);
dsc.setUsername(dataSourcename);
dsc.setPassword(dataSourcepassword);
mpg.setDataSource(dsc);

//3、包的配置
PackageConfig pc = new PackageConfig();
pc.setParent(packageParent);
pc.setController("controller"); // 可以不用设置,默认是这个
pc.setService("service"); // 同上
pc.setServiceImpl("service.impl"); // 同上
pc.setMapper("dao"); // 默认是mapper
pc.setEntity("entity"); // 默认是entity
pc.setXml("mapping"); // 默认是默认是mapper.xml
pc.setModuleName("demo"); // 控制层请求地址的包名显示
mpg.setPackageInfo(pc);

//4、策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude(tables.split(",")); // 需要生成的表 设置要映射的表名
strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true); // 自动lombok;
strategy.setCapitalMode(false); //【不懂】 开启全局大写命名
strategy.setSuperMapperClass(null); //【不懂】
// 是否需要开启特定规范字段
if (true == isNormalize) {
strategy.setLogicDeleteFieldName("deleted");
// 自动填充配置
TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
TableFill gmtModified = new TableFill("gmt_modified",
FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(gmtCreate);
tableFills.add(gmtModified);
strategy.setTableFillList(tableFills);
// 乐观锁
strategy.setVersionFieldName("version");
}
strategy.setRestControllerStyle(true); // 控制:true——生成@RsetController false——生成@Controller
strategy.setControllerMappingHyphenStyle(true); // 【不知道是啥】
strategy.setEntityTableFieldAnnotationEnable(true); // 表字段注释启动 启动模板中的这个 <#if table.convert>
strategy.setEntityBooleanColumnRemoveIsPrefix(true); // 是否删除实体类字段的前缀
strategy.setTablePrefix("mdm_"); // 去掉表名mdm_inf_rec_data中的 mdm_ 类名为InfRecData
strategy.setControllerMappingHyphenStyle(false); // 控制层mapping的映射地址 false:infRecData true:inf_rec_data
mpg.setStrategy(strategy);

//模板生成器
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
TemplateConfig tc = new TemplateConfig();
tc.setController("/templatesFreemaker/controller.java");
tc.setService("/templatesFreemaker/service.java");
tc.setServiceImpl("/templatesFreemaker/serviceImpl.java");
tc.setEntity("/templatesFreemaker/entity.java");
tc.setMapper("/templatesFreemaker/mapper.java");
tc.setXml("/templatesFreemaker/mapper.xml");
mpg.setTemplate(tc);

mpg.execute(); //执行
}

}

在resource下新建文件 generate.properties,常用的可以放在这里

1
2
3
4
5
6
7
8
9
#------------------- 数据源 -------------------#
datasource.username=root
datasource.password=123456
datasource.url=jdbc:mysql://127.0.0.1:3306/basic_project?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
datasource.driver-class-name=com.mysql.jdbc.Driver
# 父包名
package.parent=com.xxxx.generate.generatedemo
# 需要生成的表名,多张表用英文逗号隔开 #
datatables.name=user,mdm_inf_rec_data

在springboot项目下test下新建 GenerateApplicationTests.java

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
import com.hong.generate.mybatisplus.GenerateMybatisPlus;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

@SpringBootTest
@TestPropertySource("classpath:generate.properties")
class GenerateApplicationTests {

@Value("${datasource.url}")
private String dataSourceurl;

@Value("${datasource.username}")
private String dataSourcename;

@Value("${datasource.password}")
private String dataSourcepassword;

@Value("${datasource.driver-class-name}")
private String dataSourcedriver;

@Value("${datatables.name}")
private String tables;

@Value("${package.parent}")
private String packageParent;

@Value("${datatables.isNormalize}")
private boolean isNormalize;

@Test
void generateMybatisPlusTest() {
new GenerateMybatisPlus().generate(
dataSourceurl,
dataSourcename,
dataSourcepassword,
dataSourcedriver,
tables,
packageParent,
isNormalize);
}
}

最重要的模板内容

controller.java.ftl

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
package ${package.Controller};



import ${package.Service}.${table.serviceName};
import ${package.Entity}.${entity};
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hong.generate.common.PageResult;
import com.hong.generate.common.Result;
import com.hong.generate.common.StatusCode;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
<#if restControllerStyle>
import org.springframework.web.bind.annotation.RestController;
<#else>
import org.springframework.stereotype.Controller;
</#if>
<#if superControllerClassPackage??>
import ${superControllerClassPackage};
</#if>

/**
* <p>
* ${table.comment!} 前端控制器
* </p>
*
* @author ${author}
* @since ${date}
*/

@Slf4j
@Api(tags = "${table.comment!}")
<#if restControllerStyle>
@RestController
<#else>
@Controller
</#if>
@RequestMapping("<#if package.ModuleName??>/${package.ModuleName}</#if>/<#if controllerMappingHyphenStyle??>${controllerMappingHyphen}<#else>${table.entityPath}</#if>")
<#if kotlin>
class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}()</#if>
<#else>
<#if superControllerClass??>
public class ${table.controllerName} extends ${superControllerClass} {
<#else>
public class ${table.controllerName} {

@Autowired
public ${table.serviceName} ${table.entityPath}Service;

@ApiOperation(value = "新增")
@PostMapping("/save")
public Result save(@RequestBody ${entity} ${table.entityPath}){
${table.entityPath}Service.save(${table.entityPath});
return new Result(StatusCode.SUCCESS,"保存成功");
}

@ApiOperation(value = "根据id删除")
@PostMapping("/delete/{id}")
public Result delete(@PathVariable("id") Long id){
${table.entityPath}Service.removeById(id);
return new Result(StatusCode.SUCCESS,"删除成功");
}

@ApiOperation(value = "条件查询")
@PostMapping("/get")
public Result list(@RequestBody ${entity} ${table.entityPath}){
List<${entity}> ${table.entityPath}List = ${table.entityPath}Service.list(new QueryWrapper<>(${table.entityPath}));
return new Result(StatusCode.SUCCESS,"查询成功",${table.entityPath}List);
}

@ApiOperation(value = "列表(分页)")
@GetMapping("/list/{pageNum}/{pageSize}")
public Object list(@PathVariable("pageNum")Long pageNum, @PathVariable("pageSize")Long pageSize){
IPage<${entity}> page = ${table.entityPath}Service.page(
new Page<>(pageNum, pageSize), null);
return new Result(StatusCode.SUCCESS,"查询成功",new PageResult<>(page.getTotal(),page.getRecords()));
}

@ApiOperation(value = "详情")
@GetMapping("/get/{id}")
public Result get(@PathVariable("id") String id){
${entity} ${table.entityPath} = ${table.entityPath}Service.getById(id);
return new Result(StatusCode.SUCCESS,"查询成功",${table.entityPath});
}

@ApiOperation(value = "根据id修改")
@PostMapping("/update/{id}")
public Result update(@PathVariable("id") String id, @RequestBody ${entity} ${table.entityPath}){
${table.entityPath}.setId(id);
${table.entityPath}Service.updateById(${table.entityPath});
return new Result(StatusCode.SUCCESS,"更新成功");
}

</#if>

}
</#if>

entity.java.ftl

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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package ${package.Entity};

<#list table.importPackages as pkg>
import ${pkg};
</#list>
<#if table.convert>
import com.baomidou.mybatisplus.annotation.TableName;
</#if>
<#if swagger2>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel>
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
</#if>

/**
* <p>
* ${table.comment!}
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if entityLombokModel>
@Data
<#if superEntityClass??>
@EqualsAndHashCode(callSuper = true)
<#else>
@EqualsAndHashCode(callSuper = false)
</#if>
@Accessors(chain = true)
</#if>
<#if table.convert>
@TableName("${table.name}")
</#if>
<#if swagger2>
@ApiModel(value = "${entity}对象", description = "${table.comment!}")
</#if>
<#if superEntityClass??>
public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}></#if> {
<#elseif activeRecord>
public class ${entity} extends Model<${entity}> {
<#else>
public class ${entity} implements Serializable {
</#if>

private static final long serialVersionUID = 1L;
<#-- ---------- BEGIN 字段循环遍历 ---------->
<#list table.fields as field>
<#if field.keyFlag>
<#assign keyPropertyName="${field.propertyName}"/>
</#if>

<#if field.comment!?length gt 0>
//${field.comment}
<#if swagger2>
@ApiModelProperty(value = "${field.comment}")
<#else>
/**
* ${field.comment}
*/
</#if>
</#if>
<#if field.keyFlag>
<#-- 主键 -->
<#if field.keyIdentityFlag>
@TableId(value = "${field.name}", type = IdType.AUTO)
<#elseif idType??>
@TableId(value = "${field.name}", type = IdType.${idType})
<#elseif field.convert>
@TableId("${field.name}")
</#if>
<#-- 普通字段 -->
<#elseif field.fill??>
<#-- ----- 存在字段填充设置 ----->
<#if field.convert>
@TableField(value = "${field.name}", fill = FieldFill.${field.fill})
<#else>
@TableField(fill = FieldFill.${field.fill})
</#if>
<#elseif field.convert>
@TableField("${field.name}")
</#if>
<#-- 乐观锁注解 -->
<#if (versionFieldName!"") == field.name>
@Version
</#if>
<#-- 逻辑删除注解 -->
<#if (logicDeleteFieldName!"") == field.name>
@TableLogic
</#if>
private ${field.propertyType} ${field.propertyName};
</#list>
<#------------ END 字段循环遍历 ---------->

<#if !entityLombokModel>
<#list table.fields as field>
<#if field.propertyType == "boolean">
<#assign getprefix="is"/>
<#else>
<#assign getprefix="get"/>
</#if>
public ${field.propertyType} ${getprefix}${field.capitalName}() {
return ${field.propertyName};
}

<#if entityBuilderModel>
public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
<#else>
public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
</#if>
this.${field.propertyName} = ${field.propertyName};
<#if entityBuilderModel>
return this;
</#if>
}
</#list>
</#if>

<#if entityColumnConstant>
<#list table.fields as field>
public static final String ${field.name?upper_case} = "${field.name}";

</#list>
</#if>
<#if activeRecord>
@Override
protected Serializable pkVal() {
<#if keyPropertyName??>
return this.${keyPropertyName};
<#else>
return null;
</#if>
}

</#if>
<#if !entityLombokModel>
@Override
public String toString() {
return "${entity}{" +
<#list table.fields as field>
<#if field_index==0>
"${field.propertyName}=" + ${field.propertyName} +
<#else>
", ${field.propertyName}=" + ${field.propertyName} +
</#if>
</#list>
"}";
}
</#if>
}

mapper.java.ftl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package ${package.Mapper};

import ${package.Entity}.${entity};
import ${superMapperClassPackage};
import org.apache.ibatis.annotations.Mapper;

/**
* <p>
* ${table.comment!} Mapper 接口
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if kotlin>
interface ${table.mapperName} : ${superMapperClass}<${entity}>
<#else>
@Mapper
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {

}
</#if>

mapper.xml.ftl

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
<?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="${package.Mapper}.${table.mapperName}">

<#if enableCache>
<!-- 开启二级缓存 -->
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>

</#if>
<#if baseResultMap>
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
<#list table.fields as field>
<#if field.keyFlag><#--生成主键排在第一位-->
<id column="${field.name}" property="${field.propertyName}" />
</#if>
</#list>
<#list table.commonFields as field><#--生成公共字段 -->
<result column="${field.name}" property="${field.propertyName}" />
</#list>
<#list table.fields as field>
<#if !field.keyFlag><#--生成普通字段 -->
<result column="${field.name}" property="${field.propertyName}" />
</#if>
</#list>
</resultMap>

</#if>
<#if baseColumnList>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
<#list table.commonFields as field>
${field.name},
</#list>
${table.fieldNames}
</sql>

</#if>
</mapper>

service.java.ftl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package ${package.Service};

import ${package.Entity}.${entity};
import ${superServiceClassPackage};

/**
* <p>
* ${table.comment!} 服务类
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if kotlin>
interface ${table.serviceName} : ${superServiceClass}<${entity}>
<#else>
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {

}
</#if>

serviceImpl.java.ftl

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
package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;

/**
* <p>
* ${table.comment!} 服务实现类
* </p>
*
* @author ${author}
* @since ${date}
*/
@Service
<#if kotlin>
open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {

}
<#else>
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {

}
</#if>

辅助类:

PageResult.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
* @description:
* @author: liyh
* @time: 2020/12/21 10:47
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageResult <T>{

private long total;
private List<T> rows;
}

Result.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import lombok.*;
import org.apache.ibatis.annotations.ConstructorArgs;

/**
* @description:
* @author: liyh
* @time: 2020/12/21 10:47
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor
public class Result {

@NonNull
private Integer code;

@NonNull
private String message;

private Object data;


}

StatusCode.java

1
2
3
4
5
6
7
8
9
10
/**
* @description:
* @author: liyh
* @time: 2021/12/21 11:52
*/
public class StatusCode {

public static final int SUCCESS = 200;
public static final int ERROR = 500;
}

不足之处,望多多之处,定会改正。