该版本是号是3.5.1,与之前版本不兼容
分为两种方式:第一种是单模块,或者只有父模块,模块名可填;第二种是多模块,需要配置模块名称,父包名,各层独立包名。
controller层可以自定义返回封装类,其他不用修改
以下是依赖版本:
pom
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.5.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
gradle
// https://mvnrepository.com/artifact/com.baomidou/mybatis-plus
implementation group: 'com.baomidou', name: 'mybatis-plus', version: '3.5.0'
// https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter
implementation group: 'com.baomidou', name: 'mybatis-plus-boot-starter', version: '3.5.0'
// https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator
implementation group: 'com.baomidou', name: 'mybatis-plus-generator', version: '3.5.1'
// https://mvnrepository.com/artifact/com.alibaba/fastjson
implementation group: 'com.alibaba', name: 'fastjson', version: '1.2.79'
// https://mvnrepository.com/artifact/org.freemarker/freemarker
implementation group: 'org.freemarker', name: 'freemarker', version: '2.3.31'
单模块生成配置
package com.eidos.mephiste;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import org.apache.commons.lang3.StringUtils;
import java.util.Collections;
/**
* 单模块代码自动生成器
* mybatis-plus-generator 3.5.1
*
* @author :eidos.mephiste
* @version : 1.0
* @date :Created in 2022/1/12
* @description :
* @modified By :
*/
public class SimpleModuleCodeGenerator {
public static void main(String[] args) {
String database = "localhost:3306/test";
String username = "root";
String password = "123456";
String[] tables = new String[]{"user_test"};
String parentPackageName = "com.eidos.mephiste";
String moduleName = "generator";
simpleModuleCodeGenerator(database, username, password, tables, parentPackageName, moduleName);
}
/**
* 单模块代码自动生成器
*
* @param database 数据库连接: IP:PORT/实例名
* @param username 数据库用户名
* @param password 数据库密码
* @param tables 表名 (字符串数组)
* @param parentPackageName 父包名
* @param moduleName 模块名称(如果没有则为空)
*/
public static void simpleModuleCodeGenerator(String database, String username, String password, String[] tables, String parentPackageName, String moduleName) {
StringBuffer outPutDir = new StringBuffer(System.getProperty("user.dir"));
if (StringUtils.isNotBlank(moduleName)) {
outPutDir.append("/").append(moduleName);
}
// 包路径
String packagePath = outPutDir + "/src/main/java";
// XML文件的路径
String mapperXmlPath = outPutDir + "/src/main/resources/mapper";
// 数据源配置
StringBuffer url = new StringBuffer();
url.append("jdbc:mysql://").append(database).append("?characterEncoding=UTF-8&useSSL=false&useUnicode=true&serverTimezone=UTC");
FastAutoGenerator.create(url.toString(), username, password)
.globalConfig(builder -> builder
// 作者名称
.author("eidos.mephiste")
// 开启覆盖已生成的文件。注释掉则关闭覆盖。
//.fileOverride()
// 禁止打开输出目录。注释掉则生成完毕后,自动打开生成的文件目录。
.disableOpenDir()
// 指定输出目录。多模块不指定
.outputDir(packagePath)
// 开启swagger2.注释掉则默认关闭。
.enableSwagger()
// 指定时间策略。
.dateType(DateType.ONLY_DATE)
// 注释时间策略。
.commentDate("yyyy-MM-dd HH:mm:ss")
)
.packageConfig(builder -> builder
// 设置父包名
.parent(parentPackageName)
// 设置父包模块名
//.moduleName("system")
// mapper.xml 文件的路径。单模块下,其他文件路径默认即可。
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, mapperXmlPath))
)
.strategyConfig(builder -> builder
// 表名
.addInclude(tables)
// 阶段1:Entity实体类策略配置
.entityBuilder()
// 设置父类。会在生成的实体类名后:extends BaseEntity
// .superClass(BaseEntity.class)
// 生成 serialVersionUID。(不推荐禁用)
//.disableSerialVersionUID()
// 开启生成字段常量。
//.enableColumnConstant()
// 开启链式模型。
.enableChainModel()
// 开启 lombok 模型。
.enableLombok()
// 开启 Boolean 类型字段移除 is 前缀。
.enableRemoveIsPrefix()
// 开启生成实体时生成字段注解。
// 会在实体类的属性前,添加[@TableField("nickname")]
.enableTableFieldAnnotation()
// 逻辑删除字段名(数据库)。
//.logicDeleteColumnName("is_delete")
// 逻辑删除属性名(实体)。
// 会在实体类的该字段属性前加注解[@TableLogic]
//.logicDeletePropertyName("isDelete")
// 数据库表映射到实体的命名策略(默认下划线转驼峰)。一般不用设置
.naming(NamingStrategy.underline_to_camel)
// 数据库表字段映射到实体的命名策略(默认为 null,未指定按照 naming 执行)。一般不用设置
.columnNaming(NamingStrategy.underline_to_camel)
// 添加父类公共字段。
// 这些字段不会出现在新增的实体类中。
//.addSuperEntityColumns("id", "delete_time")
// 添加忽略字段。
// 这些字段不会出现在新增的实体类中。
// .addIgnoreColumns("password")
// 添加表字段填充
// 会在实体类的该字段上追加注解[@TableField(value = "create_time", fill = FieldFill.INSERT)]
.addTableFills(new Column("create_time", FieldFill.INSERT))
// 会在实体类的该字段上追加注解[@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)]
.addTableFills(new Column("update_time", FieldFill.INSERT_UPDATE))
// 全局主键类型。如果MySQL主键设置为自增,则不需要设置此项。
.idType(IdType.AUTO)
// 格式化文件名称。
// 如果不设置,如表[sys_user]的实体类名是[SysUser]。设置成下面这样,将是[SysUserEntity]
//.formatFileName("%sEntity")
// 阶段2:Mapper策略配置
.mapperBuilder()
// 设置父类
// 会在mapper接口方法集成[extends BaseMapper]
// .superClass(BaseMapper.class)
// 启用 BaseResultMap 生成。
// 会在mapper.xml文件生成[通用查询映射结果]配置。
.enableBaseResultMap()
// 启用 BaseColumnList。
// 会在mapper.xml文件生成[通用查询结果列 ]配置
.enableBaseColumnList()
// 设置缓存实现类
// .cache(MyMapperCache.class)
// 格式化 mapper 文件名称。
// 如果不设置,如表[sys_user],默认的文件名是[SysUserMapper]。写成下面这种形式后,将变成[SysUserDao]。
// .formatMapperFileName("%sDao")
// 格式化 xml 实现类文件名称。
// 如果不设置,如表[sys_user],默认的文件名是[SysUserMapper.xml],写成下面这种形式后,将变成[SysUserXml.xml]。
// .formatXmlFileName("%sXml")
// 阶段3:Service策略配置
// .serviceBuilder()
// 设置 service 接口父类
// .superServiceClass(BaseService.class)
// 设置 service 实现类父类
// .superServiceImplClass(BaseServiceImpl.class)
// 格式化 service 接口文件名称
// 如果不设置,如表[sys_user],默认的是[ISysUserService]。写成下面这种形式后,将变成[SysUserService]。
// .formatServiceFileName("%sService")
// 格式化 service 实现类文件名称
// 如果不设置,如表[sys_user],默认的是[SysUserServiceImpl]。
// .formatServiceImplFileName("%sServiceImpl")
// 阶段4:Controller策略配置
.controllerBuilder()
// 设置父类。
// 会集成此父类。
// .superClass(BaseController.class)
// 开启生成 @RestController 控制器
// 会在控制类中加[@RestController]注解。
.enableRestStyle()
// 开启驼峰转连字符
.enableHyphenStyle()
)
.templateConfig(builder -> builder
// 自定义模板:https://github.com/baomidou/generator/tree/develop/mybatis-plus-generator/src/main/resources/templates
.entity("/freemarker/entity.java")
.mapper("/freemarker/mapper.java")
.mapperXml("/freemarker/mapper.xml")
.service("/freemarker/service.java")
.serviceImpl("/freemarker/serviceImpl.java")
.controller("/freemarker/controller.java")
)
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
多模块生成配置
package com.eidos.mephiste;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
/**
* @author :eidos.mephiste
* @version : 1.0
* @date :Created in 2022/1/14
* @description :
* @modified By :
*/
public class MultipleModuleCodeGenerator {
// 基础信息配置
// 数据库连接字符
private static final String URL = "jdbc:mysql://localhost:3306/test?useUnicode=true&serverTimezone=UTC&useSSL=false&characterEncoding=utf8";
// 数据库用户名
private static final String USERNAME = "root";
// 数据库密码
private static final String PASSWORD = "123456";
// 项目根路径。生成结果如:D:\MyProject\spring-boot
private static final String projectRootPath = System.getProperty("user.dir");
// 父包名。用于生成的java文件的import。
//private static final String parentPackageName = "com.eidos.mephiste";
public static void main(String[] args) {
String database = "localhost:3306/test";
String username = "root";
String password = "123456";
String[] tables = new String[]{"user_test"};
//统一父包名
String parentPackageName = "com.eidos.mephiste";
// 实体模块名称
String entityModule = "entity";
// mapper模块名称
String mapperModule = "mapper";
// service模块名称
String serviceModule = "service";
// controller模块名称
String controllerModule = "controller";
// 实体自定义包名
String entityPackage = "entity";
// manpper自定义包名
String mapperPackage = "mapper";
// service自定义包名
String servicePackage = "service";
// controller自定义包名
String controllerPackage = "controller";
multipleModuleCodeGenerator(database, username, password, tables, parentPackageName, entityModule, entityPackage, mapperModule, mapperPackage, serviceModule, servicePackage, controllerModule, controllerPackage);
}
/**
* 多模块代码自动生成器
*
* @param database
* @param username
* @param password
* @param tables
* @param parentPackageName
* @param entityModule
* @param mapperModule
* @param serviceModule
* @param controllerModule
*/
public static void multipleModuleCodeGenerator(String database, String username, String password, String[] tables, String parentPackageName,
String entityModule, String entityPackage, String mapperModule, String mapperPackage,
String serviceModule, String servicePackage, String controllerModule, String controllerPackage) {
// 基础路径配置。多模块项目下,一般来说每个文件的路径都是不同的(根据项目实际,可能在不同的模块下)。
String packagePath = StringUtils.replace(parentPackageName, ".", "/");
String entityTemp = StringUtils.replace(entityPackage, ".", "/");
String mapperTemp = StringUtils.replace(mapperPackage, ".", "/");
String serviceTemp = StringUtils.replace(servicePackage, ".", "/");
String serviceImplTemp = StringUtils.replace(servicePackage + ".impl", ".", "/");
String controllerTemp = StringUtils.replace(controllerPackage, ".", "/");
String entityPath = projectRootPath + "/" + entityModule + "/src/main/java/" + packagePath + "/" + entityTemp;
String mapperPath = projectRootPath + "/" + mapperModule + "/src/main/java/" + packagePath + "/" + mapperTemp;
String mapperXmlPath = projectRootPath + "/" + mapperModule + "/src/main/resources/mapper";
String servicePath = projectRootPath + "/" + serviceModule + "/src/main/java/" + packagePath + "/" + serviceTemp;
String serviceImplPath =
projectRootPath + "/" + serviceModule + "/src/main/java/" + packagePath + "/" + serviceImplTemp;
String controllerPath = projectRootPath + "/" + controllerModule + "/src/main/java/" + packagePath + "/" + controllerTemp;
// 数据源配置
StringBuffer url = new StringBuffer();
url.append("jdbc:mysql://").append(database).append("?characterEncoding=UTF-8&useSSL=false&useUnicode=true&serverTimezone=UTC");
FastAutoGenerator.create(url.toString(), username, password)
.globalConfig(builder -> builder
// 作者名称
.author("eidos.mephiste")
// 开启覆盖已生成的文件。注释掉则关闭覆盖。
// .fileOverride()
// 禁止打开输出目录。注释掉则生成完毕后,自动打开生成的文件目录。
.disableOpenDir()
// 指定输出目录。如果指定,Windows生成至D盘根目录下,Linux or MAC 生成至 /tmp 目录下。多模块不指定
//.outputDir("")
// 开启swagger2.注释掉则默认关闭。
.enableSwagger()
// 指定时间策略。
.dateType(DateType.ONLY_DATE)
// 注释时间策略。
.commentDate("yyyy-MM-dd HH:mm:ss")
)
.packageConfig(builder -> builder
// 设置父包名
.parent(StringUtils.replace(parentPackageName, "/", "."))
// 设置父包模块名
//.moduleName("web")
.pathInfo(
new HashMap<OutputFile, String>() {{
// 实体类的保存路径
put(OutputFile.entity, entityPath);
// mapper接口的保存路径
put(OutputFile.mapper, mapperPath);
// mapper.xml文件的保存路径
put(OutputFile.mapperXml, mapperXmlPath);
// service层接口的保存路径
put(OutputFile.service, servicePath);
// service层接口实现类的保存路径
put(OutputFile.serviceImpl, serviceImplPath);
// 控制类的保存路径
put(OutputFile.controller, controllerPath);
}}
)
)
.strategyConfig(builder -> builder
// 表名
.addInclude(tables)
// 阶段1:Entity实体类策略配置
.entityBuilder()
// 设置父类。会在生成的实体类名后:extends BaseEntity
// .superClass(BaseEntity.class)
// 生成 serialVersionUID。(不推荐禁用)
//.disableSerialVersionUID()
// 开启生成字段常量。
// 会在实体类末尾生成一系列 [public static final String NICKNAME = "nickname";] 的语句。(一般在写wapper时,会用到)
//.enableColumnConstant()
// 开启链式模型。
// 会在实体类前添加 [@Accessors(chain = true)] 注解。用法如 [User user=new User().setAge(31).setName("snzl");](这是Lombok的注解,需要添加Lombok依赖)
.enableChainModel()
// 开启 lombok 模型。
// 会在实体类前添加 [@Getter] 和 [@Setter] 注解。(这是Lombok的注解,需要添加Lombok依赖)
.enableLombok()
// 开启 Boolean 类型字段移除 is 前缀。
.enableRemoveIsPrefix()
// 开启生成实体时生成字段注解。
// 会在实体类的属性前,添加[@TableField("nickname")]
.enableTableFieldAnnotation()
// 逻辑删除字段名(数据库)。
//.logicDeleteColumnName("is_delete")
// 逻辑删除属性名(实体)。
// 会在实体类的该字段属性前加注解[@TableLogic]
//.logicDeletePropertyName("isDelete")
// 数据库表映射到实体的命名策略(默认下划线转驼峰)。一般不用设置
.naming(NamingStrategy.underline_to_camel)
// 数据库表字段映射到实体的命名策略(默认为 null,未指定按照 naming 执行)。一般不用设置
.columnNaming(NamingStrategy.underline_to_camel)
// 添加父类公共字段。
// 这些字段不会出现在新增的实体类中。
//.addSuperEntityColumns("id", "delete_time")
// 添加忽略字段。
// 这些字段不会出现在新增的实体类中。
// .addIgnoreColumns("password")
// 添加表字段填充
// 会在实体类的该字段上追加注解[@TableField(value = "create_time", fill = FieldFill.INSERT)]
.addTableFills(new Column("create_time", FieldFill.INSERT))
// 会在实体类的该字段上追加注解[@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)]
.addTableFills(new Column("update_time", FieldFill.INSERT_UPDATE))
// 全局主键类型。如果MySQL主键设置为自增,则不需要设置此项。
.idType(IdType.AUTO)
// 格式化文件名称。
// 如果不设置,如表[sys_user]的实体类名是[SysUser]。设置成下面这样,将是[SysUserEntity]
//.formatFileName("%sEntity")
// 阶段2:Mapper策略配置
.mapperBuilder()
// 设置父类
// 会在mapper接口方法集成[extends BaseMapper]
// .superClass(BaseMapper.class)
// 启用 BaseResultMap 生成。
// 会在mapper.xml文件生成[通用查询映射结果]配置。
.enableBaseResultMap()
// 启用 BaseColumnList。
// 会在mapper.xml文件生成[通用查询结果列 ]配置
.enableBaseColumnList()
// 设置缓存实现类
// .cache(MyMapperCache.class)
// 格式化 mapper 文件名称。
// 如果不设置,如表[sys_user],默认的文件名是[SysUserMapper]。写成下面这种形式后,将变成[SysUserDao]。
// .formatMapperFileName("%sDao")
// 格式化 xml 实现类文件名称。
// 如果不设置,如表[sys_user],默认的文件名是[SysUserMapper.xml],写成下面这种形式后,将变成[SysUserXml.xml]。
// .formatXmlFileName("%sXml")
// 阶段3:Service策略配置
// .serviceBuilder()
// 设置 service 接口父类
// .superServiceClass(BaseService.class)
// 设置 service 实现类父类
// .superServiceImplClass(BaseServiceImpl.class)
// 格式化 service 接口文件名称
// 如果不设置,如表[sys_user],默认的是[ISysUserService]。写成下面这种形式后,将变成[SysUserService]。
// .formatServiceFileName("%sService")
// 格式化 service 实现类文件名称
// 如果不设置,如表[sys_user],默认的是[SysUserServiceImpl]。
// .formatServiceImplFileName("%sServiceImpl")
// 阶段4:Controller策略配置
.controllerBuilder()
// 设置父类。
// 会集成此父类。
// .superClass(BaseController.class)
// 开启生成 @RestController 控制器
// 会在控制类中加[@RestController]注解。
.enableRestStyle()
// 开启驼峰转连字符
.enableHyphenStyle()
)
.templateConfig(builder -> builder
// 自定义模板:https://github.com/baomidou/generator/tree/develop/mybatis-plus-generator/src/main/resources/templates
.entity("/freemarker/entity.java")
.mapper("/freemarker/mapper.java")
.mapperXml("/freemarker/mapper.xml")
.service("/freemarker/service.java")
.serviceImpl("/freemarker/serviceImpl.java")
.controller("/freemarker/controller.java")
)
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
Freemarker模板引擎
controller.java.ftl
package ${package.Controller};
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import ${package.Service}.${table.serviceName};
import com.mephiste.eidos.framework.api.common.Response;
import com.mephiste.eidos.framework.api.common.ResponseWrapper;
import ${package.Entity}.${entity};
<#if superControllerClassPackage??>
import ${superControllerClassPackage};
</#if>
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* @author : ${author}
* @date :Created in ${date}
* @description:${table.comment!} 服务类
* @modified By:
* @version: 1.0
*/
@Api(tags = "${table.comment!}管理")
@Slf4j
@RequestMapping("<#if package.ModuleName?? && package.ModuleName != "">/${package.ModuleName}#if>/<#if controllerMappingHyphenStyle??>${controllerMappingHyphen}<#else>${table.entityPath}#if>")
<#if restControllerStyle>
@RestController
<#else>
@Controller
</#if>
<#if kotlin>
class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}()</#if>
<#else>
<#if superControllerClass??>
<#else>
public class ${table.controllerName} {
</#if>
@Resource
private ${table.serviceName} ${table.serviceName?uncap_first};
@ApiOperation(value = "${table.comment!} 分页列表", notes = "${table.comment!} 分页列表")
@PostMapping(value = "/v1/page", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public Response<Page<${entity}>> page(@Validated @RequestBody PageDTO pageDTO) {
return ResponseWrapper.ok(${table.serviceName?uncap_first}.page(pageDTO));
}
@ApiOperation(value = "${table.comment!} 新增", notes = "${table.comment!} 新增")
@PostMapping(value = "/v1/add", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public Response<${entity}> add(@Validated @RequestBody ${entity} ${entity?uncap_first}) {
return ResponseWrapper.ok(${table.serviceName?uncap_first}.add(${entity?uncap_first}));
}
@ApiOperation(value = "${table.comment!} 更新", notes = "${table.comment!} 更新")
@PostMapping(value = "/v1/update", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public Response<Boolean> update(@Validated @RequestBody ${entity} ${entity?uncap_first}) {
return ResponseWrapper.ok(${table.serviceName?uncap_first}.update(${entity?uncap_first}));
}
@ApiOperation(value = "${table.comment!} 详情", notes = "${table.comment!} 详情")
@GetMapping(value = "/v1/detail/{id}")
public Response<${entity}> detail(Long id) {
return ResponseWrapper.ok(${table.serviceName?uncap_first}.detail(id));
}
@ApiOperation(value = "${table.comment!} 根据主键ID删除", notes = "${table.comment!} 根据主键ID删除")
@GetMapping(value = "/v1/delete/{ids}")
public Response<Boolean> delete(Long id) {
return ResponseWrapper.ok(${table.serviceName?uncap_first}.delete(id));
}
@ApiOperation(value = "${table.comment!} 批量删除", notes = "${table.comment!} 批量删除")
@GetMapping(value = "/v1/batchDelete/{ids}")
public Response<Boolean> batchDelete(String ids) {
return ResponseWrapper.ok(${table.serviceName?uncap_first}.batchDelete(ids));
}
}
</#if>
entity.java.ftl
package ${package.Entity};
<#list table.importPackages as pkg>
import ${pkg};
</#list>
<#if swagger??>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel??>
import lombok.*;
<#if chainModel??>
import lombok.experimental.Accessors;
</#if>
</#if>
/**
* @author : ${author}
* @date :Created in ${date}
* @description:${table.comment!} 实体类
* @modified By:
* @version: 1.0
*/
<#if table.convert??>
@TableName("${table.name}")
</#if>
<#if entityLombokModel>
<#if superEntityClass??>
@EqualsAndHashCode(callSuper = true)
<#else>
@EqualsAndHashCode(callSuper = false)
</#if>
<#if chainModel??>
@Accessors(chain = true)
</#if>
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
</#if>
<#--<#if swagger??>-->
@ApiModel(value = "${entity} 实体", description = "${table.comment!}")
<#--</#if>-->
<#if superEntityClass??>
public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}></#if> implements Serializable{
<#elseif activeRecord>
public class ${entity} extends Model<${entity}> implements Serializable{
<#else>
public class ${entity} <#if entitySerialVersionUID>implements Serializable</#if> {
</#if>
<#if entitySerialVersionUID>
private static final long serialVersionUID = 1L;
</#if>
<#-- ---------- BEGIN 字段循环遍历 -------- -->
<#list table.fields as field>
<#-- 排除公共字段 -->
<#-- <#if field.propertyName != 'id' && field.propertyName != 'delFlag' && field.propertyName != 'createdTime' && field.propertyName != 'createdBy' && field.propertyName != 'updatedTime' && field.propertyName != 'updatedBy' && field.propertyName != 'remark'>-->
/**
* ${field.comment}
*/
<#if field.keyFlag>
<#assign keyPropertyName="${field.propertyName}"/>
</#if>
<#if swagger??>
@ApiModelProperty("${field.comment}")
</#if>
<#if field.keyFlag>
<#-- 主键 -->
<#if field.keyIdentityFlag>
@TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
<#elseif idType??>
@TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
<#elseif field.convert>
@TableId("${field.annotationColumnName}")
</#if>
<#-- 普通字段 -->
<#elseif field.fill??>
<#-- ----- 存在字段填充设置 ----->
<#if field.convert>
@TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
<#else>
@TableField(fill = FieldFill.${field.fill})
</#if>
<#elseif field.convert>
@TableField("${field.annotationColumnName}")
</#if>
<#-- 乐观锁注解 -->
<#if field.versionField>
@Version
</#if>
<#-- 逻辑删除注解 -->
<#if field.logicDeleteField>
@TableLogic
</#if>
private ${field.propertyType} ${field.propertyName};
<#-- </#if>-->
</#list>
<#-- ---------- END 字段循环遍历 -------- -->
<#-- Lombok 模式 -->
<#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 chainModel>
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 chainModel>
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 com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import ${package.Entity}.${entity};
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* @author : ${author}
* @date :Created in ${date}
* @description:${table.comment!} Mapper 接口
* @modified By:
* @version: 1.0
*/
@Mapper
public interface ${table.mapperName} extends BaseMapper<${entity}> {
/**
* 分页查询
*
* @param page
* @param pageDTO
* @return
*/
Page<${entity}> getPage(@Param("page") Page<${entity}> page, @Param("dto") PageDTO pageDTO);
}
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>
<select id="getPage" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List"/>
FROM ${table.name}
</select>
</mapper>
service.java.ftl
package ${package.Service};
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import ${package.Entity}.${entity};
/**
* @author : ${author}
* @date :Created in ${date}
* @description:${table.comment!} 服务类
* @modified By:
* @version: 1.0
*/
<#if kotlin>
interface ${table.serviceName} : ${superServiceClass}<${entity}>
<#else>
public interface ${table.serviceName} {
/**
* ${table.comment!} 分页列表
*
* @param pageDTO
* @return
*/
Page<${entity}> page(PageDTO pageDTO);
/**
* ${table.comment!} 新增
*
* @param ${entity?uncap_first}
* @return
*/
${entity} add(${entity} ${entity?uncap_first});
/**
* ${table.comment!} 更新
*
* @param ${entity?uncap_first}
* @return
*/
Boolean update(${entity} ${entity?uncap_first});
/**
* ${table.comment!} 详情
*
* @param id
* @return
*/
${entity} detail(Long id);
/**
* ${table.comment!} 根据主键ID删除
*
* @param id 主键ID
* @return
*/
Boolean delete(Long id);
/**
* ${table.comment!} 批量删除
*
* @param ids 主键ID 以逗号隔开
* @return
*/
Boolean batchDelete(String ids);
}
</#if>
serviceImpl.java.ftl
package ${package.ServiceImpl};
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import ${superServiceImplClassPackage};
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* ${table.comment!} 服务实现
*
<#if author != "">
* @author ${author}
#if>
<#if date != "">
* @since ${date}
#if>
*/
@Service
<#if kotlin>
open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {
}
<#else>
@Slf4j
public class ${table.serviceImplName} extends ServiceImpl<${table.mapperName}, ${entity}> {
@Override
public IPage<${entity}> page(PageDTO pageDTO) {
// 第一种分页
Page<${entity}> page = new Page<>(pageDTO.getCurrent(), pageDTO.getSize());
//QueryWrapper<${entity}> wrapper = new QueryWrapper();
//return baseMapper.selectPage(page, wrapper);
// 第二种分页
return baseMapper.getPageList(page,pageDTO);
}
@Override
@Transactional(rollbackFor = {Exception.class, RuntimeException.class, MybatisPlusException.class})
public ${entity} add(${entity} ${entity?uncap_first}) {
if (!super.save(${entity?uncap_first})) {
log.error("save fail, 请求入参: {}" , JSONObject.toJSONString(${entity?uncap_first}));
throw new MybatisPlusException("操作失败");
}
return ${entity?uncap_first};
}
@Override
@Transactional(rollbackFor = {Exception.class, RuntimeException.class, MybatisPlusException.class})
public Boolean update(${entity} ${entity?uncap_first}) {
Assert.isFalse(Objects.isNull(super.getById(${entity?uncap_first}.getId())), "资源不存在");
if (!super.updateById(${entity?uncap_first})) {
log.error("updateById fail, 请求入参: {}" , JSONObject.toJSONString(${entity?uncap_first}));
throw new MybatisPlusException("操作失败");
}
return Boolean.TRUE;
}
@Override
public ${entity} detail(Long id) {
${entity} byId = super.getById(id);
Assert.isFalse(Objects.isNull(byId), "资源不存在");
return byId;
}
@Override
@Transactional(rollbackFor = {Exception.class, RuntimeException.class, MybatisPlusException.class})
public Boolean delete(Long id) {
Assert.isFalse(Objects.isNull(super.getById(id)), "资源不存在");
if (!super.removeById(id)) {
log.error("removeById fail, 请求入参: {}" , id );
throw new MybatisPlusException("操作失败");
}
return Boolean.TRUE;
}
@Override
@Transactional(rollbackFor = {Exception.class, RuntimeException.class, MybatisPlusException.class})
public Boolean batchDelete(String ids) {
Assert.isTrue(StringUtils.isNotBlank(ids), "请求参数错误");
String[] batchIds = StringUtils.split(ids, ',');
Assert.isFalse(Objects.isNull(batchIds), "请求参数错误");
Assert.isTrue(batchIds.length > 0, "请求参数错误");
QueryWrapper<${entity}> wrapper=new QueryWrapper<>();
wrapper.lambda().in(${entity}::getId,batchIds);
wrapper.last("limit 0," + batchIds.length);
List<${entity}> list = super.list(wrapper);
Assert.isTrue(CollectionUtils.isNotEmpty(list) && list.size()==batchIds.length,"请求参数关联失败");
if (!super.removeBatchByIds(Arrays.asList(batchIds))) {
log.error("removeBatchByIds fail, 请求入参: {}" , ids);
throw new MybatisPlusException("操作失败");
}
return Boolean.TRUE;
}
}
</#if>
</#if>