mybatis-plus 代码生成器(Swagger2、自定义模板)
大佬新搭建的项目是mybatis—plus,因而自己学习使用下,对于这些固定的代码还是一键生成比较好。可根据模板自定义生成内容。
直接上代码了。整个项目我附上网盘地址链接: https://pan.baidu.com/s/1EhAa__HTcGJSYWBnvAuLNA 提取码: nd8a
maven依赖
<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
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,常用的可以放在这里
#------------------- 数据源 -------------------# 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
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
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
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
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
<?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
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
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
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
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
/** * @description: * @author: liyh * @time: 2021/12/21 11:52 */ public class StatusCode { public static final int SUCCESS = 200; public static final int ERROR = 500; }
不足之处,望多多之处,定会改正。