mybatis-plus代码生成器自定义模板

    最近接受到一个任务,代码生成器的开发。当时自己有两种思路来实现,第一种:自己写个程序,通过java代码生成,第二种:寻找第三方插件来支持,引用他们的。当时自己开发了一个代码生成器程序,但是不够完善,不能全面满足需求,还是借鉴他人意见,网上查询资料,发现Mybatis-plus插件还是挺不错,分享给大家,不过本人才疏学浅,若有说的不对,还望大家指出来。
 

  1.    Mybatis-plus官网,有兴趣的可以了解了解,学习学习的。
  2.    官网配置代码生成器的例子。

   

   当时针对参数校验方面,是需要判断表中字段非空约束,可是查看了Mybatis-plus的源代码,一直没有找出非空字段,幸好TableField中有个  customMap  map结构,只好通过jdbc去查询sql,获取字段的非空约束,再设置到customMap中。

package com.poi.code.creator.tool;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.converts.PostgreSqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.config.rules.PropertyInfo;
import com.google.common.collect.Maps;
import com.poi.code.creator.config.OrdinaryGeneratorConfig;
import com.poi.code.creator.util.SQLExecutor;

//import lombok.Data;
//import lombok.extern.slf4j.Slf4j;

/**
 * 

* 方式二:代码生成器 * 可按照表 生成crud。 *

* * @author : dengbin * @date : 2019/10/11 */ //@RunWith(SpringRunner.class) //@SpringBootTest(classes = Application.class) //@Data //@Slf4j public class OrdinaryCodeGenerator { // @Autowired // private OrdinaryGeneratorConfig ordinaryGeneratorConfig; private final static String sql = "SELECT a.attnum,\n" + " a.attname AS name,\n" + " t.typname AS type,\n" + " a.attlen AS length,\n" + " a.atttypmod AS lengthvar,\n" + " a.attnotnull AS isNull,\n" + " b.description AS columnComment\n" + " FROM pg_class c,\n" + " pg_attribute a\n" + " LEFT OUTER JOIN pg_description b ON a.attrelid=b.objoid AND a.attnum = b.objsubid,\n" + " pg_type t\n" + " WHERE c.relname =" + " ? \n" + " and a.attnum > 0\n" + " and a.attrelid = c.oid\n" + " and a.atttypid = t.oid\n" + " ORDER BY a.attnum"; private final static Map params = Maps.newHashMap(); private final static List placeholderNameList = Collections.singletonList("tableName"); public static void main(String[] args) throws IOException { OrdinaryGeneratorConfig ordinaryGeneratorConfig = new OrdinaryGeneratorConfig(); ordinaryGeneratorConfig.setAbsolutePath("src/main/java"); ordinaryGeneratorConfig.setAuthor("dengbin"); ordinaryGeneratorConfig.setRelativeName("com.poi.code.creator"); ordinaryGeneratorConfig.setTables("ent_i_meter"); generateCode(ordinaryGeneratorConfig); } public static void generateCode(OrdinaryGeneratorConfig ordinaryGeneratorConfig) throws IOException { String author = ordinaryGeneratorConfig.getAuthor(); String resultPath = ordinaryGeneratorConfig.getAbsolutePath() + "/" + ordinaryGeneratorConfig.getRelativeName().replace(".", "/"); boolean exists = new File(resultPath).exists(); if (!exists) { throw new RuntimeException("目录:" + resultPath + "不存在,请重新确认!"); } String tables = ordinaryGeneratorConfig.getTables(); params.put("tableName", tables); //获取数据库连接 GlobalConfig config = new GlobalConfig(); String dbUrl = "你的数据库url链接"; DataSourceConfig dataSourceConfig = new DataSourceConfig(); dataSourceConfig.setDbType(DbType.POSTGRE_SQL) .setUrl(dbUrl) .setUsername("你的数据库用户名称") .setPassword("你的数据库用户账号") .setDriverName("org.postgresql.Driver") .setSchemaName("**"); //类型转换 dataSourceConfig.setTypeConvert(new PostgreSqlTypeConvert() { @Override public PropertyInfo processTypeConvert(GlobalConfig globalConfig, String fieldType) { System.out.println("转换类型:" + fieldType); // 注意!!processTypeConvert 存在默认类型转换,如果不是你要的效果请自定义返回、非如下直接返回。 if (fieldType.contains("numeric")) { return DbColumnType.DOUBLE; } else { return super.processTypeConvert(globalConfig, fieldType); } } }); StrategyConfig strategyConfig = new StrategyConfig(); strategyConfig .setCapitalMode(true) .setLogicDeleteFieldName("rec_status") .setEntityLombokModel(false) .setNaming(NamingStrategy.underline_to_camel) // .setTablePrefix("eff_","ent_i_","ent_s_","ent_r_","eqp_i_","eqp_r_","eqp_s_","prod_i_","prod_r_","prod_s_","sys_i_") .setInclude(tables) //修改替换成你需要的表名,多个表名传数组 .setEntityLombokModel(true); //是否使用lombok config.setActiveRecord(true) .setAuthor(author) .setOutputDir(ordinaryGeneratorConfig.getAbsolutePath()) .setEnableCache(false) .setBaseColumnList(false) .setBaseColumnList(false) .setIdType(IdType.AUTO) //主键类型 定死id自增 .setFileOverride(true) .setServiceName("%sService") .setSwagger2(true); //是否使用Swagger InjectionConfig ic = new InjectionConfig() { @Override public void initMap() { this.setMap(getMap()); } }; TemplateConfig tc = new TemplateConfig(); tc.setXml(null) .setServiceImpl(null) .setController("template/controller.java.vm") .setEntity("template/entity.java.vm") .setService("template/service.java.vm"); //添加add 请求对象 List foc = new ArrayList<>(); foc.add(new FileOutConfig("/template/addVo.java.vm") { @Override public String outputFile(TableInfo tableInfo) { setCustomMap(tableInfo); return resultPath + "/vo/req/Add" + tableInfo.getEntityName() + "Req" + StringPool.DOT_JAVA; } }); //添加update 请求对象 foc.add(new FileOutConfig("/template/updateVo.java.vm") { @Override public String outputFile(TableInfo tableInfo) { setCustomMap(tableInfo); return resultPath + "/vo/req/Update" + tableInfo.getEntityName() + "Req" + StringPool.DOT_JAVA; } }); //添加list请求对象 foc.add(new FileOutConfig("/template/listVo.java.vm") { @Override public String outputFile(TableInfo tableInfo) { return resultPath + "/vo/req/List" + tableInfo.getEntityName() + "Req" + StringPool.DOT_JAVA; } }); //添加分页请求对象 foc.add(new FileOutConfig("/template/pageVo.java.vm") { @Override public String outputFile(TableInfo tableInfo) { return resultPath + "/vo/req/Page" + tableInfo.getEntityName() + "Req" + StringPool.DOT_JAVA; } }); ic.setFileOutConfigList(foc); new AutoGenerator() .setGlobalConfig(config) .setDataSource(dataSourceConfig) .setStrategy(strategyConfig) .setTemplate(tc) .setCfg(ic) .setPackageInfo( new PackageConfig() .setParent(ordinaryGeneratorConfig.getRelativeName()) .setController("controller") .setEntity("entity") ).execute(); } private static void setCustomMap(TableInfo tableInfo) { List> execute = SQLExecutor.execute(sql, params, placeholderNameList); List fields = tableInfo.getFields(); for (TableField field : fields) { Optional> mapOptional = execute.stream().filter(item -> item.get("name").equals(field.getName())).findAny(); Map customMap = Maps.newHashMap(); mapOptional.ifPresent(stringObjectMap -> customMap.put("isNull", (Boolean) stringObjectMap.get("isnull"))); field.setCustomMap(customMap); } } }

   controller的模板(controller.java.vm)内容如下:

