Appearance
Basic继承体系开发完整指南
⭐ 推荐方式:适用于标准CRUD操作、工作流业务、快速开发场景
📋 目录
核心概念
什么是Basic继承体系?
Basic继承体系是JPwise提供的快速开发框架,通过继承基类自动获得完整的CRUD功能、工作流集成、钩子方法等特性。
核心优势
- ✅ 减少80%重复代码 - 继承即拥有完整API
- ✅ 内置工作流支持 - 自动集成审批流程
- ✅ 丰富的钩子方法 - 灵活扩展业务逻辑(详见钩子方法参考)
- ✅ 统一的数据处理 - 自动处理创建人、时间等字段
- ✅ 子表自动处理 - 通过注解自动管理主子表关系
模块对应的Basic类
JPwise采用模块化架构,每个模块都有对应的Basic基类:
模块 | Controller基类 | Service基类 | ServiceImpl基类 | API路径前缀 | 数据源常量 |
---|---|---|---|---|---|
jpwise-extend(扩展模块) | BasicDemoController | BasicDemoService | BasicDemoServiceImpl | /api/extend/ | DbNameConst.JPWISE_DEMO |
jpwise-essential(市场营销) | BasicEssentialController | BasicEssentialService | BasicEssentialServiceImpl | /api/essential/ | DbNameConst.JPWISE_ESSENTIAL |
jpwise-design(设计项目) | BasicDesignController | BasicDesignService | BasicDesignServiceImpl | /api/design/ | DbNameConst.JPWISE_DESIGN |
jpwise-hr(人力资源) | BasicHrController | BasicHrService | BasicHrServiceImpl | /api/hr/ | DbNameConst.JPWISE_HR |
jpwise-officeAuto(办公自动化) | BasicOfficeAutoController | BasicOfficeAutoService | BasicOfficeAutoServiceImpl | /api/officeAuto/ | DbNameConst.JPWISE_OFFICEAUTO |
jpwise-infra(业务配置) | BasicInfraController | BasicInfraService | BasicInfraServiceImpl | /api/infra/ | DbNameConst.JPWISE_INFRA |
如何选择合适的模块?
- jpwise-extend: 示例功能、测试功能、通用扩展功能
- jpwise-essential: 客户、供应商、合同、开票、到款等市场营销功能
- jpwise-design: 设计项目、设计任务、设计策划、设计执行、设计校审等
- jpwise-hr: 人员管理、考勤、薪资、绩效等人力资源功能
- jpwise-officeAuto: 公文管理、会议管理、日程安排等办公自动化功能
- jpwise-infra: 业务配置、基础数据维护等功能
快速开始
最简实现(4个文件即可)
💡 提示:以下示例以jpwise-extend模块为例,其他模块请参考上表替换对应的基类和常量。
1. Controller层强制规范
java
// ✅ Controller必须遵循的规范
@RestController
// 路径规范:根据模块使用对应的路径前缀
// jpwise-extend: /api/extend/Xxx
// jpwise-hr: /api/hr/Xxx
// jpwise-essential: /api/essential/Xxx
// jpwise-officeAuto: /api/officeAuto/Xxx
// jpwise-infra: /api/infra/Xxx
@RequestMapping("/api/[module]/Xxx")
// 根据模块继承对应的BasicController
public class XxxController extends Basic[Module]Controller<XxxEntity> {
@Autowired
private XxxService xxxService;
// 自定义接口使用POST方法,添加权限检查
@Operation(summary = "接口描述")
@PostMapping("/customAction/{id}")
public ActionResult<String> customAction(@PathVariable String id){
// 实现逻辑
return ActionResult.success("操作成功");
}
}
⚠️ 重要规范:
- 路径前缀:必须使用模块对应的API路径前缀
- 继承规范:根据模块继承对应的BasicController
- 自定义接口:统一使用POST方法,避免使用PUT/DELETE/PATCH
- 返回格式:使用ActionResult统一返回格式
2. Service接口
java
// 根据模块导入对应的BasicService
// import jpwise.base.service.BasicDemoService; // jpwise-extend模块
// import jpwise.base.service.BasicEssentialService; // jpwise-essential模块
// import jpwise.base.service.BasicHrService; // jpwise-hr模块
// 其他模块类推...
public interface UserService extends Basic[Module]Service<UserEntity> {
// 继承基础方法,可添加自定义方法
}
3. Service实现
java
// 根据模块导入对应的BasicServiceImpl
// import jpwise.base.service.impl.BasicDemoServiceImpl; // jpwise-extend模块
// import jpwise.base.service.impl.BasicEssentialServiceImpl; // jpwise-essential模块
// import jpwise.base.service.impl.BasicHrServiceImpl; // jpwise-hr模块
// 其他模块类推...
import com.mybatisflex.annotation.UseDataSource;
import jpwise.database.constant.DbNameConst;
import lombok.extern.slf4j.Slf4j;
@Slf4j // 必须添加日志注解
@Service
@UseDataSource(DbNameConst.[MODULE]) // 根据模块使用对应的数据源常量
public class UserServiceImpl extends Basic[Module]ServiceImpl<UserMapper, UserEntity>
implements UserService {
// 如果没有特殊业务逻辑,可以为空类
}
4. Mapper接口强制规范
java
// ✅ Mapper接口必须遵循的规范
import jpwise.base.dao.BasicMapper; // 正确的BasicMapper导入路径
import org.apache.ibatis.annotations.Mapper;
@Mapper // 强制必须
public interface UserMapper extends BasicMapper<UserEntity> {
// 继承基础数据库操作
}
⚠️ 重要提醒:
- 正确导入路径:
import jpwise.base.dao.BasicMapper;
- 错误路径:
import jpwise.base.mapper.BasicMapper;
❌ - 必须注解:
@Mapper
注解是强制必须的
自动获得的API接口
继承Basic[Module]Controller后,自动获得以下接口:
GET /api/[module]/User/getPageListQuery
- 分页查询列表(SQL方式)GET /api/[module]/User/getPageList
- 分页查询列表(实体方式)POST /api/[module]/User/getInfo
- 获取详情POST /api/[module]/User/save
- 保存表单(新增/更新)POST /api/[module]/User/delete
- 批量删除POST /api/[module]/User/superDelete/{flowId}/{id}
- 删除表单和流程POST /api/[module]/User/bulkSave
- 批量保存数据
💡 接口说明:
- [module] 替换为具体模块名,如
hr
、essential
、officeAuto
等- User 替换为具体的实体名称,如
OutingApplication
、Customer
等- 所有接口都遵循RESTful设计,查询用GET,操作用POST
- 接口自动包含权限验证、数据校验、异常处理等基础功能
完整示例
示例1:报销申请功能(jpwise-officeAuto模块)
报销申请属于办公自动化功能,应放在jpwise-officeAuto模块
1. 实体类
java
import jpwise.model.base.BaseEntity;
import jpwise.annotation.SubEntity;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("OA_REIMBURSEMENT")
@Schema(description = "报销申请")
public class ReimbursementEntity extends BaseEntity {
@Schema(description = "报销单号")
@Column("CODE")
@JsonProperty("CODE")
private String CODE;
@Schema(description = "申请人")
@Column("APPLICANT")
@JsonProperty("APPLICANT")
private String APPLICANT;
@Schema(description = "报销金额")
@Column("AMOUNT")
@JsonProperty("AMOUNT")
private BigDecimal AMOUNT;
// 子表关联
@Schema(description = "报销明细")
@SubEntity(targetEntity = ReimbursementDetailEntity.class,
service = ReimbursementDetailService.class,
foreign = "MAINID")
@Column(ignore = true)
@JsonProperty("DETAILLIST")
private List<ReimbursementDetailEntity> DETAILLIST;
}
2. Controller层
java
import jpwise.base.controller.BasicOfficeAutoController;
@RestController
@RequestMapping("/api/officeAuto/Reimbursement")
public class ReimbursementController extends BasicOfficeAutoController<ReimbursementEntity> {
}
3. Service实现
java
import jpwise.base.service.impl.BasicOfficeAutoServiceImpl;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
@UseDataSource(DbNameConst.JPWISE_OFFICEAUTO)
public class ReimbursementServiceImpl
extends BasicOfficeAutoServiceImpl<ReimbursementMapper, ReimbursementEntity>
implements ReimbursementService {
}
示例2:客户管理功能(jpwise-essential模块)
客户管理属于市场营销功能,应放在jpwise-essential模块
Controller层
java
import jpwise.base.controller.BasicEssentialController;
@RestController
@RequestMapping("/api/essential/Customer")
public class CustomerController extends BasicEssentialController<CustomerEntity> {
// 自动继承所有CRUD接口
}
Service实现
java
import jpwise.base.service.impl.BasicEssentialServiceImpl;
@Slf4j
@Service
@UseDataSource(DbNameConst.JPWISE_ESSENTIAL)
public class CustomerServiceImpl
extends BasicEssentialServiceImpl<CustomerMapper, CustomerEntity>
implements CustomerService {
}
钩子方法详解
📖 完整的钩子方法使用指南请参考 → 钩子方法参考
钩子方法使用原则
⚠️ 重要:
- 不要预生成钩子函数 - 只有用户明确提出具体业务需求时才添加
- ServiceImpl可以为空类 - 如果没有特殊业务逻辑需求
- 按需添加 - 根据用户的具体业务需求逐步添加钩子方法
钩子方法编码强制规范
⚠️ 钩子方法必须遵循的核心原则:
- 按需添加 - 只有用户明确需要时才添加钩子方法,ServiceImpl可以为空类
- Entity优先 - 转换为Entity对象进行类型安全操作
- 避免双重操作 - 不要同时修改entity和dic
- 统一转换 - 最后用JsonUtil.entityToMap()转换回dic
- 必须调用super - 每个钩子方法都必须调用父类方法
- 避免硬编码常量 - 尽量不在代码中直接写字符串常量
钩子方法类型
钩子方法主要分为以下几类:
- 数据操作钩子:beforeSave、afterSave、beforeDelete等
- 工作流钩子:beforeTaskExec、afterTaskExec、onFlowEnd等
- 子表操作钩子:beforeSaveSubTable、afterSaveSubTable等
- 数据获取钩子:afterGetData等
详细的使用方法、完整示例和最佳实践,请参考 钩子方法参考文档。
子表处理
配置子表关联
java
@Table("main_table")
public class MainEntity extends BaseEntity {
// 使用@SubEntity注解配置子表
@Schema(description = "子表列表")
@SubEntity(targetEntity = DetailEntity.class, // 子表实体类
service = DetailService.class, // 子表Service类
foreign = "MAINID") // 子表外键字段
@Column(ignore = true) // 忽略数据库映射
@JsonProperty("DETAILLIST") // JSON属性名
private List<DetailEntity> DETAILLIST;
}
子表实体类
java
@Table("detail_table")
public class DetailEntity {
@Id(value = "ID")
@Column(value = "ID")
@JsonProperty("ID")
private String ID;
@Column("MAINID")
@JsonProperty("MAINID")
private String MAINID; // 关联主表的外键
// 其他业务字段...
}
子表自动处理流程
- 保存主表时自动保存子表
- 查询主表时自动查询子表
- 删除主表时自动删除子表
- 支持多个子表配置
工作流集成
工作流自动支持
继承BasicDemoController后,自动集成工作流功能,无需额外编码。
工作流相关字段
BaseEntity已包含工作流支持字段:
FLOWPHASE
- 流程状态STEPNAME
- 流程环节名称
工作流操作
工作流的具体操作(提交、审批、拒绝等)由jpwise-workflow模块提供,业务模块只需要:
- 实现钩子方法处理业务逻辑(详见工作流钩子)
- 不要重复实现工作流接口
最佳实践
1. 文件命名规范
java
// ✅ 正确:使用标准文件名,不加Basic后缀
UserController.java // 不是 UserBasicController.java
UserService.java // 不是 UserBasicService.java
UserServiceImpl.java // 不是 UserBasicServiceImpl.java
UserMapper.java // 不是 UserBasicMapper.java
2. 必要的注解
java
// Service实现必须添加的注解
@Slf4j // 必须添加日志注解
@Service
@UseDataSource(DbNameConst.JPWISE_DEMO) // 根据模块选择对应数据源
// Mapper接口必须添加@Mapper注解
@Mapper
public interface UserMapper extends BasicMapper<UserEntity> { }
3. 异常处理
java
// 使用项目定义的异常类型
throw new BusinessException("业务异常信息");
throw new DataException("数据验证失败");
4. 渐进式开发
- 先创建最简实现(空的ServiceImpl)
- 根据需求逐步添加钩子方法
- 不要预先添加所有钩子方法
核心原则总结:
- Entity优先 - 转换为Entity对象进行类型安全操作
- 避免双重操作 - 不要同时修改entity和dic
- 统一转换 - 最后用JsonUtil.entityToMap()转换回dic
- 避免硬编码 - 常量提取为方法,优先从配置/枚举获取
- 保持一致性 - 所有钩子方法都遵循相同的编码规范
模块选择决策指南
功能归属快速判断
当不确定功能应该放在哪个模块时,可以按以下原则判断:
与人员管理相关 → jpwise-hr
- 员工信息、考勤、请假、薪资、绩效、培训等
与客户/市场相关 → jpwise-essential
- 客户、供应商、合同、订单、发票、收付款等
与办公流程相关 → jpwise-officeAuto
- 公文、会议、日程、通知、报销、用车等
与设计项目相关 → jpwise-design
- 项目管理、任务分配、设计评审、图纸管理等
与基础配置相关 → jpwise-infra
- 业务字典、参数配置、规则设置等
测试或示例功能 → jpwise-extend
- POC功能、技术验证、示例代码等
模块选择示例
功能名称 | 推荐模块 | 原因 |
---|---|---|
报销申请 | jpwise-officeAuto | 属于办公自动化流程 |
客户管理 | jpwise-essential | 属于市场营销核心功能 |
考勤管理 | jpwise-hr | 属于人力资源管理 |
会议室预订 | jpwise-officeAuto | 属于办公资源管理 |
产品管理 | jpwise-essential | 与销售业务相关 |
业务参数配置 | jpwise-infra | 属于基础配置 |
常见问题
Q: 什么时候使用Basic继承体系? A: 标准CRUD操作、需要工作流支持、快速开发原型时使用。
Q: 如何选择合适的模块? A: 根据功能的业务属性选择,参考上面的模块选择决策指南。
Q: 必须实现所有钩子方法吗? A: 不需要,只在有具体业务需求时才添加对应的钩子方法。详见钩子方法参考。
Q: 如何添加自定义接口? A: 在Controller中添加自定义方法即可,会与继承的接口共存。
Q: 子表如何配置? A: 使用@SubEntity注解在主表实体类中配置子表关联。
Q: 不同模块的数据是否隔离? A: 是的,每个模块使用独立的数据源,通过@UseDataSource注解指定。
💡 提示:Basic继承体系是快速开发的最佳选择,通过继承和钩子方法的组合,既能快速实现功能,又保持了足够的灵活性。完整的钩子方法使用指南请参考钩子方法参考。