以下是基于 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. 继承 IService 与 ServiceImpl 的优势
- 自动获得 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 等
✅ 这两份模板已在多个生产项目中验证,兼顾 规范性、可读性、可扩展性,可作为团队代码生成标准模板使用。开发者只需在生成后补充具体业务逻辑即可快速交付高质量代码。
369

被折叠的 条评论
为什么被折叠?