package ${package.Controller};

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import ${package.Service.replace(".service","")}.service.${table.serviceName} ;
import ${package.Service.replace(".service","")}.vo.req.Add${entity}Req;
import ${package.Service.replace(".service","")}.vo.req.List${entity}Req;
import ${package.Service.replace(".service","")}.vo.req.Page${entity}Req;
import ${package.Service.replace(".service","")}.vo.req.Update${entity}Req;
import com.poit.commons.utils.resp.ApiResp;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;



/**
* @author ${author}
* @since ${date}
*/
@Api(description = "$!{table.comment}")
@RestController
@RequestMapping("/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end" )
@Slf4j
public class ${table.controllerName}  {

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

    @ApiOperation("列表")
    @GetMapping("/list")
    public ApiResp list(List${entity}Req req) throws Exception {
        return ${table.entityPath}Service.list(req);
    }

    @ApiOperation("分页")
    @GetMapping("/page")
    public ApiResp page(Page${entity}Req req) throws Exception {
        return ${table.entityPath}Service.page(req);
    }

    @ApiOperation("获取详情")
    @GetMapping("/get")
    public ApiResp get(#foreach($field in ${table.fields})#if(${field.keyFlag})@RequestParam("${field.propertyName}") ${field.propertyType} ${field.propertyName}#end#end) throws Exception {
        return ${table.entityPath}Service.get(#foreach($field in ${table.fields})#if(${field.keyFlag})${field.propertyName}#end#end);
    }

    @ApiOperation("添加")
    @PostMapping("/add")
    public ApiResp add(@Valid @RequestBody Add${entity}Req req) throws Exception {
        return ${table.entityPath}Service.add(req);
    }

    @ApiOperation("修改")
    @PostMapping("/modify")
    public ApiResp modify(@Valid @RequestBody Update${entity}Req req) throws Exception {
        return ${table.entityPath}Service.modify(req);
    }

    @ApiOperation("删除")
    @GetMapping("/delete")
    public ApiResp delete(#foreach($field in ${table.fields})#if(${field.keyFlag})@RequestParam("${field.propertyName}") ${field.propertyType} ${field.propertyName}#end#end) throws Exception {
        return ${table.entityPath}Service.delete(#foreach($field in ${table.fields})#if(${field.keyFlag})${field.propertyName}#end#end);
    }
 }

entity.java.vm

package ${package.Entity};

    #foreach($pkg in ${table.importPackages})
    import ${pkg};
    #end
    #if(${swagger2})
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    #end
    #if(${entityLombokModel})
    import lombok.Data;
    #end
import com.baomidou.mybatisplus.annotation.TableName;

import javax.validation.constraints.Size;
/**
 * 

* ${entity}对象 *

* * @author ${author} * @since ${date} */ #if(${entityLombokModel}) @Data #end @TableName("${table.name}") #if(${swagger2}) @ApiModel(value = "${entity}对象", description = "$!{table.comment}") #end #if(${superEntityClass}) public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end { #elseif(${activeRecord}) public class ${entity} extends Model<${entity}> { #else public class ${entity} implements Serializable{ #end ## ---------- BEGIN 字段循环遍历 ---------- #foreach($field in ${table.fields}) #if(${field.keyFlag}) #set($keyPropertyName=${field.propertyName}) #end #if("$!field.comment" != "") #if(${swagger2}) @ApiModelProperty(value = "${field.comment}") #end #end #if(${field.keyFlag}) #if(${field.keyIdentityFlag}) @TableId(value = "${field.name}", type = IdType.AUTO) #elseif(!$null.isNull(${idType}) && "$!idType" != "") @TableId(value = "${field.name}", type = IdType.${idType}) #elseif(${field.convert}) @TableId("${field.name}") #end #elseif(${field.fill}) #if(${field.convert}) @TableField(value = "${field.name}", fill = FieldFill.${field.fill}) #else @TableField(fill = FieldFill.${field.fill}) #end #elseif(${field.convert}) @TableField("${field.name}") #end #if(${logicDeleteFieldName}==${field.name}) @TableLogic #end #if(${field.columnType}=="STRING" && ${field.type} !="text") @Size(max = ${field.type.replace("character varying(","").replace(")","")}, message = "${field.comment}应该在0-${field.type.replace("character varying(","").replace(")","")}字符之间") #end private ${field.propertyType} ${field.propertyName}; #end #if(!${entityLombokModel}) #foreach($field in ${table.fields}) #if(${field.propertyType.equals("boolean")}) #set($getprefix="is") #else #set($getprefix="get") #end 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}) { #end this.${field.propertyName} = ${field.propertyName}; #if(${entityBuilderModel}) return this; #end } #end #end #if(${entityColumnConstant}) #foreach($field in ${table.fields}) public static final String ${field.name.toUpperCase()} ="${field.name}"; #end #end #if(${activeRecord}) @Override protected Serializable pkVal(){ #if(${keyPropertyName}) return this.${keyPropertyName}; #else return null; #end } #end #if(!${entityLombokModel}) @Override public String toString() { return "${entity}{" + #foreach($field in ${table.fields}) #if($!{foreach.index}==0) "${field.propertyName}=" + ${field.propertyName} + #else ", ${field.propertyName}=" + ${field.propertyName} + #end #end "}"; } #end }

service.java.vm

package ${package.Service};

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service.replace(".service","")}.vo.req.Add${entity}Req;
import ${package.Service.replace(".service","")}.vo.req.List${entity}Req;
import ${package.Service.replace(".service","")}.vo.req.Page${entity}Req;
import ${package.Service.replace(".service","")}.vo.req.Update${entity}Req;
import com.poit.commons.utils.resp.ApiResp;

/**
 * 

* ${entity}服务类 *

* * @author ${author} * @since ${date} */ @Service public class ${table.serviceName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> { public ApiResp list(List${entity}Req req)throws Exception{ String keyword = req.getKeyword(); QueryWrapper<${entity}> queryWrapper = new QueryWrapper<>(); if (!StringUtils.isEmpty(keyword)) { queryWrapper.like("", req.getKeyword()); } return ApiResp.of(baseMapper.selectList(queryWrapper)); } public ApiResp page(Page${entity}Req req)throws Exception{ String keyword = req.getKeyword(); IPage<${entity}> page = new Page<>(req.getPageNum(), req.getPageSize()); QueryWrapper<${entity}> queryWrapper = new QueryWrapper<>(); if (!StringUtils.isEmpty(keyword)) { queryWrapper.like("", keyword); } return ApiResp.of(baseMapper.selectPage(page, queryWrapper)); } public ApiResp add(Add${entity}Req req)throws Exception{ ${entity} data = new ${entity}(); BeanUtils.copyProperties(req, data); #foreach($field in ${table.fields}) #if(${field.propertyName.equals("createTime")}) data.set${field.capitalName}(new Date()); #end #end baseMapper.insert(data); return ApiResp.of(#foreach($field in ${table.fields})#if(${field.keyFlag})data.get${field.capitalName}()#end#end); } public ApiResp modify(Update${entity}Req req)throws Exception{ ${entity} data = new ${entity}(); BeanUtils.copyProperties(req, data); #foreach($field in ${table.fields}) #if(${field.propertyName.equals("updateTime")} || ${field.propertyName.equals("modifyTime")}) data.set${field.capitalName}(new Date()); #end #end baseMapper.updateById(data); return ApiResp.of(Boolean.TRUE); } public ApiResp delete(#foreach($field in ${table.fields})#if(${field.keyFlag})${field.propertyType} ${field.propertyName}#end#end)throws Exception{ baseMapper.deleteById(#foreach($field in ${table.fields})#if(${field.keyFlag})${field.propertyName}#end#end); return ApiResp.of(Boolean.TRUE); } public ApiResp get(#foreach($field in ${table.fields})#if(${field.keyFlag})${field.propertyType} ${field.propertyName}#end#end)throws Exception{ return ApiResp.of(baseMapper.selectById(#foreach($field in ${table.fields})#if(${field.keyFlag})${field.propertyName}#end#end)); } }

接下来VO对象,请求对象,返回对象  

package  ${package.Service.replace(".service","")}.vo.req;


import java.io.Serializable;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * 

* Add${entity}Req 请求对象 *

* * @author ${author} * @since ${date} */ @Data @ApiModel(value = "${entity}新增请求对象", description = "$!{table.comment}") public class Add${entity}Req implements Serializable { #foreach($field in ${table.fields}) #if(${swagger2} && !${field.propertyName.equals("recStatus")} &&!${field.propertyName.equals("updateTime")} &&!${field.propertyName.equals("createTime")} &&!${field.propertyName.equals("modifyTime")}&&!${field.keyFlag}) #if("$!field.comment" != "") @ApiModelProperty(value = "${field.comment}") #else @ApiModelProperty(value = "") #end #if(${field.columnType}=="STRING" && ${field.type} !="text") @Size(max = ${field.type.replace("character varying(","").replace(")","")}, message = "${field.comment}应该在0-${field.type.replace("character varying(","").replace(")","")}字符之间") #end #if(${field.customMap.get("isNull")}) @NotNull(message = "${field.comment}不能为空") #end private ${field.propertyType} ${field.propertyName}; #end #end }

 

你可能感兴趣的:(个人成长)