ADR-002 - 數據庫抽象
ADR-002:數據庫抽象
Section titled “ADR-002:數據庫抽象”XOOPS 面向對象數據庫訪問模式的架構決策記錄。
已接受 - XOOPS 2.0 以來的核心模式
XOOPS 需要數據庫交互策略,該策略可以:
- 抽象掉數據庫特定的 SQL 語法
- 在所有模塊中提供一致的 CRUD 操作
- 啟用自動數據清理和轉義
- 支持未來數據庫引擎的更改
- 為開發人員簡化常見操作
替代方案是:
- 整個代碼庫中的原始 SQL
- 完整的 ORM (Doctrine、Eloquent)
- 自定義輕量級抽象
graph TB subgraph "應用層" A[模塊代碼] B[處理器方法] end
subgraph "抽象層" C[XoopsObjectHandler] D[XoopsPersistableObjectHandler] E[Criteria 系統] end
subgraph "數據庫層" F[XoopsDatabase] G[MySQLDatabase] H[PDO 包裝器] end
subgraph "存儲" 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. 處理器 - 操作管理器
Section titled “2. 處理器 - 操作管理器”每個對象都有相應的處理器:
class ItemHandler extends XoopsPersistableObjectHandler{ public function __construct($db) { parent::__construct($db, 'mymodule_items', Item::class, 'id', 'title'); }
// 繼承的 CRUD 方法: // - create(), get(), insert(), delete() // - getObjects(), getCount(), getAll()}3. Criteria - 查詢構建器
Section titled “3. Criteria - 查詢構建器”面向對象的查詢條件:
$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 “數據類型常量”// 具有自動清理的變量類型XOBJ_DTYPE_INT // 整數XOBJ_DTYPE_TXTBOX // 單行文本(轉義)XOBJ_DTYPE_TXTAREA // 多行文本(轉義)XOBJ_DTYPE_EMAIL // 電子郵件驗證XOBJ_DTYPE_URL // URL 驗證XOBJ_DTYPE_ARRAY // 序列化數組XOBJ_DTYPE_OTHER // 無處理XOBJ_DTYPE_FLOAT // 浮點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 問題:沒有內置急加載
- 性能:緩存頻繁訪問的對象
- 複雜查詢:在需要時允許原始 SQL
- N+1:使用帶適當 Criteria 的 getAll()
XOOPS 4.0 的演進
Section titled “XOOPS 4.0 的演進”flowchart LR subgraph "當前 (2.5.x)" A[XoopsDatabase] B[Handlers] C[Criteria] end
subgraph "未來 (4.0.x)" D[PDO/DBAL] E[Repository 模式] F[查詢構建器] G[DI 容器] end
A --> D B --> E C --> F D --> G E --> GXOOPS 4.0 計劃:
- 用於數據庫抽象的 Doctrine DBAL
- 替換處理器的 Repository 模式
- 用於複雜查詢的查詢構建器
- 完整的 PSR-11 容器集成
基本 CRUD
Section titled “基本 CRUD”$helper = Helper::getInstance();$handler = $helper->getHandler('Item');
// 創建$item = $handler->create();$item->setVar('title', 'New Item');$handler->insert($item);
// 讀取$item = $handler->get($id);$title = $item->getVar('title');
// 更新$item->setVar('title', 'Updated Title');$handler->insert($item);
// 刪除$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 - 企業應用架構模式
- 域驅動設計概念
- Active Record vs Data Mapper 模式
#xoops #architecture #adr #database #handler #design-decision