DAO 分库机制与 Process 服务工厂¶
本文讲清 OBPM 数据访问层两大机制:Abstract*DAO → 每库一实现 的方言分库,与 ProcessFactory → *Process/*ProcessBean 的服务门面。基类体系见 [[entity-base-hierarchy]]。
1. DAO 三层结构(多数据库支持的核心)¶
以工作流实例 DAO 为例(全平台同构):
classDiagram
class IRuntimeDAO {
<<interface, core/common/dao>>
通用 DAO 契约
}
class FlowStateRTDAO {
<<interface>>
实体专属契约
}
class AbstractFlowStateRTDAO {
<<abstract>>
手写 SQL 的主体
getFullTableName() 抽象
}
class MysqlFlowStateRTDAO
class OracleFlowStateRTDAO
class PostgreSQLFlowStateRTDAO
class HsqldbFlowStateRTDAO
IRuntimeDAO <|.. AbstractFlowStateRTDAO
FlowStateRTDAO <|.. AbstractFlowStateRTDAO
AbstractFlowStateRTDAO <|-- MysqlFlowStateRTDAO
AbstractFlowStateRTDAO <|-- OracleFlowStateRTDAO
AbstractFlowStateRTDAO <|-- PostgreSQLFlowStateRTDAO
AbstractFlowStateRTDAO <|-- HsqldbFlowStateRTDAO
各层职责¶
| 层 | 职责 |
|---|---|
IRuntimeDAO |
平台级 DAO 契约(连接管理入口) |
*DAO 接口(如 FlowStateRTDAO) |
实体专属方法签名 |
Abstract*DAO |
SQL 主体写在这里(INSERT INTO T_FLOWSTATERT (ID,FLOWID,...) 列清单即表结构的权威来源);方言差异点抽为钩子 |
Mysql*DAO / Oracle*DAO / PostgreSQL*DAO / KingBase*DAO / DmSQL*DAO / OceanBase*DAO / Oscar*DAO / DB2*DAO / Hsqldb*DAO… |
每库一个薄子类:只覆写分页 LIMIT、函数、schema 前缀(KingBase/OceanBase 常强制 PUBLIC.)、类型差异等钩子 |
要点:新增数据库 = 为每个 Abstract*DAO 派生一个薄子类 + 动态表侧增加一组 *Builder/*TableDefinition/*Validator(designtime/table/ddlutil/<db>/)。这也解释了为什么表结构文档(design/table-schema/core-tables.md)可以从 DAO 的 INSERT 列清单提取——SQL 就写在抽象层。
2. Process 服务工厂(业务门面)¶
DAO 之上是 Process 层——对外统一业务入口,ProcessFactory 按运行上下文创建:
classDiagram
class ProcessFactory {
<<obpm-core/util>>
+getInstance() iProcessFactory$
+createProcess(Class) AuthTimeService$
+createRuntimeProcess(Class,...) RunTimeService$
}
class iProcessFactory {
<<interface>>
}
class AuthTimeService {
<<interface>>
认证域服务 doCreate/doUpdate/...
}
class RunTimeService {
<<interface>>
运行域服务 + 事务
beginTransaction/commit
}
class AbstractAuthTimeServiceImpl {
<<abstract, E 泛型>>
}
class AbstractRunTimeServiceImpl {
<<abstract>>
}
class UserProcess
class UserProcessBean
class DocumentProcess
class DocumentProcessBean
ProcessFactory --> iProcessFactory : 单例
iProcessFactory <|.. AuthTimeService
ProcessFactory ..> RunTimeService
AuthTimeService <|-- AbstractAuthTimeServiceImpl
RunTimeService <|-- AbstractRunTimeServiceImpl
AbstractAuthTimeServiceImpl <|-- UserProcessBean
UserProcess <|.. UserProcessBean
AbstractRunTimeServiceImpl <|-- DocumentProcessBean
DocumentProcess <|.. DocumentProcessBean
调用机制¶
flowchart TD
A[Controller / iScript] -->|"ProcessFactory.createProcess(UserProcess.class)"| B[iProcessFactory 实现]
B -->|按域路由| C[UserProcessBean<br/>AuthTime 线]
B -->|按域路由| D[DocumentProcessBean<br/>RunTime 线]
C --> E["按 dbType / 数据源<br/>new MysqlUserDAO / OracleUserDAO / …"]
D --> F["AbstractDocStaticTblDAO 子类<br/>按 tabelType 写 TLK_ / LOG_"]
E --> G[(系统库 T_USER 等)]
F --> H[(业务库 TLK_ 动态表)]
| 概念 | 说明 |
|---|---|
AuthTimeService<E> |
认证/组织域服务根接口(User/Department/Domain…),E 为实体泛型 |
RunTimeService<E> |
运行域服务根接口,多出 beginTransaction/commitTransaction 事务边界(跨 DAO 组合写) |
*Process 接口 |
每实体一份业务契约(UserProcess、DocumentProcess、TaskInfoProcess…),iScript 通过 getProcess() 系列拿到 |
*ProcessBean |
实现类,继承两个抽象基类之一;内部再按数据库选 DAO——调用方永远不感知数据库类型 |
两条服务线的划分与继承主线一致:AuthTime 管组织/租户(数据在系统库),RunTime 管业务文档/流程(数据可在任意业务库)。ProcessFactory.createProcess vs createRuntimeProcess 的区别即在于此。
3. 设计时侧的平行机制¶
workspace 资源的读写不走 DAO 分库,而是 AbstractFSDesignTimeDAO(文件系统 DAO)+ DesignTimeServiceManager → 各 *DesignTimeServiceImpl(如 FormDesignTimeServiceImpl、ApplicationDesignTimeServiceImpl)。与 Process 层同构(Service 接口 + Impl + Manager 工厂),只是存储介质换成 XML 文件。见 [[../../workspace-mechanism/overview]]。