概要说明
MyBatis-Plus
是一个增强版的MyBatis
,旨在简化数据库开发工作。其代码生成器可以帮助开发者根据数据库表结构自动生成Entity
、Mapper
、Service
、Controller
等模块文件和代码。默认情况下,代码生成器使用Velocity
作为模板引擎。然而,开发者可以根据需求自定义模板引擎,以生成符合项目规范的代码。MyBatis-Plus
代码生成器是一个功能强大的工具,但它默认提供的模板可能无法完全满足所有项目的需求。通过自定义模板引擎,开发者可以灵活地调整生成代码的格式、结构和内容,以适应特定的编码规范或业务逻辑需求。
控制器模板
js
package ${package.Controller};
import com.xiaomayi.core.utils.R;
import com.xiaomayi.logger.annotation.RequestLog;
import com.xiaomayi.logger.enums.RequestType;
import ${packageName}.dto.${entity?lower_case}.${table.entityName}AddDTO;
import ${packageName}.dto.${entity?lower_case}.${table.entityName}ListDTO;
import ${packageName}.dto.${entity?lower_case}.${table.entityName}PageDTO;
import ${packageName}.dto.${entity?lower_case}.${table.entityName}UpdateDTO;
import ${package.Service}.${table.entityName}Service;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Collections;
import java.util.List;
<#if restControllerStyle>
import org.springframework.web.bind.annotation.RestController;
<#else>
import org.springframework.stereotype.Controller;
</#if>
<#if superControllerClassPackage??>
import ${superControllerClassPackage};
</#if>
/**
* <p>
* ${table.comment!} 前端控制器
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if restControllerStyle>
@RestController
<#else>
@Controller
</#if>
@RequestMapping("<#if package.ModuleName?? && package.ModuleName != "">/${package.ModuleName}</#if>/<#if controllerMappingHyphenStyle>${controllerMappingHyphen}<#else>${table.entityPath}</#if>")
@Tag(name = "${table.comment!}管理", description = "${table.comment!}管理")
@AllArgsConstructor
<#if kotlin>
class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}()</#if>
<#else>
<#if superControllerClass??>
public class ${table.controllerName} extends ${superControllerClass} {
<#else>
public class ${table.controllerName} {
</#if>
private final ${table.entityName}Service ${table.entityName?uncap_first}Service;
/**
* 查询分页列表
*
* @param ${table.entityName?uncap_first}PageDTO 查询条件
* @return 返回结果
*/
@Operation(summary = "查询分页列表", description = "查询分页列表")
@GetMapping("/page")
public R page(${table.entityName}PageDTO ${table.entityName?uncap_first}PageDTO) {
return R.ok(${table.entityName?uncap_first}Service.page(${table.entityName?uncap_first}PageDTO));
}
/**
* 查询数据列表
*
* @param ${table.entityName?uncap_first}ListDTO 查询条件
* @return 返回结果
*/
@Operation(summary = "查询数据列表", description = "查询数据列表")
@GetMapping("/list")
public R getList(${table.entityName}ListDTO ${table.entityName?uncap_first}ListDTO) {
return R.ok(${table.entityName?uncap_first}Service.getList(${table.entityName?uncap_first}ListDTO));
}
/**
* 根据ID查询详情
*
* @param id ${table.comment!}ID
* @return 返回结果
*/
@Operation(summary = "根据ID查询详情", description = "根据ID查询详情")
@GetMapping("/detail/{id}")
public R getDetail(@PathVariable("id") Integer id) {
return R.ok(${table.entityName?uncap_first}Service.getDetail(id));
}
/**
* 添加${table.comment!}
*
* @param ${table.entityName?uncap_first}AddDTO 参数
* @return 返回结果
*/
@Operation(summary = "添加${table.comment!}", description = "添加${table.comment!}")
@RequestLog(title = "添加${table.comment!}", type = RequestType.INSERT)
@PreAuthorize("@pms.hasAuthority('sys:${table.entityName?uncap_first}:add')")
@PostMapping("/add")
public R add(@RequestBody @Validated ${table.entityName}AddDTO ${table.entityName?uncap_first}AddDTO) {
return ${table.entityName?uncap_first}Service.add(${table.entityName?uncap_first}AddDTO);
}
/**
* 更新${table.comment!}
*
* @param ${table.entityName?uncap_first}UpdateDTO 参数
* @return 返回结果
*/
@Operation(summary = "更新${table.comment!}", description = "更新${table.comment!}")
@RequestLog(title = "更新${table.comment!}", type = RequestType.UPDATE)
@PreAuthorize("@pms.hasAuthority('sys:${table.entityName?uncap_first}:update')")
@PutMapping("/update")
public R update(@RequestBody @Validated ${table.entityName}UpdateDTO ${table.entityName?uncap_first}UpdateDTO) {
return ${table.entityName?uncap_first}Service.update(${table.entityName?uncap_first}UpdateDTO);
}
/**
* 删除${table.comment!}
*
* @param id 记录ID
* @return 返回结果
*/
@Operation(summary = "删除${table.comment!}", description = "删除${table.comment!}")
@RequestLog(title = "删除${table.comment!}", type = RequestType.DELETE)
@PreAuthorize("@pms.hasAuthority('sys:${table.entityName?uncap_first}:delete')")
@DeleteMapping("/delete/{id}")
public R delete(@PathVariable Integer id) {
return ${table.entityName?uncap_first}Service.delete(id);
}
/**
* 批量删除${table.comment!}
*
* @param idList 记录ID
* @return 返回结果
*/
@Operation(summary = "批量删除${table.comment!}", description = "批量删除${table.comment!}")
@RequestLog(title = "批量删除${table.comment!}", type = RequestType.BATCH_DELETE)
@PreAuthorize("@pms.hasAuthority('sys:${table.entityName?uncap_first}:batchDelete')")
@DeleteMapping("/batchDelete")
public R batchDelete(@RequestBody @Validated List<Integer> idList) {
return ${table.entityName?uncap_first}Service.batchDelete(idList);
}
}
</#if>
DTO参数模板
js
package ${packageName}.dto.${entity?lower_case};
<#if fileComment?contains("分页")>
import com.xiaomayi.mybatis.dto.PageDTO;
</#if>
<#if springdoc>
import io.swagger.v3.oas.annotations.media.Schema;
<#elseif swagger>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel>
import lombok.Data;
</#if>
<#if fileComment?contains("分页")>
import lombok.EqualsAndHashCode;
</#if>
<#if fileComment?contains("添加") || fileComment?contains("更新")>
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
</#if>
import java.time.LocalDateTime;
/**
* <p>
* ${table.comment!}
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if entityLombokModel>
@Data
</#if>
<#if fileComment?contains("分页")>
@EqualsAndHashCode(callSuper = true)
</#if>
<#if springdoc>
@Schema(name = "${table.comment!}${fileComment}", description = "${table.comment!}${fileComment}")
<#elseif swagger>
@ApiModel(value = "${table.comment!}", description = "${table.comment!}")
</#if>
<#if superEntityClass??>
public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}></#if> {
<#elseif activeRecord>
public class ${entity} extends Model<${entity}> {
<#elseif entitySerialVersionUID>
public class ${entity} implements Serializable {
<#else>
<#if fileComment?contains("分页")>
public class ${entity}${modelSuffix} extends PageDTO {
<#else>
public class ${entity}${modelSuffix} {
</#if>
</#if>
<#if fileComment?contains("分页") || fileComment?contains("列表")>
<#-- ---------- BEGIN 字段循环遍历 ---------->
<#list table.fields as field>
<#if field.comment?contains('名称') || field.comment?contains('标题') || field.comment?contains('状态') || field.comment?contains('类型')>
<#if field.comment!?length gt 0>
<#if springdoc>
@Schema(description = "${field.comment}")
<#elseif swagger>
@ApiModelProperty("${field.comment}")
<#else>
/**
* ${field.comment}
*/
</#if>
</#if>
private ${field.propertyType} ${field.propertyName};
</#if>
</#list>
<#------------ END 字段循环遍历 ---------->
<#elseif fileComment?contains("添加") || fileComment?contains("更新")>
<#-- ---------- BEGIN 字段循环遍历 ---------->
<#list table.fields as field>
<#if field.propertyName!="createUser" && field.propertyName!="createTime" && field.propertyName!="updateUser" && field.propertyName!="updateTime" && field.propertyName!="delFlag">
<#if fileComment?contains("添加") && field.propertyName=="id">
<#------- 添加时无主键 ------>
<#else>
<#if field.comment!?length gt 0>
<#if springdoc>
@Schema(description = "${field.comment}")
<#elseif swagger>
@ApiModelProperty("${field.comment}")
<#else>
/**
* ${field.comment}
*/
</#if>
</#if>
<#if field.columnType == "INTEGER">
@NotNull(message = "${field.comment}不能为空")
<#elseif field.columnType == "STRING">
@NotBlank(message = "${field.comment}不能为空")
</#if>
private ${field.propertyType} ${field.propertyName};
</#if>
</#if>
</#list>
<#------------ END 字段循环遍历 ---------->
</#if>
}
实体对象模板
js
package ${package.Entity};
<#list table.importPackages as pkg>
import ${pkg};
</#list>
import com.alibaba.fastjson2.annotation.JSONField;
<#if springdoc>
import io.swagger.v3.oas.annotations.media.Schema;
<#elseif swagger>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel>
import lombok.Data;
<#if chainModel>
import lombok.experimental.Accessors;
</#if>
</#if>
/**
* <p>
* ${table.comment!}
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if entityLombokModel>
@Data
<#if chainModel>
@Accessors(chain = true)
</#if>
</#if>
<#if table.convert>
@TableName("${schemaName}${table.name}")
</#if>
<#if springdoc>
@Schema(name = "${table.comment!}", description = "${table.comment!}")
<#elseif swagger>
@ApiModel(value = "${table.comment!}", description = "${table.comment!}")
</#if>
<#if superEntityClass??>
public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}></#if> {
<#elseif activeRecord>
public class ${entity} extends Model<${entity}> {
<#elseif entitySerialVersionUID>
public class ${entity} implements Serializable {
<#else>
public class ${entity} {
</#if>
<#if entitySerialVersionUID>
private static final long serialVersionUID = 1L;
</#if>
<#-- ---------- BEGIN 字段循环遍历 ---------->
<#list table.fields as field>
<#if field.keyFlag>
<#assign keyPropertyName="${field.propertyName}"/>
</#if>
<#if field.comment!?length gt 0>
<#if springdoc>
@Schema(description = "${field.comment}")
<#elseif swagger>
@ApiModelProperty("${field.comment}")
<#else>
/**
* ${field.comment}
*/
</#if>
</#if>
<#if field.propertyType == 'LocalDateTime'>
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
</#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};
</#list>
<#------------ END 字段循环遍历 ---------->
<#if !entityLombokModel>
<#list table.fields as field>
<#if field.propertyType == "boolean">
<#assign getprefix="is"/>
<#else>
<#assign getprefix="get"/>
</#if>
public ${field.propertyType} ${getprefix}${field.capitalName}() {
return ${field.propertyName};
}
<#if 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
public 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>
}
DAO模板
js
package ${package.Mapper};
import ${package.Entity}.${entity};
import ${superMapperClassPackage};
<#if mapperAnnotationClass??>
import ${mapperAnnotationClass.name};
</#if>
/**
* <p>
* ${table.comment!} Mapper 接口
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if mapperAnnotationClass??>
@${mapperAnnotationClass.simpleName}
</#if>
<#if kotlin>
interface ${table.mapperName} : ${superMapperClass}<${entity}>
<#else>
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
}
</#if>
XML文件模板
js
<?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="${cacheClassName}"/>
</#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.columnName},
</#list>
${table.fieldNames}
</sql>
</#if>
</mapper>
接口模板
js
package ${package.Service};
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaomayi.core.utils.R;
import ${packageName}.dto.${entity?lower_case}.${table.entityName}AddDTO;
import ${packageName}.dto.${entity?lower_case}.${table.entityName}ListDTO;
import ${packageName}.dto.${entity?lower_case}.${table.entityName}PageDTO;
import ${packageName}.dto.${entity?lower_case}.${table.entityName}UpdateDTO;
import ${package.Entity}.${entity};
import ${superServiceClassPackage};
import ${packageName}.vo.${entity?lower_case}.${table.entityName}InfoVO;
import java.util.List;
/**
* <p>
* ${table.comment!} 服务类
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if kotlin>
interface ${table.serviceName} : ${superServiceClass}<${entity}>
<#else>
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
/**
* 查询分页列表
*
* @param ${table.entityName?uncap_first}PageDTO 查询条件
* @return 返回结果
*/
Page<${table.entityName}> page(${table.entityName}PageDTO ${table.entityName?uncap_first}PageDTO);
/**
* 查询数据列表
*
* @param ${table.entityName?uncap_first}ListDTO 查询条件
* @return 返回结果
*/
List<${table.entityName}> getList(${table.entityName}ListDTO ${table.entityName?uncap_first}ListDTO);
/**
* 根据ID查询信息
*
* @param id ${table.comment!}ID
* @return 返回结果
*/
${table.entityName} getInfo(Integer id);
/**
* 根据ID查询详情
*
* @param id ${table.comment!}ID
* @return 返回结果
*/
${table.entityName}InfoVO getDetail(Integer id);
/**
* 添加${table.comment!}
*
* @param ${table.entityName?uncap_first}AddDTO 参数
* @return 返回结果
*/
R add(${table.entityName}AddDTO ${table.entityName?uncap_first}AddDTO);
/**
* 更新${table.comment!}
*
* @param ${table.entityName?uncap_first}UpdateDTO 参数
* @return 返回结果
*/
R update(${table.entityName}UpdateDTO ${table.entityName?uncap_first}UpdateDTO);
/**
* 删除${table.comment!}
*
* @param id ${table.comment!}ID
* @return 返回结果
*/
R delete(Integer id);
/**
* 批量删除${table.comment!}
*
* @param idList ${table.comment!}ID
* @return 返回结果
*/
R batchDelete(List<Integer> idList);
}
</#if>
接口实现模板
js
package ${package.ServiceImpl};
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaomayi.core.utils.R;
import com.xiaomayi.core.utils.StringUtils;
import ${packageName}.dto.${entity?lower_case}.${table.entityName}AddDTO;
import ${packageName}.dto.${entity?lower_case}.${table.entityName}ListDTO;
import ${packageName}.dto.${entity?lower_case}.${table.entityName}PageDTO;
import ${packageName}.dto.${entity?lower_case}.${table.entityName}UpdateDTO;
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import ${packageName}.vo.${entity?lower_case}.${table.entityName}InfoVO;
import ${packageName}.vo.${entity?lower_case}.${table.entityName}ListVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* ${table.comment!} 服务实现类
* </p>
*
* @author ${author}
* @since ${date}
*/
@Service
<#if kotlin>
open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {
}
<#else>
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
/**
* 查询分页列表
*
* @param ${table.entityName?uncap_first}PageDTO 查询条件
* @return 返回结果
*/
@Override
public Page<${table.entityName}> page(${table.entityName}PageDTO ${table.entityName?uncap_first}PageDTO) {
// 分页设置
Page<${table.entityName}> page = new Page<>(${table.entityName?uncap_first}PageDTO.getPageNo(), ${table.entityName?uncap_first}PageDTO.getPageSize());
// 查询条件
LambdaQueryWrapper<${table.entityName}> wrapper = new LambdaQueryWrapper<${table.entityName}>()
<#-- ---------- BEGIN 字段循环遍历 ---------->
<#list table.fields as field>
<#if field.comment?contains('名称') || field.comment?contains('标题') || field.comment?contains('状态') || field.comment?contains('类型')>
<#if field.comment!?length gt 0>
// ${field.comment}
</#if>
<#if field.columnType == "INTEGER">
.eq(StringUtils.isNotNull(${table.entityName?uncap_first}PageDTO.get${field.propertyName?cap_first}()) && ${table.entityName?uncap_first}PageDTO.get${field.propertyName?cap_first}() > 0, ${table.entityName}::get${field.propertyName?cap_first}, ${table.entityName?uncap_first}PageDTO.get${field.propertyName?cap_first}())
<#elseif field.columnType == "STRING">
.like(StringUtils.isNotEmpty(${table.entityName?uncap_first}PageDTO.get${field.propertyName?cap_first}()), ${table.entityName}::get${field.propertyName?cap_first}, ${table.entityName?uncap_first}PageDTO.get${field.propertyName?cap_first}())
</#if>
</#if>
</#list>
<#------------ END 字段循环遍历 ---------->
.eq(${table.entityName}::getDelFlag, 0)
.orderByAsc(${table.entityName}::getId);
// 查询分页数据
Page<${table.entityName}> pageData = page(page, wrapper);
pageData.convert(item -> {
// 实例化VO对象
${table.entityName}ListVO ${table.entityName?uncap_first}ListVO = new ${table.entityName}ListVO();
BeanUtils.copyProperties(item, ${table.entityName?uncap_first}ListVO);
return ${table.entityName?uncap_first}ListVO;
});
// 返回结果
return pageData;
}
/**
* 查询数据列表
*
* @param ${table.entityName?uncap_first}ListDTO 查询条件
* @return 返回结果
*/
@Override
public List<${table.entityName}> getList(${table.entityName}ListDTO ${table.entityName?uncap_first}ListDTO) {
List<${table.entityName}> ${table.entityName?uncap_first}List = list(new LambdaQueryWrapper<${table.entityName}>()
.eq(${table.entityName}::getDelFlag, 0)
.orderByAsc(${table.entityName}::getId));
return ${table.entityName?uncap_first}List;
}
/**
* 根据ID查询信息
*
* @param id ${table.comment!}ID
* @return 返回结果
*/
@Override
public ${table.entityName} getInfo(Integer id) {
${table.entityName} ${table.entityName?uncap_first} = getById(id);
if (StringUtils.isNull(${table.entityName?uncap_first}) || !${table.entityName?uncap_first}.getDelFlag().equals(0)) {
return null;
}
return ${table.entityName?uncap_first};
}
/**
* 根据ID查询详情
*
* @param id ${table.comment!}ID
* @return 返回结果
*/
@Override
public ${table.entityName}InfoVO getDetail(Integer id) {
${table.entityName} ${table.entityName?uncap_first} = getInfo(id);
if (StringUtils.isNull(${table.entityName?uncap_first})) {
return null;
}
// 实例化VO
${table.entityName}InfoVO ${table.entityName?uncap_first}InfoVO = new ${table.entityName}InfoVO();
BeanUtils.copyProperties(${table.entityName?uncap_first}, ${table.entityName?uncap_first}InfoVO);
return ${table.entityName?uncap_first}InfoVO;
}
/**
* 添加${table.comment!}
*
* @param ${table.entityName?uncap_first}AddDTO 参数
* @return 返回结果
*/
@Override
public R add(${table.entityName}AddDTO ${table.entityName?uncap_first}AddDTO) {
// 实例化对象
${table.entityName} ${table.entityName?uncap_first} = new ${table.entityName}();
// 属性拷贝
BeanUtils.copyProperties(${table.entityName?uncap_first}AddDTO, ${table.entityName?uncap_first});
boolean result = save(${table.entityName?uncap_first});
if (!result) {
return R.failed();
}
return R.ok();
}
/**
* 更新${table.comment!}
*
* @param ${table.entityName?uncap_first}UpdateDTO 参数
* @return 返回结果
*/
@Override
public R update(${table.entityName}UpdateDTO ${table.entityName?uncap_first}UpdateDTO) {
// 根据ID查询信息
${table.entityName} ${table.entityName?uncap_first} = getInfo(${table.entityName?uncap_first}UpdateDTO.getId());
if (StringUtils.isNull(${table.entityName?uncap_first})) {
return R.failed("记录不存在");
}
// 属性拷贝
BeanUtils.copyProperties(${table.entityName?uncap_first}UpdateDTO, ${table.entityName?uncap_first});
boolean result = updateById(${table.entityName?uncap_first});
if (!result) {
return R.failed();
}
return R.ok();
}
/**
* 删除${table.comment!}
*
* @param id ${table.comment!}ID
* @return 返回结果
*/
@Override
public R delete(Integer id) {
// 根据ID查询信息
${table.entityName} ${table.entityName?uncap_first} = getInfo(id);
if (StringUtils.isNull(${table.entityName?uncap_first})) {
return R.failed("记录不存在");
}
// 删除
boolean result = removeById(id);
if (!result) {
return R.failed();
}
// 返回结果
return R.ok();
}
/**
* 批量删除${table.comment!}
*
* @param idList ${table.comment!}ID
* @return 返回结果
*/
@Override
public R batchDelete(List<Integer> idList) {
// 删除ID判空
if (StringUtils.isEmpty(idList)) {
return R.failed("删除记录ID不存在");
}
// 批量删除
boolean result = removeBatchByIds(idList);
if (!result) {
return R.failed();
}
return R.ok();
}
}
</#if>
VO参数模板
js
package ${packageName}.vo.${entity?lower_case};
import ${package.Entity}.${table.entityName};
<#if springdoc>
import io.swagger.v3.oas.annotations.media.Schema;
<#elseif swagger>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel>
import lombok.Data;
import lombok.EqualsAndHashCode;
</#if>
/**
* <p>
* ${table.comment!}
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if entityLombokModel>
@Data
@EqualsAndHashCode(callSuper = true)
</#if>
<#if springdoc>
@Schema(name = "${table.comment!}${fileComment}", description = "${table.comment!}${fileComment}")
<#elseif swagger>
@ApiModel(value = "${table.comment!}", description = "${table.comment!}")
</#if>
<#if superEntityClass??>
public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}></#if> {
<#elseif activeRecord>
public class ${entity}${modelSuffix} extends Model<${entity}> {
<#elseif entitySerialVersionUID>
public class ${entity} implements Serializable {
<#else>
public class ${entity}${modelSuffix} extends ${entity} {
</#if>
}
前端列表模板
ts
<template>
<PageWrapper>
<el-card :bordered="false" class="pt-3 mb-3 proCard">
<BasicForm @register="register" @submit="handleSubmit" @reset="handleReset" />
</el-card>
<el-card :bordered="false" class="proCard">
<BasicTable
:columns="columns"
:request="loadDataTable"
:row-key="(row) => row.id"
ref="tableRef"
:actionColumn="actionColumn"
@selection-change="onSelectionChange"
>
<template #tableTitle>
<el-button type="primary" @click="handleAdd" v-perm="['sys:${entity?lower_case}:add']">
<template #icon>
<el-icon class="el-input__icon">
<PlusOutlined />
</el-icon>
</template>
添加${table.comment!}
</el-button>
<el-button
type="danger"
@click="handleDelete()"
:disabled="!selectionData.length"
v-perm="['sys:${entity?lower_case}:batchDelete']"
>
<template #icon>
<el-icon class="el-input__icon">
<Delete />
</el-icon>
</template>
删除
</el-button>
</template>
</BasicTable>
</el-card>
<editDialog
v-if="editVisible"
:${entity?lower_case}Id="${entity?lower_case}Id"
v-model:visible="editVisible"
@success="reloadTable('noRefresh')"
/>
</PageWrapper>
</template>
<script lang="ts" setup>
import { reactive, ref, h, nextTick, defineAsyncComponent } from 'vue';
import { ColProps } from 'element-plus';
import { schemas } from './querySchemas';
import { useForm } from '@/components/Form/index';
import { TableAction } from '@/components/Table';
import { get${entity}List, ${entity?lower_case}Delete, ${entity?lower_case}BatchDelete } from '@/api/tool/${entity?lower_case}';
import { columns } from './columns';
import { PlusOutlined } from '@vicons/antd';
import { message, confirm } from '@/utils/auth';
/**
* 导入组件
*/
const editDialog = defineAsyncComponent(() => import('./edit.vue'));
/**
* 定义参数变量
*/
const ${entity?lower_case}Id = ref(0);
const editVisible = ref(false);
const selectionData = ref([]);
const tableRef = ref();
/**
* 定义查询参数
*/
const formParams = reactive({
name: '',
status: '',
});
/**
* 定义操作栏
*/
const actionColumn = reactive({
width: 200,
label: '操作',
prop: 'action',
fixed: 'right',
render(record) {
return h(TableAction, {
style: 'button',
actions: [
{
label: '编辑',
icon: 'Edit',
type: 'warning',
onClick: handleEdit.bind(null, record),
auth: ['sys:${entity?lower_case}:update'],
},
{
label: '删除',
icon: 'Delete',
type: 'danger',
onClick: handleDelete.bind(null, record),
auth: ['sys:${entity?lower_case}:delete'],
},
],
});
},
});
/**
* 加载数据列表
* @param res 参数
*/
const loadDataTable = async (res: any) => {
const result = await get${entity}List({ ...formParams, ...res });
return result;
};
/**
* 刷新数据列表
* @param noRefresh 参数
*/
function reloadTable(noRefresh = '') {
tableRef.value.reload(noRefresh ? {} : { pageNo: 1 });
}
/**
* 注册
*/
const [register, {}] = useForm({
labelWidth: 80,
layout: 'horizontal',
colProps: { span: 6 } as ColProps,
submitOnReset: true,
schemas,
});
/**
* 执行提交表单
*/
function handleSubmit(values: Recordable) {
handleReset();
for (const key in values) {
formParams[key] = values[key];
}
reloadTable();
}
/**
* 执行重置
*/
function handleReset() {
for (const key in formParams) {
formParams[key] = '';
}
}
/**
* 执行添加
*/
const handleAdd = async () => {
${entity?lower_case}Id.value = 0;
await nextTick();
editVisible.value = true;
};
/**
* 执行编辑
* @param record 参数
*/
const handleEdit = async (record: Recordable) => {
${entity?lower_case}Id.value = record.row.id;
await nextTick();
editVisible.value = true;
};
/**
* 执行删除
* @param record 参数
*/
async function handleDelete(record: Recordable) {
let ids = [];
if (!record) {
ids = selectionData.value.map(({ id }) => id);
}
await confirm('确定要删除?');
record ? await ${entity?lower_case}Delete(record.row.id) : await ${entity?lower_case}BatchDelete(ids);
message('删除成功');
reloadTable();
}
/**
* 选项发生变化
* @param value 参数
*/
function onSelectionChange(value) {
selectionData.value = value;
}
</script>
<style lang="scss" scoped></style>
前端列参数模板
ts
import { h } from 'vue';
import { ElAvatar, ElTag } from 'element-plus';
export const columns = [
{
type: 'selection',
},
{
label: 'ID',
prop: 'id',
width: 100,
},
<#list table.fields as field>
<#if field.propertyName != 'id'
&& field.propertyName != 'createUser'
&& field.propertyName != 'createTime'
&& field.propertyName != 'updateUser'
&& field.propertyName != 'updateTime'
&& field.propertyName != 'delFlag'
&& field.propertyName != 'tenantId'
>
<#if (field.customMap?? && field.customMap?size > 0)>
<#if (field.customMap?size > 2)>
{
label: '${field.comment}',
prop: '${field.propertyName}',
render(record) {
let ${field.propertyName}Text = '';
switch (record.row.${field.propertyName}) {
<#list field.customMap?keys as key>
case ${key}:
${field.propertyName}Text = '${field.customMap[key]!}';
break;
</#list>
default:
break;
}
return h('span', ${field.propertyName}Text || '-');
},
},
<#else>
{
label: '${field.comment}',
prop: '${field.propertyName}',
render(record) {
return h(
ElTag,
{
type: record.row.${field.propertyName} == ${field.metaInfo.defaultValue} ? 'success' : 'danger',
},
{
default: () => (record.row.${field.propertyName} == ${field.metaInfo.defaultValue} ? '${field.customMap["1"]!}' : '${field.customMap["2"]!}'),
},
);
},
},
</#if>
<#elseif field.propertyName == 'cover' || field.propertyName == 'logo' || field.propertyName == 'image'>
{
label: '${field.comment}',
prop: '${field.propertyName}',
render(record) {
return h(ElAvatar, {
size: 48,
src: record.row.${field.propertyName},
shape: 'square',
fit: 'fill',
});
},
width: 100,
},
<#else>
{
label: '${field.comment}',
prop: '${field.propertyName}',
},
</#if>
</#if>
</#list>
{
label: '创建人',
prop: 'createUser',
},
{
label: '创建时间',
prop: 'createTime',
width: 180,
},
];
前端查询条件模板
ts
import { FormSchema } from '@/components/Form/index';
export const schemas: FormSchema[] = [
<#list table.fields as field>
<#if field.propertyName == 'name' || field.propertyName == 'title'>
{
field: '${field.propertyName}',
component: 'Input',
label: '${field.comment}',
componentProps: {
placeholder: '请输入${field.comment}',
},
},
<#elseif (field.customMap?? && field.customMap?size > 0)>
{
field: '${field.propertyName}',
component: 'Select',
label: '${field.comment}',
componentProps: {
placeholder: '请选择${field.comment}',
clearable: true,
options: [
<#list field.customMap?keys as key>
{
label: '${field.customMap[key]!}',
value: '${key}',
},
</#list>
],
},
},
</#if>
</#list>
];
前端编辑视图模板
ts
<template>
<el-dialog
v-model="props.visible"
:title="props.${entity?lower_case}Id ? '编辑' : '新增'"
width="500"
:close-on-click-modal="false"
:before-close="dialogClose"
>
<el-form class="ls-form" ref="formRef" :model="formData" label-width="80px">
<#list table.fields as field>
<#if field.propertyName != 'id'
&& field.propertyName != 'createUser'
&& field.propertyName != 'createTime'
&& field.propertyName != 'updateUser'
&& field.propertyName != 'updateTime'
&& field.propertyName != 'delFlag'
&& field.propertyName != 'tenantId'
>
<#if (field.customMap?? && field.customMap?size > 0)>
<#if (field.customMap?size > 2)>
<el-form-item label="${field.comment}">
<el-select v-model="formData.${field.propertyName}" placeholder="请选择${field.comment}">
<#list field.customMap?keys as key>
<el-option label="${field.customMap[key]!}" :value="${key}" />
</#list>
</el-select>
</el-form-item>
<#else>
<el-form-item label="${field.comment}" prop="${field.propertyName}">
<el-radio-group v-model="formData.${field.propertyName}" name="${field.propertyName}">
<#list field.customMap?keys as key>
<el-radio :value="${key}">${field.customMap[key]!}</el-radio>
</#list>
</el-radio-group>
</el-form-item>
</#if>
<#elseif field.propertyName == 'cover' || field.propertyName == 'logo' || field.propertyName == 'image'>
<el-form-item
label="${field.comment}"
prop="${field.propertyName}"
:rules="{ required: true, message: '请上传${field.comment}', trigger: 'change' }"
>
<UploadImg
@changeFileName="(name) => (formData.imageImgName = name)"
:fileType="['image/jpeg', 'image/png', 'image/jpg', 'image/gif']"
name="${entity?lower_case}"
:fileSize="20"
v-model:image-url="formData.${field.propertyName}"
>
<template #tip>支持扩展名: jpg png jpeg;文件大小不超过20M</template>
</UploadImg>
</el-form-item>
<#elseif field.columnType?string == 'INTEGER'>
<el-form-item label="${field.comment}" prop="${field.propertyName}">
<el-input-number v-model="formData.${field.propertyName}" />
</el-form-item>
<#else>
<el-form-item
label="${field.comment}"
prop="${field.propertyName}"
:rules="{ required: true, message: '请输入${field.comment}', trigger: 'blur' }"
>
<el-input class="ls-input" v-model="formData.${field.propertyName}" placeholder="请输入${field.comment}" clearable />
</el-form-item>
</#if>
</#if>
</#list>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogClose">取消</el-button>
<el-button :loading="subLoading" type="primary" @click="submit"> 确定 </el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus';
import { get${entity}Detail, ${entity?lower_case}Add, ${entity?lower_case}Update } from '@/api/tool/${entity?lower_case}';
import { onMounted, reactive, shallowRef } from 'vue';
import UploadImg from '@/components/Upload/Image.vue';
import { message } from '@/utils/auth';
import { useLockFn } from '@/utils/useLockFn';
const emit = defineEmits(['success', 'update:visible']);
const formRef = shallowRef<FormInstance>();
/**
* 定义表单参数
*/
const formData = reactive({
id: '',
<#list table.fields as field>
<#if field.propertyName != 'id'
&& field.propertyName != 'createUser'
&& field.propertyName != 'createTime'
&& field.propertyName != 'updateUser'
&& field.propertyName != 'updateTime'
&& field.propertyName != 'delFlag'
&& field.propertyName != 'tenantId'
>
<#if (field.customMap?? && field.customMap?size > 0)>
${field.propertyName}: ${field.metaInfo.defaultValue},
<#elseif field.columnType?string == 'INTEGER'>
${field.propertyName}: ${field.metaInfo.defaultValue!0},
<#else>
${field.propertyName}: '',
</#if>
</#if>
</#list>
});
/**
* 定义接收的参数
*/
const props = defineProps({
visible: {
type: Boolean,
required: true,
default: false,
},
${entity?lower_case}Id: {
type: Number,
required: true,
default: 0,
},
});
/**
* 执行提交表单
*/
const handleSubmit = async () => {
await formRef.value?.validate();
props.${entity?lower_case}Id ? await ${entity?lower_case}Update(formData) : await ${entity?lower_case}Add(formData);
message('操作成功');
emit('update:visible', false);
emit('success');
};
/**
* 关闭窗体
*/
const dialogClose = () => {
emit('update:visible', false);
};
const { isLock: subLoading, lockFn: submit } = useLockFn(handleSubmit);
/**
* 设置表单数据
*/
const setFormData = async () => {
const data = await get${entity}Detail(props.${entity?lower_case}Id);
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key];
}
}
};
/**
* 钩子函数
*/
onMounted(() => {
if (props.${entity?lower_case}Id) {
setFormData();
}
});
</script>
前端接口定义模板
ts
import { http } from '@/utils/http/axios';
/**
* @description: ${table.comment!}列表
*/
export function get${entity}List(params?) {
return http.request({
url: '/${entity?lower_case}/page',
method: 'GET',
params,
});
}
/**
* 获取全部${table.comment!}列表
* @param params 参数
* @returns 返回结果
*/
export function get${entity}AllList(params?) {
return http.request({
url: '/${entity?lower_case}/list',
method: 'GET',
params,
});
}
/**
* @description: 根据ID获取详情
*/
export function get${entity}Detail(${entity?lower_case}Id) {
return http.request({
url: '/${entity?lower_case}/detail/' + ${entity?lower_case}Id,
method: 'get',
});
}
/**
* @description: 添加${table.comment!}
*/
export function ${entity?lower_case}Add(data: any) {
return http.request({
url: '/${entity?lower_case}/add',
method: 'POST',
data,
});
}
/**
* @description: 更新${table.comment!}
*/
export function ${entity?lower_case}Update(data: any) {
return http.request({
url: '/${entity?lower_case}/update',
method: 'PUT',
data,
});
}
/**
* @description: 删除${table.comment!}
*/
export function ${entity?lower_case}Delete(${entity?lower_case}Id) {
return http.request({
url: '/${entity?lower_case}/delete/' + ${entity?lower_case}Id,
method: 'DELETE',
});
}
/**
* @description: 批量删除${table.comment!}
*/
export function ${entity?lower_case}BatchDelete(data: any) {
return http.request({
url: '/${entity?lower_case}/batchDelete',
method: 'DELETE',
data,
});
}
总结
通过自定义模板引擎,MyBatis-Plus 代码生成器的灵活性和可扩展性得到了极大的提升。开发者可以根据项目需求,定制生成代码的格式和内容,从而提高开发效率和代码质量。希望这篇说明能够帮助你更好地理解和应用 MyBatis-Plus 的代码生成器自定义模板引擎功能。