mapper.java.ftl(Mapper 接口模板标准规范版2)

当然可以!以下是企业级标准、完全符合 MyBatis-Plus 最佳实践、并添加详尽中文注释mapper.java.ftlmapper.xml.ftl 模板文件。

这两个模板是 MyBatis-Plus 代码生成器的核心组件,直接决定了数据访问层的规范性、可维护性和扩展性。它们遵循:

  • 接口与 XML 分离(标准 MyBatis 规范)
  • 继承 BaseMapper<T>(自动获得 CRUD 方法)
  • 启用 @Mapper 注解(Spring 扫描)
  • 生成 BaseResultMapBaseColumnList(复用 SQL 片段)
  • XML 文件结构清晰、注释完整
  • 支持自定义 SQL 片段

✅ 一、mapper.java.ftl —— Mapper 接口模板(标准规范版)

<#--
  =================================================================================================
  MyBatis-Plus 代码生成器 - Mapper 接口模板 (标准规范版)
  =================================================================================================
  作者:CodeGenWeb
  生成时间:${now?string("yyyy-MM-dd HH:mm:ss")}
  数据库表:${table.comment}(表名:${table.name})
  
  说明:
  1. 本模板定义 Mapper 接口,继承 MyBatis-Plus 的 BaseMapper<${entity}>。
  2. BaseMapper 已提供所有基础 CRUD 方法(如 selectById, insert, updateById, deleteById 等),
     开发者无需手动编写,直接调用即可。
  3. 此接口必须添加 @Mapper 注解,确保 Spring Boot 能够扫描并注册为 Bean。
  4. 所有方法均使用中文注释,明确用途和参数含义,便于团队协作。
  5. 本文件为 Freemarker 模板,生成时会自动替换 ${} 中的变量。
  6. 请勿手动修改生成的文件,下次生成将覆盖!
  =================================================================================================
-->

package ${package.Mapper};

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import ${package.Entity}.${entity};
import org.apache.ibatis.annotations.Mapper;

/**
 * ${table.comment!""} Mapper 接口
 * 
 * <p>本接口继承 MyBatis-Plus 的 BaseMapper<${entity}>,自动获得以下基础方法:</p>
 * <ul>
 *   <li><code>selectById(id)</code> - 根据 ID 查询单条记录</li>
 *   <li><code>selectList()</code> - 查询所有记录</li>
 *   <li><code>selectPage(page)</code> - 分页查询</li>
 *   <li><code>insert(entity)</code> - 新增记录</li>
 *   <li><code>updateById(entity)</code> - 根据 ID 更新记录</li>
 *   <li><code>deleteById(id)</code> - 根据 ID 删除记录(物理删除)</li>
 *   <li><code>selectCount()</code> - 统计记录总数</li>
 *   <li>... 等 10+ 个常用方法</li>
 * </ul>
 * 
 * <p>开发者应在本接口中声明**自定义的复杂查询方法**,例如:</p>
 * <ul>
 *   <li>根据多个条件组合查询</li>
 *   <li>复杂聚合统计</li>
 *   <li>自定义 SQL 片段</li>
 * </ul>
 * 
 * <p>推荐:所有自定义方法都应使用 MyBatis-Plus 的 LambdaQueryWrapper 或 QueryWrapper 构建,避免手写 SQL,提高可维护性。</p>
 * 
 * @author ${author}
 * @date ${now?string("yyyy-MM-dd")}
 */
@Mapper // ✅ 必须添加 @Mapper 注解,让 Spring 扫描为 Bean。这样就不再需要 @MapperScan 注解
public interface ${mapper} extends BaseMapper<${entity}> {

    /**
     * 根据用户名查询用户信息
     * 
     * <p>此方法用于登录验证或用户检索,通过用户名精确查找</p>
     * 
     * @param username 用户名(非空)
     * @return 找到的 ${entity} 对象,未找到返回 null
     * @throws IllegalArgumentException 当 username 为 null 或空字符串时抛出
     */
    ${entity} selectByUsername(String username);

