Skip to content

概要说明

  • MyBatis-Plus 是一个增强版的 MyBatis,旨在简化数据库开发工作。其代码生成器可以帮助开发者根据数据库表结构自动生成 EntityMapperServiceController 等模块文件和代码。默认情况下,代码生成器使用 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 的代码生成器自定义模板引擎功能。

小蚂蚁云团队 · 提供技术支持