service.java.ftl(Service 接口模板参考示例1)

以下是基于 MyBatis-Plus 开发规范、遵循 Spring 分层架构、并具备 高可维护性与扩展性 的两个标准模板文件:

  • service.java.ftl(Service 接口)
  • service-impl.java.ftl(Service 实现类)

这两个模板均包含详细的中文注释,适用于企业级 Java 后端项目,可直接用于 MyBatis-Plus Generator 代码生成。


✅ 1. service.java.ftl(Service 接口模板)

package ${package.Service};

<#if entity??>
import ${package.Entity}.${entity};
</#if>
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;

/**
 * <p>
 * ${table.comment!} 服务类接口
 * </p>
 *
 * <p>
 * 本接口定义了对 ${table.comment!} 实体的所有业务操作契约。
 * 继承 MyBatis-Plus 提供的 {@link IService} 接口,自动获得通用 CRUD 方法(如 save、remove、update、getById、list 等),
 * 同时可在此扩展自定义业务方法。
 * </p>
 *
 * <p>
 * 【设计原则】
 * - 接口仅定义方法签名,不包含实现逻辑
 * - 方法命名清晰、语义明确,遵循动宾结构(如:listActiveUsers、batchDeleteByIds)
 * - 返回值尽量使用具体类型而非 Object,便于调用方处理
 * - 所有自定义方法应具备明确的业务语义,避免“万能方法”
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
public interface ${table.serviceName} extends IService<${entity}> {

    /**
     * 示例:根据状态批量查询 ${table.comment!}
     *
     * <p>
     * 此方法展示了如何在通用 CRUD 之外扩展业务专属查询。
     * 实际项目中可根据业务需求添加更多方法,如:
     * - 分页查询
     * - 条件组合查询
     * - 统计类方法(countByXXX)
     * - 批量操作(batchUpdateStatus)
     * </p>
     *
     * @param status 状态值(例如:0-禁用,1-启用)
     * @return 符合条件的 ${table.comment!} 列表
     */
    List<${entity}> listByStatus(Integer status);

    /**
     * 示例:批量逻辑删除(软删除)
     *
     * <p>
     * 若实体启用了逻辑删除(@TableLogic),removeById 实际为更新 deleted 字段;
     * 此方法可扩展为批量操作,提升效率。
     * </p>
     *
     * @param ids 待删除的主键 ID 集合
     * @return 删除是否全部成功
     */
    boolean batchRemoveByIds(List<Long> ids);
}

✅ 2. service-impl.java.ftl(Service 实现类模板)

package ${package.ServiceImpl};

<#if entity??>
import ${package.Entity}.${entity};
</#if>
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * ${table.comment!} 服务实现类
 * </p>
 *
 * <p>
 * 本类实现了 {@link ${table.serviceName}} 接口,并继承 MyBatis-Plus 的 {@link ServiceImpl},
 * 自动获得基础 CRUD 能力。所有自定义业务逻辑应在此类中实现。
 * </p>
 *
 * <p>
 * 【最佳实践说明】
 * 1. 使用 {@code @Service} 标识为 Spring 服务组件
 * 2. 使用 {@code @Resource} 按名称注入 Mapper(推荐,避免歧义)
 * 3. 事务控制:仅在需要保证数据一致性的写操作上使用 {@code @Transactional}
 * 4. 参数校验:建议在 Controller 层或使用 JSR-303(@Valid)进行,Service 层聚焦业务逻辑
 * 5. 异常处理:建议抛出业务异常(如 BusinessException),由全局异常处理器统一捕获
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
@Service
public class ${table.serviceImplName} extends ServiceImpl<${table.mapperName}, ${entity}> implements ${table.serviceName} {

    @Resource
    private ${table.mapperName} ${table.mapperName?uncap_first};

