苞米豆mybatis-plus generator代码生成器3.5.1版本 Freemarker引擎

该版本是号是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 controllerMappingHyphenStyle??>${controllerMappingHyphen}<#else>${table.entityPath}")
<#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 date != "">
 * @since ${date}

 */
@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>

你可能感兴趣的:(代码模板,java,开发语言,后端)