服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - 基于mybatis-plus-generator实现代码自动生成器

基于mybatis-plus-generator实现代码自动生成器

2022-12-05 15:18北根娃 Java教程

这篇文章专门为小白准备了入门级mybatis-plus-generator代码自动生成器,可以提高开发效率。文中的示例代码讲解详细,感兴趣的可以了解一下

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盘生成代码,但是,生成的代码只是最基本的模板。

基于mybatis-plus-generator实现代码自动生成器

基于mybatis-plus-generator实现代码自动生成器

以上生成的代码都是基于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定义启动类

执行以上函数就可以自动生成代码了,如下图:

基于mybatis-plus-generator实现代码自动生成器

目前代码自动生成器只是一个脚本方式运行,后续我们会把它集成到页面上,通过图形界面的方式去操作。

原文链接:https://www.cnblogs.com/alanlin/p/16241473.html

以上就是基于mybatis-plus-generator实现代码自动生成器的详细内容,更多关于mybatis-plus-generator代码生成的资料请关注服务器之家其它相关文章!

延伸 · 阅读

精彩推荐