TocoAI生成代码架构总结
一、项目整体概览
技术栈:Java(JDK11 或以上)+ Spring Boot + MyBatis-Plus + Hibernate
顶层目录结构:
root/
├── pom.xml # 根 POM,声明全局依赖
├── common/ # 全局公共模块(UserContext、JwtUtil 等)
├── public_service/ # 跨模块 RPC 公开接口存放处
├── entrance/ # 项目启动入口(AppApplication、全局 Filter 等)
└── modules/ # 所有业务模块💡 注意:文中具体案例均基于《民宿系统》需求会员管理模块
二、单个业务模块的内部分层结构
每个业务模块均被拆分为 5 个 Maven 子模块,严格遵循四层架构:
modules/member/
├── pom.xml # 模块聚合 POM
├── common/ # 模块级枚举、常量、工具类
├── persist/ # 数据持久层
├── manager/ # 数据组装层(DTO 工厂)
├── service/ # 业务服务层(写操作核心)
└── entrance/ # HTTP 接入层(Controller)层间单向依赖关系(从上到下)
entrance
└── service
└── manager
└── persist
└── common / public_service(均可)三、各层核心职责与代码文件详解
1. common 层 — 模块公共定义
| 目录 | 内容 |
|---|---|
| enums/ | 枚举类型,如 MemberStatusEnum、RegisterChannelEnum |
| utils/ | 模块级工具类 |
| constants/ | 常量定义 |
2. persist 层 — 数据持久层(MyBatis-Plus 读 + Hibernate 写)
persist/
├── dos/
│ └── Member.java # DO:@TableName + @TableField,映射数据库表,MyBatis-Plus 使用
├── mapper/
│ ├── MemberDao.java # Dao 接口:提供 getByXxx 查询方法(供上层调用)
│ ├── MemberDaoImpl.java # Dao 实现:调用 MemberMapper 执行查询
│ └── mybatis/
│ └── MemberMapper.java # extends BaseMapper<Member>,MyBatis-Plus 原生 Mapper
└── qto/ # 读方案对应的查询参数对象(自动生成,禁止修改)关键特性:
- 读操作:使用 MyBatis-Plus,Mapper → Dao → Manager
- 写操作:使用 Hibernate(BO.persist()),绕过 Mapper 直接通过 JPA Session 持久化
3. manager 层 — 数据组装层(Entity → DTO 工厂)
manager/
├── dto/
│ └── MemberBaseDto.java # DTO 数据结构定义(FULLY_LOCKED,禁止修改)
├── bo/
│ ├── MemberBO.java # 聚合对象(充血模型,可扩展 validateAggregate)
│ │ └── 继承 base/BaseMemberBO.java(FULLY_LOCKED)
│ └── ...(PointRecordBO、RechargeRecordBO 等)
├── converter/
│ └── MemberBaseDtoConverter.java # DO → DTO 转换器(FULLY_LOCKED)
└── impl/
├── MemberBaseDtoManagerImpl.java # Manager 实现(可扩展)
└── base/
└── MemberBaseDtoManagerBaseImpl.java # 基类(FULLY_LOCKED,自动调用 Converter)关键特性:
- MemberBO 继承 BaseMemberBO,实现 BoValidator,使用 JPA 注解(
@Entity、@Column、@OneToMany等),作为 Hibernate 实体参与写操作 validateAggregate()方法是业务不变性校验扩展点(框架自动调用,禁止手动调用)- Converter 负责 DO → BaseDTO 的字段映射,只做 get/set
4. service 层 — 业务服务层(写操作核心 + DTO 查询服务)
service/
├── MemberBOService.java # 写操作入口,继承 BaseMemberBOService(STRUCTURE_LOCKED,可扩展方法体)
├── base/
│ └── BaseMemberBOService.java # 写操作框架代码(FULLY_LOCKED,框架生成的核心逻辑)
├── bto/
│ └── RegisterMemberBto.java # 写方案参数对象(FULLY_LOCKED,由写方案自动生成)
├── dto/
│ ├── MemberBaseDtoService.java # DTO 预置查询服务(implements PubMemberBaseDtoService)
│ ├── RechargeRecordBaseDtoService.java
│ └── assembler/
│ ├── MemberBaseDtoDataAssembler.java # 数据后处理扩展点(可实现 postProcessData)
│ └── base/
│ └── MemberBaseDtoBaseDataAssembler.java # 基类(FULLY_LOCKED)
└── query/ # 读方案生成的 QueryHandler(DtoQueryHandler)关键特性:
- BOService 写操作流程:Controller → BOService.writeMethod() → super.xxxBase(bto) → BaseBOService 操作 BO → rootBo.persist() 提交到 Hibernate Session
- DtoService 查询流程:Service.getByXxx() → Manager.getByXxx() → Dao.getByXxx() → Converter 转换 → DataAssembler.postProcessData() 后处理
5. entrance 层 — HTTP 接入层(Controller)
entrance/
└── web/
├── controller/
│ └── MemberController.java # @Controller + @Validated(STRUCTURE_LOCKED,方法体可修改)
├── vo/ # VO 结构定义(目前 member 模块未使用 VO 直接返回)
│ ├── converter/ # DTO → VO 转换器
│ └── assembler/ # VO 数据填充
└── query/ # VoQueryHandler(读方案返回 VO 时生成)关键特性:
- Controller 使用
@Controller(非@RestController),返回值由框架 HandlerMethodReturnValueHandler 自动包装为{code, message, data}格式,禁止加@ResponseBody - 只能使用 BTO/QTO/基本类型/Enum/VO 作为参数,禁止 DTO 直接暴露
四、模块间调用机制(RPC 订阅)
其他模块调用 member 模块的 MemberBaseDtoService:
┌─────────────┐
│ 其他模块 │
│ Controller │
└──────┬──────┘
│ @Resource 注入
▼
┌────────────────────────────────┐
│ public_service 模块 │
│ PubMemberBaseDtoService │ ← 公开 RPC 接口(Stub)
└────────────────┬───────────────┘
│ 实现类在 member 模块
▼
┌────────────────────────────────┐
│ member 模块 │
│ MemberBaseDtoService │ ← 实现 PubMemberBaseDtoService
└────────────────────────────────┘同模块调用:直接 @Resource 注入对应 Service,不走 public_service。
五、典型写操作完整调用链(以”注册会员”为例)
HTTP POST /api/member/register
│
▼
AuthFilter(JWT 校验 → UserContext 写入 memberId)
│
▼
MemberController.register(RegisterMemberBto)
├── 参数校验(validateRegisterParams)
├── 手机号唯一性校验(MemberBaseDtoService.getByPhone)
└── MemberBOService.registerMember(bto)
│
▼
BaseMemberBOService.registerMemberBase(bto)
├── 检查 phone 唯一键冲突
├── new MemberBO() + 设置字段
└── boResult.getAddedList().add(memberBO)
│
▼
MemberBO.persist() ← Hibernate Session flush → 写入 MySQL六、典型读操作完整调用链(以”按手机号查询会员”为例)
MemberBaseDtoService.getByPhone(phone)
│
▼
MemberBaseDtoManager.getByPhoneList([phone])
│
▼
MemberBaseDtoManagerBaseImpl
└── MemberDao.getByPhoneList([phone]) ← MyBatis-Plus 查询 MySQL
│
▼
MemberBaseDtoConverter.convertFromDo(memberList) ← DO → DTO
│
▼
MemberBaseDtoDataAssembler.postProcessData(dtoList) ← 自定义字段后处理扩展点
│
▼
返回 List<MemberBaseDto>💡 核心原则:读写分离(MyBatis-Plus 读 + Hibernate 写)+ 严格四层分层 + 以设计元素驱动代码生成。
最后更新于