    /**
     * 根据邮箱查询用户信息
     * 
     * <p>此方法用于注册时检查邮箱是否已被占用</p>
     * 
     * @param email 邮箱地址(非空)
     * @return 找到的 ${entity} 对象,未找到返回 null
     * @throws IllegalArgumentException 当 email 为 null 或空字符串时抛出
     */
    ${entity} selectByEmail(String email);

    /**
     * 根据创建时间范围查询用户列表(按创建时间倒序)
     * 
     * <p>此方法用于生成用户增长报表,支持按时间段筛选</p>
     * 
     * @param startTime 创建开始时间(包含)
     * @param endTime   创建结束时间(包含)
     * @return 满足条件的用户列表,按创建时间倒序排列
     */
    java.util.List<${entity}> selectListByCreateTimeRange(java.time.LocalDateTime startTime, java.time.LocalDateTime endTime);

    /**
     * 批量启用/禁用用户
     * 
     * <p>此方法用于管理员批量操作用户状态,支持传入多个用户ID</p>
     * 
     * @param userIds 要操作的用户ID列表(非空)
     * @param enabled   true=启用,false=禁用
     * @return 成功操作的记录数
     * @throws IllegalArgumentException 当 userIds 为 null 或空时抛出
     */
    int batchEnableUsers(java.util.List<Long> userIds, boolean enabled);

    /**
     * 统计激活用户数量
     * 
     * <p>此方法用于统计系统中活跃用户数量</p>
     * 
     * @return 激活用户的总数
     */
    Long selectActiveUserCount();

    // ==================== 以下为预留方法示例(请根据实际业务增删) ====================
    // /**
    //  * 根据多个角色ID查询用户列表
    //  * 
    //  * @param roleIds 角色ID列表
    //  * @return 拥有指定角色的用户列表
    //  */
    // List<${entity}> selectListByRoleIds(List<Long> roleIds);

    // /**
    //  * 根据用户名模糊查询用户列表
    //  * 
    //  * @param usernamePattern 用户名模糊匹配模式
    //  * @return 匹配的用户列表
    //  */
    // List<${entity}> selectListByUsernameLike(String usernamePattern);

    // /**
    //  * 获取用户最近登录时间
    //  * 
    //  * @param userId 用户ID
    //  * @return 最近登录时间,未登录返回 null
    //  */
    // LocalDateTime selectLastLoginTime(Long userId);
}

✅ 模板说明(关键点)

特性说明
继承 BaseMapper<${entity}>自动获得 MyBatis-Plus 提供的全部基础方法,无需手动编写。
@Mapper 注解必须添加,确保 Spring Boot 能扫描到此接口并注册为 Bean。
方法命名规范使用 selectXXX 前缀,清晰区分于 Service 层的 getXXXlistXXX
参数校验注释明确说明 @param 是否允许为 null,避免调用方传参错误。
返回值说明清晰说明返回 nullListLongint 的含义。
异常说明使用 @throws 注解,明确业务异常(如 IllegalArgumentException)。
预留注释提供了 4 个常见业务场景的注释示例,供开发者参考和扩展。
避免手写 SQL强调使用 LambdaQueryWrapper,而非直接写 XML SQL,提升可维护性。

✅ 二、mapper.xml.ftl —— Mapper XML 映射文件模板(标准规范版)

<#--
  =================================================================================================
  MyBatis-Plus 代码生成器 - Mapper XML 映射文件模板 (标准规范版)
  =================================================================================================
  作者:CodeGenWeb
  生成时间:${now?string("yyyy-MM-dd HH:mm:ss")}
  数据库表:${table.comment}(表名:${table.name})
  
  说明:
  1. 本模板是 MyBatis-Plus 的 XML 映射文件,用于定义自定义 SQL 查询。
  2. 本文件必须与 Mapper 接口同名,且位于 resources/${package.xml} 目录下。
  3. 本文件已自动生成 BaseResultMap 和 BaseColumnList,用于复用 SQL 片段,避免重复。
  4. 所有自定义 SQL 均使用 #{} 占位符,防止 SQL 注入。
  5. 所有注释均为中文,详细说明 SQL 用途、参数和返回值。
  6. 本文件为 Freemarker 模板,生成时会自动替换 ${} 中的变量。
  7. 请勿手动修改生成的文件,下次生成将覆盖!
  =================================================================================================
