MybatisPlus自动生成代码这里(链接地址)已经详细介绍过了,这里主要补充下自定义模版配置
传参、模版中字符串首字母大写相关的信息
文末有完整的配置文件
自定义模版传参
AutoGenerator方法中,自定义模版传参可以在InjectionConfig对象中注入自定义 Map 对象,针对所有表的全局参数
InjectionConfig中配置
一个简单的配置如下
parentPackage、queryDtoPackage、addDtoPackage、updateDtoPackage、voPackage对应的包名,
已经dtoIgnoreFields DTO的忽略字段,通过map传进去,在addDTO.java.vm模版中通过${cfg.addDtoPackage}获取属性
InjectionConfig cfg = new InjectionConfig() {
// map.put("queryDtoPackage", PARENT + ".dto.query");
// 在.ftl(或者是.vm)模板中,通过${cfg.queryDtoPackage}获取属性
@Override
public void initMap() {
// 自定义生成模板参数
Map<String, Object> map = new HashMap<>();
map.put("parentPackage", PARENT);
map.put("queryDtoPackage", PARENT + ".dto.query");
map.put("addDtoPackage", PARENT + ".dto.add");
map.put("updateDtoPackage", PARENT + ".dto.update");
map.put("voPackage", PARENT + ".vo");
map.put("dtoIgnoreFields", DTO_IGNORE_FIELD);
this.setMap(map);
}
};
addDTO.java.vm中使用
addDTO.java.vm配置如下
package ${cfg.addDtoPackage}; 就是获取上面 map.put(“addDtoPackage”, PARENT + “.dto.add”);中addDtoPackage的值
package ${cfg.addDtoPackage};
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
#foreach($field in ${table.fields})
#if(${field.propertyType} == "Date")
import java.util.Date;
#break
#end
#end
/**
* $!{table.comment} 创建DTO
*
* @author ${author}
* @since ${date}
*/
@Data
@ApiModel(value = "${entity}对象", description = "$!{table.comment}")
#set($ignoreFields = ${cfg.dtoIgnoreFields})
public class ${entity}AddDTO {
## ---------- BEGIN 字段循环遍历 ----------
#foreach($field in ${table.fields})
#set($flag = "0")
#foreach($ignoreName in ${cfg.dtoIgnoreFields.split(",")})
#if("$ignoreName" == "${field.propertyName}")
#set($flag = "1")
#break
#end
#end
#if($flag != "1")
#if(${field.keyFlag})
#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")
#if(${swagger2})
@ApiModelProperty(value = "${field.comment}")
#else
/**
* ${field.comment}
*/
#end
#end
private ${field.propertyType} ${field.propertyName};
#end
#end
}
自定义输出文件配置
addDTO.java.vm、queryDTO.java.vm等模版生成文件对应的项目目录配置
// 自定义输出文件配置
List<FileOutConfig> fileOutConfigList = new ArrayList<>();
// queryDTO
fileOutConfigList.add(new FileOutConfig("templates/queryDTO.java.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return path + "dto/query/" + tableInfo.getEntityName() + "QueryDTO" + StringPool.DOT_JAVA;
}
});
// addDTO
fileOutConfigList.add(new FileOutConfig("templates/addDTO.java.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return path + "dto/add/" + tableInfo.getEntityName() + "AddDTO" + StringPool.DOT_JAVA;
}
});
// updateDTO
fileOutConfigList.add(new FileOutConfig("templates/updateDTO.java.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return path + "dto/update/" + tableInfo.getEntityName() + "UpdateDTO" + StringPool.DOT_JAVA;
}
});
// vo
fileOutConfigList.add(new FileOutConfig("templates/vo.java.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return path + "vo/" + tableInfo.getEntityName() + "VO" + StringPool.DOT_JAVA;
}
});
cfg.setFileOutConfigList(fileOutConfigList);
mpg.setCfg(cfg);
注意:配置路径的文件名一定要与vm模版文件的类名要一致,不然路径就会有问题
比如配置addDTO如下
// addDTO
fileOutConfigList.add(new FileOutConfig("templates/addDTO.java.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return path + "dto/add/" + tableInfo.getEntityName() + "AddDTO" + StringPool.DOT_JAVA;
}
});
addDTO.java.vm中的类名:public class ${entity}AddDTO
这里path + “dto/add/” + tableInfo.getEntityName() + “AddDTO” + StringPool.DOT_JAVA中的
AddDTO" + StringPool.DOT_JAVA一定要与 ${entity}AddDTO 一样才可以,不然路径就会有问题
vm模版中字符串首字母大写
在代码中经常都需要手字母大写,例如:
User user = lambdaQuery().eq(User::getUsername, loginDTO.getUsername()).one();
getUsername中这里Username就是username首字母大写
这时生成模版时的步骤就的如下:
- 获取字段属性名
#set($name = ${field.propertyName})
- 根据获取的属性名首字母大写
#set($capitalizedName = $name.substring(0, 1).toUpperCase() + $name.substring(1))
实现类中列表查询就会用到
/**
* ${table.comment}-列表
*
* @param queryDTO 查询参数
* @return ${entity}VO
*/
@Override
public List<${entity}> list(${entity}QueryDTO queryDTO){
return lambdaQuery()
#foreach($field in ${table.fields})
#set($name = ${field.propertyName})
#set($capitalizedName = $name.substring(0, 1).toUpperCase() + $name.substring(1))
.like(ObjectUtil.isNotNull(queryDTO.get$capitalizedName()), ${entity}::get$capitalizedName, queryDTO.get$capitalizedName())
#end
.orderByDesc(${entity}::getId)
.list();
}
完整的配置
CodeGenerator
package com.example.student;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
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.*;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
/**
* @author CuMamba
* @date 2024/3/3
*/
public class CodeGenerator {
/**
* 数据库链接
*/
private static final String DATABASE_URL = "jdbc:mysql://127.0.0.1:3306/student?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8";
/**
* 数据库用户名
*/
private static final String DATABASE_USERNAME = "root";
/**
* 数据库密码
*/
private static final String DATABASE_PASSWORD = "12345678";
/**
* 包名(根据自己项目修改)
*/
private static final String PACKAGE_NAME = "com.example.student";
/**
* 模块名称(如果项目中有多个模块需要设置(如:用户模块、商品模块、订单模块),只有一个模块就不用设置(为空就好))
*/
private static final String SECOND_MODULE = "";
/**
* 作者
*/
private static final String AUTHOR = "CuMamba";
/**
* 表前缀(org_user表需要去掉前缀时这里填写"org_")
*/
private static final String TABLE_PREFIX = "";
/**
* 生成代码文件的路径
*/
private static final String PARENT = PACKAGE_NAME + (StringUtils.isNotBlank(SECOND_MODULE) ? "." + SECOND_MODULE : "");
/**
* 生成代码文件的路径
*/
private static final String XML_PATH = "/src/main/resources/mapper" + (StringUtils.isNotBlank(SECOND_MODULE) ? "/" + SECOND_MODULE : "");
/**
* DTO 忽略的字段
*/
public static String DTO_IGNORE_FIELD = "createTime,updateTime,creatorId,updaterId";
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
// 设置代码生成路径
gc.setOutputDir(projectPath + "/src/main/java/");
// 是否覆盖以前文件
gc.setFileOverride(true);
// 是否打开生成目录
gc.setOpen(false);
// 设置项目作者名称
gc.setAuthor(AUTHOR);
// 设置主键策略
gc.setIdType(IdType.AUTO);
// 生成基本ResultMap
gc.setBaseResultMap(true);
// 生成基本ColumnList
gc.setBaseColumnList(true);
// 去掉服务默认前缀
gc.setServiceName("%sService");
// 设置时间类型
gc.setDateType(DateType.ONLY_DATE);
// 设置Swagger2
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
// 数据库链接
dsc.setUrl(DATABASE_URL);
// 数据库驱动
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
// 数据库用户名
dsc.setUsername(DATABASE_USERNAME);
// 数据库密码
dsc.setPassword(DATABASE_PASSWORD);
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setParent(PARENT);
pc.setMapper("mapper");
pc.setXml("mapper");
pc.setEntity("entity");
pc.setService("service");
pc.setServiceImpl("service.impl");
pc.setController("controller");
Map<String, String> packageInfo = new HashMap<>();
String path = gc.getOutputDir() + PARENT.replace(".", "/") + "/";
String xmlPath = projectPath + XML_PATH;
System.out.println("XML_PATH:" + xmlPath);
packageInfo.put(ConstVal.XML_PATH, xmlPath);
packageInfo.put(ConstVal.ENTITY_PATH, path + "entity");
packageInfo.put(ConstVal.SERVICE_PATH, path + "service");
packageInfo.put(ConstVal.SERVICE_IMPL_PATH, path + "service/impl");
packageInfo.put(ConstVal.MAPPER_PATH, path + "mapper");
packageInfo.put(ConstVal.CONTROLLER_PATH, path + "controller");
pc.setPathInfo(packageInfo);
mpg.setPackageInfo(pc);
// 策略配置
StrategyConfig sc = new StrategyConfig();
sc.setNaming(NamingStrategy.underline_to_camel);
sc.setColumnNaming(NamingStrategy.underline_to_camel);
// 自动lombok
sc.setEntityLombokModel(true);
sc.setRestControllerStyle(true);
sc.setControllerMappingHyphenStyle(true);
// 设置逻辑删除
sc.setLogicDeleteFieldName("deleted");
// 设置自动填充配置
TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
TableFill updateTime = new TableFill("update_time", FieldFill.INSERT_UPDATE);
TableFill creatorId = new TableFill("creator_id", FieldFill.INSERT);
TableFill updaterId = new TableFill("updater_id", FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(createTime);
tableFills.add(updateTime);
tableFills.add(creatorId);
tableFills.add(updaterId);
sc.setTableFillList(tableFills);
// 乐观锁
sc.setVersionFieldName("version");
// 驼峰命名
sc.setRestControllerStyle(true);
// 设置表名前缀
sc.setTablePrefix(TABLE_PREFIX);
// 设置需要生成的表名
sc.setInclude(scanner("表名,如果同时输入多个表名,中间用英文逗号分割(例如:user,order,product)").split(","));
mpg.setStrategy(sc);
// 自定义配置,配置自定义属性注入
InjectionConfig cfg = new InjectionConfig() {
// map.put("queryDtoPackage", PARENT + ".dto.query");
// 在.ftl(或者是.vm)模板中,通过${cfg.queryDtoPackage}获取属性
@Override
public void initMap() {
// 自定义生成模板参数
Map<String, Object> map = new HashMap<>();
map.put("parentPackage", PARENT);
map.put("queryDtoPackage", PARENT + ".dto.query");
map.put("addDtoPackage", PARENT + ".dto.add");
map.put("updateDtoPackage", PARENT + ".dto.update");
map.put("voPackage", PARENT + ".vo");
map.put("dtoIgnoreFields", DTO_IGNORE_FIELD);
this.setMap(map);
}
};
// 自定义输出文件配置
List<FileOutConfig> fileOutConfigList = new ArrayList<>();
// queryDTO
fileOutConfigList.add(new FileOutConfig("templates/queryDTO.java.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return path + "dto/query/" + tableInfo.getEntityName() + "QueryDTO" + StringPool.DOT_JAVA;
}
});
// addDTO
fileOutConfigList.add(new FileOutConfig("templates/addDTO.java.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return path + "dto/add/" + tableInfo.getEntityName() + "AddDTO" + StringPool.DOT_JAVA;
}
});
// updateDTO
fileOutConfigList.add(new FileOutConfig("templates/updateDTO.java.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return path + "dto/update/" + tableInfo.getEntityName() + "UpdateDTO" + StringPool.DOT_JAVA;
}
});
// vo
fileOutConfigList.add(new FileOutConfig("templates/vo.java.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return path + "vo/" + tableInfo.getEntityName() + "VO" + StringPool.DOT_JAVA;
}
});
cfg.setFileOutConfigList(fileOutConfigList);
mpg.setCfg(cfg);
// 自定义配置模板
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setController("templates/controller.java");
templateConfig.setService("templates/service.java");
templateConfig.setServiceImpl("templates/serviceImpl.java");
templateConfig.setMapper("templates/mapper.java");
mpg.setTemplate(templateConfig);
// 生成代码
mpg.execute();
}
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入" + tip + ":");
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotBlank(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("请输入正确的" + tip + "!");
}
}
addDTO.java.vm
package ${cfg.addDtoPackage};
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
#foreach($field in ${table.fields})
#if(${field.propertyType} == "Date")
import java.util.Date;
#break
#end
#end
/**
* $!{table.comment} 创建DTO
*
* @author ${author}
* @since ${date}
*/
@Data
@ApiModel(value = "${entity}对象", description = "$!{table.comment}")
#set($ignoreFields = ${cfg.dtoIgnoreFields})
public class ${entity}AddDTO {
## ---------- BEGIN 字段循环遍历 ----------
#foreach($field in ${table.fields})
#set($flag = "0")
#foreach($ignoreName in ${cfg.dtoIgnoreFields.split(",")})
#if("$ignoreName" == "${field.propertyName}")
#set($flag = "1")
#break
#end
#end
#if($flag != "1")
#if(${field.keyFlag})
#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")
#if(${swagger2})
@ApiModelProperty(value = "${field.comment}")
#else
/**
* ${field.comment}
*/
#end
#end
private ${field.propertyType} ${field.propertyName};
#end
#end
}
queryDTO.java.vm
package ${cfg.queryDtoPackage};
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
#foreach($field in ${table.fields})
#if(${field.propertyType} == "Date")
import java.util.Date;
#break
#end
#end
/**
* $!{table.comment} 查询条件
*
* @author ${author}
* @since ${date}
*/
@Data
@ApiModel(value = "${entity}对象", description = "$!{table.comment}")
public class ${entity}QueryDTO {
## ---------- BEGIN 字段循环遍历 ----------
#foreach($field in ${table.fields})
#if(${field.keyFlag})
#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")
#if(${swagger2})
@ApiModelProperty(value = "${field.comment}")
#else
/**
* ${field.comment}
*/
#end
#end
private ${field.propertyType} ${field.propertyName};
#end
}
service.java.vm
package ${package.Service};
import ${cfg.parentPackage}.dto.${entity}AddDTO;
import ${cfg.parentPackage}.dto.${entity}UpdateDTO;
import ${cfg.parentPackage}.dto.${entity}QueryDTO;
import ${package.Entity}.${entity};
import ${cfg.parentPackage}.vo.${entity}VO;
import com.github.yulichang.base.MPJBaseService;
import java.util.List;
/**
* $!{table.comment} 服务类
*
* @author ${author}
* @since ${date}
*/
public interface ${entity}Service extends MPJBaseService<${entity}> {
/**
* ${table.comment}-添加
*
* @param addDTO 添加参数
* @return 添加结果
*/
${entity}VO add(${entity}AddDTO addDTO);
/**
* ${table.comment}-删除
*
* @param id 主键
* @return 删除结果
*/
Boolean delete(Integer id);
/**
* ${table.comment}-修改
*
* @param id 主键
* @param updateDTO 修改参数
* @return 修改结果
*/
${entity}VO update(Integer id, ${entity}UpdateDTO updateDTO);
/**
* ${table.comment}-详情
*
* @param id 主键
* @return 详情
*/
${entity}VO detail(Integer id);
/**
* ${table.comment}-列表
*
* @param queryDTO 查询参数
* @return 列表
*/
List<${entity}VO> list(${entity}QueryDTO queryDTO);
}
serviceImpl.java.vm
package ${package.Service};
import ${cfg.parentPackage}.dto.${entity}AddDTO;
import ${cfg.parentPackage}.dto.${entity}UpdateDTO;
import ${cfg.parentPackage}.entity.${entity};
import ${cfg.parentPackage}.mapper.${entity}Mapper;
import ${cfg.parentPackage}.vo.${entity}VO;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.springframework.beans.BeanUtils;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* $!{table.comment} 服务实现类
*
* @author ${author}
* @since ${date}
*/
@Service
public class ${entity}ServiceImpl extends MPJBaseServiceImpl<${entity}Mapper, ${entity}> implements ${entity}Service {
/**
* ${table.comment}-添加
*
* @param addDTO 添加参数
* @return ${entity}VO
*/
@Override
public ${entity}VO add(${entity}AddDTO addDTO){
${entity} ${table.entityPath} = new ${entity}();
BeanUtils.copyProperties(addDTO, ${table.entityPath});
save(${table.entityPath});
return detail(${table.entityPath}.getId());
}
/**
* ${table.comment}-删除
*
* @param id 主键
* @return 是否成功
*/
@Override
public Boolean delete(Integer id) {
return removeById(id);
}
/**
* ${table.comment}-修改
*
* @param id 主键
* @param updateDTO 修改参数
* @return ${entity}VO
*/
public ${entity}VO update(Integer id, ${entity}UpdateDTO updateDTO){
${entity} ${table.entityPath} = new ${entity}();
BeanUtils.copyProperties(updateDTO, ${table.entityPath});
${table.entityPath}.setId(id);
updateById(${table.entityPath});
return detail(id);
}
/**
* ${table.comment}-详情
*
* @param id 主键
* @return ${entity}VO
*/
@Override
public ${entity}VO detail(Integer id){
${entity} detail = getById(id);
${entity}VO ${table.entityPath}VO = new ${entity}VO();
BeanUtils.copyProperties(detail, ${table.entityPath}VO);
return ${table.entityPath}VO;
}
/**
* ${table.comment}-列表
*
* @param queryDTO 查询参数
* @return ${entity}VO
*/
@Override
public List<${entity}VO> list(${entity}QueryDTO queryDTO){
MPJLambdaWrapper<${entity}> wrapper = new MPJLambdaWrapper<${entity}>()
.selectAll(${entity}.class)
#foreach($field in ${table.fields})
#set($name = ${field.propertyName})
#set($capitalizedName = $name.substring(0, 1).toUpperCase() + $name.substring(1))
.like(ObjectUtil.isNotNull(queryDTO.get$capitalizedName()), ${entity}::get$capitalizedName, queryDTO.get$capitalizedName())
#end
.orderByDesc(${entity}::getId);
return selectJoinList(${entity}VO.class, wrapper);
}
}