“ADR-002 - 数据库抽象”
ADR-002:数据库抽象
Section titled “ADR-002:数据库抽象”XOOPS 对象-oriented 数据库访问模式的架构决策记录。
已接受 - 自 XOOPS 2.0 起的核心模式
XOOPS 需要一个数据库交互策略:
1.抽象数据库-specificSQL语法 2. 跨所有模区块提供一致的CRUD操作 3.启用自动数据清理和转义 4.支持未来数据库引擎的变更 5、简化开发者常用操作
替代方案是:
- 整个代码库中的原始SQL
- 完整ORM(教义,雄辩)
- 自定义轻量级抽象
graph TB subgraph "Application Layer" A[Module Code] B[Handler Methods] end
subgraph "Abstraction Layer" C[XoopsObjectHandler] D[XoopsPersistableObjectHandler] E[Criteria System] end
subgraph "Database Layer" F[XoopsDatabase] G[MySQLDatabase] H[PDO Wrapper] end
subgraph "Storage" I[(MySQL/MariaDB)] end
A --> B B --> C B --> D C --> E D --> E E --> F F --> G F --> H G --> I H --> I我们将通过以下方式实现 处理程序模式:
1.XOOPSObject - 数据容器
Section titled “1.XOOPSObject - 数据容器”每个数据实体都扩展 XOOPSObject:
class Item extends XoopsObject{ public function __construct() { $this->initVar('id', XOBJ_DTYPE_INT, null, false); $this->initVar('title', XOBJ_DTYPE_TXTBOX, '', true, 255); $this->initVar('content', XOBJ_DTYPE_TXTAREA, '', false); $this->initVar('status', XOBJ_DTYPE_INT, 0, false); }}2. Handler - 运营经理
Section titled “2. Handler - 运营经理”每个对象都有一个对应的处理程序:
class ItemHandler extends XoopsPersistableObjectHandler{ public function __construct($db) { parent::__construct($db, 'mymodule_items', Item::class, 'id', 'title'); }
// CRUD methods inherited: // - create(), get(), insert(), delete() // - getObjects(), getCount(), getAll()}3. 标准 - 查询生成器
Section titled “3. 标准 - 查询生成器”对象-oriented查询条件:
$criteria = new CriteriaCompo();$criteria->add(new Criteria('status', 1));$criteria->add(new Criteria('created', time() - 86400, '>='));$criteria->setSort('created');$criteria->setOrder('DESC');$criteria->setLimit(10);
$items = $handler->getObjects($criteria);数据类型常量
Section titled “数据类型常量”// Variable types with automatic sanitizationXOBJ_DTYPE_INT // IntegerXOBJ_DTYPE_TXTBOX // Single-line text (escaped)XOBJ_DTYPE_TXTAREA // Multi-line text (escaped)XOBJ_DTYPE_EMAIL // Email validationXOBJ_DTYPE_URL // URL validationXOBJ_DTYPE_ARRAY // Serialized arrayXOBJ_DTYPE_OTHER // No processingXOBJ_DTYPE_FLOAT // Floating point处理程序继承
Section titled “处理程序继承”classDiagram class XoopsObjectHandler { <<abstract>> #db: XoopsDatabase +create(): XoopsObject +get(id): XoopsObject +insert(object): bool +delete(object): bool }
class XoopsPersistableObjectHandler { +getObjects(criteria): array +getCount(criteria): int +getAll(criteria): array +deleteAll(criteria): bool +updateAll(field, value, criteria): bool }
class ItemHandler { +getPublishedItems(): array +getByCategory(catId): array }
XoopsObjectHandler <|-- XoopsPersistableObjectHandler XoopsPersistableObjectHandler <|-- ItemHandler- 一致性:所有模区块使用相同的模式
- 安全:自动转义防止SQL注入
- 简单:常用操作需要最少的代码
- 可维护性:数据库层的更改不会影响模区块
- 可测试性:可以模拟处理程序以进行测试
- 性能:额外的抽象开销
- 复杂性:新开发人员的学习曲线
- 限制:复杂查询可能需要原始SQL
- N+1问题:未构建-in急切加载
- 性能:缓存经常访问的对象
- 复杂查询:需要时允许原始SQL
- N+1:按照适当的标准使用getAll()
演变为 XOOPS 4.0
Section titled “演变为 XOOPS 4.0”flowchart LR subgraph "Current (2.5.x)" A[XoopsDatabase] B[Handlers] C[Criteria] end
subgraph "Future (4.0.x)" D[PDO/DBAL] E[Repository Pattern] F[Query Builder] G[DI Container] end
A --> D B --> E C --> F D --> G E --> GXOOPS 4.0 计划:
- 数据库抽象的原则DBAL
- 存储库模式替换处理程序
- 用于复杂查询的查询构建器
- 完整的PSR-11容器集成
基本CRUD
Section titled “基本CRUD”$helper = Helper::getInstance();$handler = $helper->getHandler('Item');
// Create$item = $handler->create();$item->setVar('title', 'New Item');$handler->insert($item);
// Read$item = $handler->get($id);$title = $item->getVar('title');
// Update$item->setVar('title', 'Updated Title');$handler->insert($item);
// Delete$handler->delete($item);$criteria = new CriteriaCompo();$criteria->add(new Criteria('status', 'published'));$criteria->add(new Criteria('category_id', '(1,2,3)', 'IN'));$criteria->add(new Criteria('created', strtotime('-30 days'), '>='));$criteria->setSort('views');$criteria->setOrder('DESC');$criteria->setLimit(10);$criteria->setStart(0);
$items = $handler->getObjects($criteria);$total = $handler->getCount($criteria);- ADR-001:模区块化架构
- ADR-003:Smarty模板引擎
- Martin Fowler - 企业应用程序架构模式
- 领域-Driven设计理念
- Active Record 与 Data Mapper 模式
#XOOPS #architecture #adr #database #handler #design-decision