-->
<?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}.${mapper}">

    <!-- =================================================================== -->
    <!-- ========== 1. 基础字段列表:BaseColumnList ========= -->
    <!-- =================================================================== -->
    <!-- 
        作用:定义表中所有常用字段的列表,避免在多个 SQL 中重复书写。
        使用方式:在 SELECT 语句中引用 <include refid="Base_Column_List" />
        例如:<select id="selectList" resultType="${package.Entity}.${entity}">
                  SELECT <include refid="Base_Column_List" /> FROM ${table.name}
              </select>
    -->
    <sql id="Base_Column_List">
        <#list table.fields as field>
            <#if field_index != 0>,</#if>
            ${field.name}
        </#list>
    </sql>

    <!-- =================================================================== -->
    <!-- ========== 2. 基础结果映射:BaseResultMap ========= -->
    <!-- =================================================================== -->
    <!-- 
        作用:定义数据库字段与 Java 实体属性的映射关系。
        MyBatis-Plus 默认会自动映射(驼峰命名),但显式声明可提升可读性和兼容性。
        使用方式:在 SELECT 语句中指定 resultType="com.baomidou.mybatisplus.core.mapper.BaseMapper" 
                  或 resultMap="BaseResultMap"
    -->
    <resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
        <#list table.fields as field>
            <#-- 主键 -->
            <#if field.keyFlag>
                <id column="${field.name}" property="${field.name}" jdbcType="${field.jdbcType}" />
            <#-- 普通字段 -->
            <#else>
                <result column="${field.name}" property="${field.name}" jdbcType="${field.jdbcType}" />
            </#if>
        </#list>
    </resultMap>

    <!-- =================================================================== -->
    <!-- ========== 3. 自定义 SQL 查询 ========= -->
    <!-- =================================================================== -->

    <!-- 
        方法:selectByUsername
        用途:根据用户名精确查询用户信息
        参数:username - 用户名
        返回:单个 ${entity} 对象,未找到返回 null
    -->
    <select id="selectByUsername" resultType="${package.Entity}.${entity}">
        SELECT
            <include refid="Base_Column_List" />
        FROM ${table.name}
        WHERE username = #{username}
        AND deleted = 0  <!-- 逻辑删除过滤,确保只查询未删除的记录 -->
    </select>

    <!-- 
        方法:selectByEmail
        用途:根据邮箱精确查询用户信息
        参数:email - 邮箱地址
        返回:单个 ${entity} 对象,未找到返回 null
    -->
    <select id="selectByEmail" resultType="${package.Entity}.${entity}">
        SELECT
            <include refid="Base_Column_List" />
        FROM ${table.name}
        WHERE email = #{email}
        AND deleted = 0  <!-- 逻辑删除过滤 -->
    </select>

    <!-- 
        方法:selectListByCreateTimeRange
        用途:根据创建时间范围查询用户列表(按创建时间倒序)
        参数:startTime - 开始时间(包含)
              endTime - 结束时间(包含)
        返回:满足条件的 ${entity} 列表
    -->
    <select id="selectListByCreateTimeRange" resultType="${package.Entity}.${entity}">
        SELECT
            <include refid="Base_Column_List" />
        FROM ${table.name}
        WHERE create_time >= #{startTime}
          AND create_time <= #{endTime}
          AND deleted = 0
        ORDER BY create_time DESC
    </select>

    <!-- 
        方法:batchEnableUsers
        用途:批量启用/禁用用户
        参数:userIds - 用户ID列表
              enabled - 状态:true=启用,false=禁用
        返回:成功更新的记录数
    -->
    <update id="batchEnableUsers">
        UPDATE ${table.name}
        SET is_active = #{enabled}
        WHERE id IN
        <foreach collection="userIds" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </update>

    <!-- 
        方法:selectActiveUserCount
        用途:统计激活用户数量
        参数:无
        返回:激活用户的总数(Long 类型)
    -->
    <select id="selectActiveUserCount" resultType="java.lang.Long">
        SELECT COUNT(*) FROM ${table.name}
        WHERE is_active = 1
          AND deleted = 0
    </select>

    <!-- =================================================================== -->
    <!-- ========== 4. 预留自定义 SQL 示例 ========= -->
    <!-- =================================================================== -->
    <!--
        <select id="selectListByRoleIds" resultType="${package.Entity}.${entity}">
            SELECT DISTINCT
                <include refid="Base_Column_List" />
            FROM ${table.name} u
            INNER JOIN user_role ur ON u.id = ur.user_id
            WHERE ur.role_id IN
            <foreach collection="roleIds" item="roleId" open="(" separator="," close=")">
                #{roleId}
            </foreach>
            AND u.deleted = 0
        </select>
    -->

    <!--
        <select id="selectListByUsernameLike" resultType="${package.Entity}.${entity}">
            SELECT
                <include refid="Base_Column_List" />
            FROM ${table.name}
            WHERE username LIKE CONCAT('%', #{usernamePattern}, '%')
              AND deleted = 0
            ORDER BY create_time DESC
        </select>
    -->

    <!--
        <select id="selectLastLoginTime" resultType="java.time.LocalDateTime">
            SELECT last_login_time FROM ${table.name}
            WHERE id = #{userId}
              AND deleted = 0
        </select>
    -->

</mapper>

✅ 模板说明(关键点)

特性说明
<sql id="Base_Column_List">核心复用:避免在每个 SQL 中重复写字段,修改字段只需改一处。
<resultMap id="BaseResultMap">显式声明映射关系,提升可读性,兼容非驼峰命名数据库。
<include refid="...">最佳实践:所有 SELECT 都使用 <include> 引用 Base_Column_List
#{} 占位符安全第一:绝对禁止使用 ${},防止 SQL 注入攻击。
逻辑删除过滤所有查询都添加 AND deleted = 0,确保数据隔离,符合业务规范。
<foreach> 标签正确使用 collectionitemopenseparatorclose,支持 List 参数。
返回类型明确selectActiveUserCount 使用 resultType="java.lang.Long",避免类型不匹配。
预留注释提供了 3 个典型复杂查询的注释模板,降低开发门槛。
注释完整每个 SQL 都有清晰的中文注释,说明用途、参数、返回值。

✅ 总结:为什么这套模板是企业级标准?

维度说明
规范性完全遵循 MyBatis-Plus 官方推荐、Spring Boot 最佳实践。
可维护性字段复用、注释清晰,团队协作零摩擦。
安全性全部使用 #{},杜绝 SQL 注入风险。
健壮性自动处理逻辑删除、字段映射,减少人为错误。
扩展性模板结构清晰,新增自定义 SQL 只需在 XML 中添加,不影响接口。
文档化每个方法都有中文注释,相当于“自动生成的文档”。

企业级建议

  1. 所有自定义 SQL 都必须写在 XML 中,不要写在 Java 注解里(@Select),便于统一管理和调试。
  2. XML 文件命名必须与 Mapper 接口完全一致(如 UserMapper.javaUserMapper.xml)。
  3. 所有 XML 文件统一放在 resources/mapper/ 目录下,便于集中管理。
  4. 定期审查 XML 文件,确保没有重复 SQL、无用注释、拼写错误。

✅ 最终效果

当你运行代码生成器后,你会得到:

  • UserMapper.java:一个干净、简洁、只声明自定义方法的接口。
  • UserMapper.xml:一个结构清晰、注释详尽、可直接用于生产环境的 XML 文件。

🚀 从此,你的数据访问层不再是一团乱麻,而是一份
可阅读、可审计、可传承的企业级代码资产。

复制此模板,你已拥有业界标准的 MyBatis-Plus Mapper 实现。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值