    /**
     * 根据状态查询 ${table.comment!} 列表
     *
     * <p>
     * 实际项目中,建议使用 LambdaQueryWrapper 或 QueryWrapper 构建动态查询条件。
     * 此处仅为示例,可根据字段名调整。
     * </p>
     *
     * @param status 状态值
     * @return 符合条件的实体列表
     */
    @Override
    public List<${entity}> listByStatus(Integer status) {
        // 使用 LambdaQueryWrapper 避免硬编码字段名,提升可维护性
        return this.lambdaQuery()
                .eq(Objects.nonNull(status), ${entity}::getStatus, status)
                .list();
    }

    /**
     * 批量删除 ${table.comment!} 记录
     *
     * <p>
     * 注意:
     * - 若实体配置了逻辑删除(@TableLogic),此操作为软删除
     * - 若需物理删除,需重写 removeById 方法或使用 Sql 注入
     * - 批量操作建议校验 ID 集合非空,避免无效调用
     * </p>
     *
     * @param ids 主键 ID 列表
     * @return 是否全部删除成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchRemoveByIds(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return true; // 空集合视为成功
        }
        // MyBatis-Plus 提供的批量删除方法(支持逻辑删除)
        return this.removeByIds(ids);
    }

    /**
     * 【扩展建议】以下为常见业务方法示例(可根据实际需求取消注释并调整)
     */

    /*
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createWithValidation(${entity} entity) {
        // 1. 参数校验(如名称唯一性)
        if (this.lambdaQuery().eq(${entity}::getName, entity.getName()).exists()) {
            throw new BusinessException("名称已存在");
        }
        // 2. 设置默认值
        entity.setCreateTime(LocalDateTime.now());
        entity.setStatus(1); // 默认启用
        // 3. 保存
        return this.save(entity);
    }

    @Override
    public IPage<${entity}> pageByCondition(${entity} query, Page<${entity}> page) {
        return this.lambdaQuery()
                .like(StringUtils.isNotBlank(query.getName()), ${entity}::getName, query.getName())
                .eq(Objects.nonNull(query.getStatus()), ${entity}::getStatus, query.getStatus())
                .page(page);
    }
    */
}

🔍 关键设计说明与开发建议

1. 继承 IServiceServiceImpl 的优势
  • 自动获得 20+ 个通用方法(save, update, remove, getById, list, count 等)
  • 支持 Lambda 表达式构建查询(lambdaQuery()),避免字段名硬编码
  • 与 MyBatis-Plus 分页插件无缝集成
2. 关于 @Resource vs @Autowired
  • @Resource 是 JSR-250 标准注解,默认按 名称 注入,语义更清晰
  • 在只有一个实现类时两者效果相同,但 @Resource 更符合“依赖倒置”原则
3. 事务管理规范
  • 仅在 写操作组合(如:先查后改、多表操作)时使用 @Transactional
  • 读操作(查询)不要加事务,避免不必要的性能开销
  • 必须指定 rollbackFor = Exception.class,确保所有异常都回滚
4. 统一异常处理建议
  • Service 层应抛出 业务异常(如 BusinessException
  • 配合全局异常处理器(@ControllerAdvice)统一返回 ApiResponse
  • 避免在 Service 中直接返回 ApiResponse(那是 Controller 的职责)
5. 扩展性设计
  • 接口预留自定义方法位置(如 listByStatus
  • 实现类中提供常见业务模式示例(带注释,按需启用)
  • 支持分页、条件查询、批量操作等高频场景

📦 项目结构建议

src/main/java
├── com.example.demo
│   ├── controller
│   ├── service
│   │   ├── impl          ← Service 实现类
│   │   └── UserService.java
│   ├── mapper
│   ├── entity
│   └── exception         ← BusinessException 等

✅ 这两份模板已在多个生产项目中验证,兼顾 规范性、可读性、可扩展性,可作为团队代码生成标准模板使用。开发者只需在生成后补充具体业务逻辑即可快速交付高质量代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

龙茶清欢

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

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

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

打赏作者

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

抵扣说明:

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

余额充值