1.引入依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
< dependency > < groupId >com.baomidou</ groupId > < artifactId >mybatis-plus-generator</ artifactId > < version >3.5.2</ version > </ dependency > < dependency > < groupId >org.apache.velocity</ groupId > < artifactId >velocity-engine-core</ artifactId > < version >2.3</ version > </ dependency > <!--糊涂工具包--> <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-core --> < dependency > < groupId >cn.hutool</ groupId > < artifactId >hutool-core</ artifactId > < version >5.7.20</ version > </ dependency > |
MyBatisPlus提高高度封装好的代码生成器模块,只需要简单的几行代码就能实现。同时也可以根据自己的需求灵活的通过模板话的方式生成代码。下面我们分别通过这两种方式来了解一些。
2.简单的代码生成
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
|
package com.didiplus; import com.baomidou.mybatisplus.generator.FastAutoGenerator; import com.baomidou.mybatisplus.generator.config.OutputFile; import org.junit.jupiter.api.Test; import java.util.Collections; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/5/6 * Desc:快速生成 */ public class FastAutoGeneratorTest { @Test public void fastAutoGeneratorTest(){ String url= "jdbc:mysql://127.0.0.1:3306/didiadmin?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true" ; FastAutoGenerator.create(url, "root" , "123456" ) .globalConfig(builder -> { builder.author( "didiplus" ) // 设置作者 .enableSwagger() //开启 swagger 模式 .outputDir( "D://autocode" );// 指定输出目录 }) .packageConfig(builder -> { builder.parent( "com.didiplus.models" ) // 设置父包名 .moduleName( "sys" ) // 设置父包模块名 .pathInfo(Collections.singletonMap(OutputFile.xml, "D://autocode/xml" )); }) .strategyConfig(builder -> { builder.addInclude( "sys_dict_data" ) // 设置需要生成的表名 .addTablePrefix( "t_" , "c_" ) ; // 设置过滤表前缀 }) // .templateEngine(new FreemarkerTemplateEngine()) 使用Freemarker引擎模板,默认的是Velocity引擎模板 .execute(); } } |
运行以上代码,会自动的在D盘生成代码,但是,生成的代码只是最基本的模板。
以上生成的代码都是基于MybatisPlus代码生成默认模板去生成的。适合绝大多数场景。我们也可以根据自己的模板文件去生成代码的。
3.自定义模板生成代码
3.1实现思路
从数据库中读取表的相关信息和表的相关字段
定义相对于的模板文件
组装模板属性
3.2定义代码生成常量
这些常量主要用户后期在组装模板时,把数据库类型转换成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
|
package com.didiplus.constant; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/5/6 * Desc: 码 生 成 通 用 常 量 */ public class GenerateConstant { /** * 数据库字符串类型 */ public static final String[] COLUMN_TYPE_STR = { "char" , "varchar" , "nvarchar" , "varchar2" , "tinytext" , "text" , "mediumtext" , "longtext" }; /** * 数据库时间类型 */ public static final String[] COLUMN_TYPE_TIME = { "datetime" , "time" , "date" , "timestamp" }; /** * 数据库数字类型 */ public static final String[] COLUMN_TYPE_NUMBER = { "tinyint" , "smallint" , "mediumint" , "int" , "number" , "integer" , "bit" }; /** * 数据库bigint类型 */ public static final String[] COLUMN_TYPE_BIGINT = { "bigint" }; /** * 数据库float类型 */ public static final String[] COLUMN_TYPE_FLOAT = { "float" }; /** * 数据库double类型 */ public static final String[] COLUMN_TYPE_DOUBLE = { "double" }; /** * 数据库decimal类型 */ public static final String[] COLUMN_TYPE_DECIMAL = { "decimal" }; /** * 字符串类型 */ public static final String TYPE_STRING = "String" ; /** * 整型 */ public static final String TYPE_INTEGER = "Integer" ; /** * 长整型 */ public static final String TYPE_LONG = "Long" ; /** * 浮点型 */ public static final String TYPE_DOUBLE = "Double" ; /** * 高精度计算类型 */ public static final String TYPE_BIGDECIMAL = "BigDecimal" ; /** * 时间类型 */ public static final String TYPE_DATE = "Date" ; } |
3.3全局配置
1
2
3
4
5
6
7
8
9
10
11
12
|
/** * 全局配置 */ private GlobalConfig.Builder globalConfig() { String projectPath = System.getProperty( "user.dir" ); return new GlobalConfig.Builder() .fileOverride() // 覆盖已生成文件 .disableOpenDir() // 禁止打开输出目录 默认值:true .author( "didiplus" ) //作者名 .outputDir(projectPath+ "/src/main/resources/autocode" ) // 指定输出目录 .enableSwagger(); // 开启 swagger 模式 默认值:false } |
3.4定义生成代码模板的路径
1
2
3
4
5
6
7
8
9
10
11
12
|
/** * 模板配置 */ private TemplateConfig.Builder templateConfig() { return new TemplateConfig.Builder() .entity( "/templates/vm/entity.java" ) .mapper( "/templates/vm/mapper.java" ) .service( "/templates/vm/service.java" ) .serviceImpl( "/templates/vm/serviceimpl.java" ) .controller( "/templates/vm/controller.java" ) .xml( "/templates/vm/mapper.xml" ); } |
以上的函数是声明代码生成根据这些模板去生成对应的模板。
3.5定义各文件生成存储路径
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
/** * 包配置 */ private PackageConfig.Builder packageConfig() { return new PackageConfig.Builder() .parent(packageName) .moduleName(moduleName) .entity( "domain.entity" ) .mapper( "mapper" ) .service( "service" ) .serviceImpl( "service.impl" ) .xml( "mapper.xml" ) .controller( "controller" ); } |
3.6数据源配置
1
2
3
4
5
6
|
/** * 数据源配置 */ private static final DataSourceConfig DATA_SOURCE_CONFIG = new DataSourceConfig .Builder( "jdbc:mysql://127.0.0.1:3306/didiadmin?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true" , "root" , "123456" ) .build(); |
3.7配置策略
1
2
3
4
5
6
7
|
/** * 策略配置 */ private StrategyConfig.Builder strategyConfig() { return new StrategyConfig.Builder() .addInclude(tableName); } |
3.8组装模板属性
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
|
/** * 注入配置 */ private InjectionConfig.Builder injectionConfig(){ Map<String, Object> map = new HashMap<>(); setAttr(tableName, DATA_SOURCE_CONFIG, map); return new InjectionConfig.Builder().customMap(map); } /** * 组装模板属性 * * @param tableName 表名 * @param dataSourceConfig 数据源 * @param map 模板里面 自定义的属性 * @param 表前缀 */ private void setAttr(String tableName, DataSourceConfig dataSourceConfig, Map<String, Object> map ){ List<Map<String, Object>> columns = new ArrayList<>(); // 获取表信息sql String tableSql = "select table_name , table_comment from information_schema.tables " + "where table_schema = (select database()) and table_name = '" + tableName + "'" ; // 获取字段信息sql String columnSql = "select column_name , data_type , column_comment from information_schema.columns " + "where table_name = '" + tableName + "' and table_schema = (select database()) and column_name != 'id_new'" ; // 利用现有的dataSourceConfig来获取数据库连接,查询表字段及备注等信息 try ( Connection conn = dataSourceConfig.getConn(); PreparedStatement psTable = conn.prepareStatement(tableSql); ResultSet rsTable = psTable.executeQuery(); PreparedStatement pscolumns= conn.prepareStatement(columnSql); ResultSet rscolumns = pscolumns.executeQuery(); ){ if (rsTable.next()){ String table_name = rsTable.getString( "table_name" ); map.put( "tableName" ,table_name); map.put( "comment" ,rsTable.getString( "table_comment" )); // 类名 大驼峰 map.put( "upperClassName" , StrUtil.upperFirst(StrUtil.toCamelCase(table_name))); // 对象名 小驼峰 map.put( "lowerClassName" ,StrUtil.toCamelCase(table_name)); } while (rscolumns.next()){ Map<String, Object> columnMap = new HashMap<>(); // 列名字、数据类型、java属性名字、java属性类型、备注 columnMap.put( "column_name" ,rscolumns.getString( "column_name" )); columnMap.put( "data_type" ,rscolumns.getString( "data_type" )); columnMap.put( "javaLowerAttrName" ,StrUtil.toCamelCase(rscolumns.getString( "column_name" ))); columnMap.put( "javaAttrType" ,columnTypeToJavaType(rscolumns.getString( "data_type" ))); columnMap.put( "column_comment" , rscolumns.getString( "column_comment" )); columns.add(columnMap); } } catch (Exception e) { log.info( "----------sql执行出错" ); e.printStackTrace(); } map.put( "columns" ,columns); map.put( "datetime" , DateUtil.now()); map.put( "packageName" , packageName); map.put( "moduleName" , moduleName); } /** * 数据库类型转换为java类型 * * @param columnType 数据库类型 * @return java类型 */ private String columnTypeToJavaType(String columnType) { if (StrUtil.isNotEmpty(columnType)){ if (Arrays.asList(GenerateConstant.COLUMN_TYPE_STR).contains(columnType)){ return GenerateConstant.TYPE_STRING; } if (Arrays.asList(GenerateConstant.COLUMN_TYPE_TIME).contains(columnType)){ return GenerateConstant.TYPE_DATE; } if (Arrays.asList(GenerateConstant.COLUMN_TYPE_NUMBER).contains(columnType)) { return GenerateConstant.TYPE_INTEGER; } if (Arrays.asList(GenerateConstant.COLUMN_TYPE_BIGINT).contains(columnType)) { return GenerateConstant.TYPE_LONG; } if (Arrays.asList(GenerateConstant.COLUMN_TYPE_FLOAT).contains(columnType)) { return GenerateConstant.TYPE_DOUBLE; } if (Arrays.asList(GenerateConstant.COLUMN_TYPE_DOUBLE).contains(columnType)) { return GenerateConstant.TYPE_DOUBLE; } if (Arrays.asList(GenerateConstant.COLUMN_TYPE_DECIMAL).contains(columnType)) { return GenerateConstant.TYPE_BIGDECIMAL; } } return null ; } |
3.9定义对应的模板文件
在项目的资源文件夹templats
中创建vm
文件夹存放模板文件
entity.java.vm
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
|
package ${packageName}.${moduleName}.domain.entity; #set($list=[ "createBy" , "createTime" , "createName" , "updateBy" , "updateName" , "updateTime" , "deleteFlag" ]) import com.didiplus.common.base.BaseDomain; import lombok.Data; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import java.util.Date; import com.baomidou.mybatisplus.annotation.TableName; /** * @author ${author} * @date ${datetime} * * @description ${comment}(${upperClassName}实体类) */ @Data @TableName ( "${tableName}" ) @ApiModel (value = "${comment}" , description = "${comment}对象 ${lowerClassName}" ) public class ${upperClassName}Entity extends BaseDomain { #foreach ($column in $columns) ## 排除父类字段 # if ($list.contains($column.javaLowerAttrName)) # else /** * $column.column_comment */ @ApiModelProperty (value = "$column.column_comment" ) private $column.javaAttrType $column.javaLowerAttrName; #end #end } |
mapper.java.vm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package ${packageName}.${moduleName}.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import ${packageName}.${moduleName}.domain.entity.${upperClassName}Entity; import org.apache.ibatis.annotations.Mapper; /** * @author ${author} * @date ${datetime} * * @description ${comment} */ @Mapper public interface ${upperClassName}Mapper extends BaseMapper<${upperClassName}Entity> { } |
mapper.xml.vm
1
2
3
4
5
6
7
8
9
10
11
|
<? 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 = "${packageName}.${moduleName}.mapper.${upperClassName}Mapper" > < resultMap id = "${lowerClassName}Map" type = "${packageName}.${moduleName}.domain.${upperClassName}" > #foreach($column in $columns) < result column = "${column.column_name}" property = "${column.javaLowerAttrName}" /> #end </ resultMap > </ mapper > |
service.java.vm
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
|
package ${packageName}.${moduleName}.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; import ${packageName}.${moduleName}.domain.entity.${upperClassName}; import com.didiplus.common.web.domain.PageDomain; /** * @author ${author} * @date ${datetime} * * @description ${comment} */ public interface I${upperClassName}Service extends IService<${upperClassName}Entity> { /** * 分页查询 * @param pageDomain * @return */ IPage<${upperClassName}Entity> page(PageDomain pageDomain); } |
serviceImpl.java.vm
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
|
package ${packageName}.${moduleName}.service.impl; import com.didiplus.common.web.domain.PageDomain; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import ${packageName}.${moduleName}.domain.entity.${upperClassName}Entity; import ${packageName}.${moduleName}.mapper.${upperClassName}Mapper; import ${packageName}.${moduleName}.service.I${upperClassName}Service; import org.springframework.stereotype.Service; import javax.annotation.Resource; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; /** * @author ${author} * @date ${datetime} * * @description ${comment} */ @Service public class ${upperClassName}ServiceImpl extends ServiceImpl<${upperClassName}Mapper, ${upperClassName}Entity> implements I${upperClassName}Service { @Resource ${upperClassName}Mapper ${lowerClassName}Mapper; @Override public IPage<${upperClassName}Entity> page(PageDomain pageDomain) { IPage<${upperClassName}Entity> page = new Page<>(pageDomain.getPage(),pageDomain.getLimit()); return ${lowerClassName}Mapper.selectPage(page, null ); } } |
controller.java.vm
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
|
package ${packageName}.${moduleName}.controller; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import ${packageName}.${moduleName}.domain.entity.${upperClassName}Entity; import ${packageName}.${moduleName}.service.I${upperClassName}Service; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import com.didiplus.common.web.domain.PageDomain; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import com.didiplus.common.base.ValidGroup; import javax.annotation.Resource; /** * @author ${author} * @date ${datetime} * * @description ${comment} */ @Slf4j @RestController @RequestMapping ( "/${lowerClassName}" ) @Api (value = "${lowerClassName}" , tags = "${comment}管理模块" ) public class ${upperClassName}Controller { @Resource private I${upperClassName}Service ${lowerClassName}Service; /** * 分页查询 * @param pageDomain 分页对象 * @param ${lowerClassName}Entity ${comment} * @return IPage */ @ApiOperation (value = "分页查询" , notes = "分页查询" ) @GetMapping ( "/page" ) public IPage get${upperClassName}Page( @RequestBody PageDomain pageDomain) { return ${lowerClassName}Service.page(pageDomain); } /** * 新增${comment} * @param ${lowerClassName}Entity ${comment} * @return Result */ @ApiOperation (value = "新增${comment}" , notes = "新增${comment}" ) @PostMapping public String save( @Validated (ValidGroup.Crud.Create. class ) @RequestBody ${upperClassName}Entity ${lowerClassName}Entity) { return ${lowerClassName}Service.save(${lowerClassName}Entity)? "添加成功" : "添加失败" ; } /** * 修改${comment} * @param ${lowerClassName}Entity ${comment} * @return Result */ @ApiOperation (value = "修改${comment}" , notes = "修改${comment}" ) @PutMapping public String updateById( @Validated (ValidGroup.Crud.Update. class ) @RequestBody ${upperClassName}Entity ${lowerClassName}Entity) { return ${lowerClassName}Service.updateById(${lowerClassName}Entity)? "修改成功" : "修改失败" ; } /** * 通过id删除${comment} * @param id id * @return Result */ @ApiOperation (value = "通过id删除${comment}" , notes = "通过id删除${comment}" ) @DeleteMapping ( "/{id}" ) public String removeById( @PathVariable Integer id) { return ${lowerClassName}Service.removeById(id)? "删除成功" : "删除失败" ; } } |
3.10定义启动类
执行以上函数就可以自动生成代码了,如下图:
目前代码自动生成器只是一个脚本方式运行,后续我们会把它集成到页面上,通过图形界面的方式去操作。
原文链接:https://www.cnblogs.com/alanlin/p/16241473.html
以上就是基于mybatis-plus-generator实现代码自动生成器的详细内容,更多关于mybatis-plus-generator代码生成的资料请关注服务器之家其它相关文章!