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代码生成的资料请关注其它相关文章!
查看更多关于基于mybatis-plus-generator实现代码自动生成器的详细内容...