ADR-002 - Trừu tượng hóa cơ sở dữ liệu
ADR-002: Trừu tượng hóa cơ sở dữ liệu
Phần tiêu đề “ADR-002: Trừu tượng hóa cơ sở dữ liệu”Bản ghi quyết định kiến trúc cho mẫu truy cập cơ sở dữ liệu hướng đối tượng của XOOPS.
Trạng thái
Phần tiêu đề “Trạng thái”Được chấp nhận - Mẫu lõi kể từ XOOPS 2.0
Bối cảnh
Phần tiêu đề “Bối cảnh”XOOPS cần một chiến lược tương tác cơ sở dữ liệu có thể:
- Tóm tắt cú pháp SQL dành riêng cho cơ sở dữ liệu
- Cung cấp các hoạt động CRUD nhất quán trên tất cả modules
- Kích hoạt tính năng tự động dọn dẹp và thoát dữ liệu
- Hỗ trợ các thay đổi về công cụ cơ sở dữ liệu trong tương lai
- Đơn giản hóa các thao tác chung cho nhà phát triển
Các lựa chọn thay thế là:
- SQL thô trong toàn bộ cơ sở mã
- ORM đầy đủ (Học thuyết, Hùng biện)
- Trừu tượng nhẹ tùy chỉnh
Sơ đồ quyết định
Phần tiêu đề “Sơ đồ quyết định”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 --> IQuyết định
Phần tiêu đề “Quyết định”Chúng tôi sẽ triển khai Mẫu trình xử lý với:
1. XoopsObject - Nơi chứa dữ liệu
Phần tiêu đề “1. XoopsObject - Nơi chứa dữ liệu”Mỗi thực thể dữ liệu mở rộng 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 - Trình quản lý vận hành
Phần tiêu đề “2. Handler - Trình quản lý vận hành”Mỗi đối tượng có một trình xử lý tương ứng:
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. Tiêu chí - Trình tạo truy vấn
Phần tiêu đề “3. Tiêu chí - Trình tạo truy vấn”Điều kiện truy vấn hướng đối tượng:
$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);Hằng số kiểu dữ liệu
Phần tiêu đề “Hằng số kiểu dữ liệu”// 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 pointKế thừa trình xử lý
Phần tiêu đề “Kế thừa trình xử lý”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 <|-- ItemHandlerHậu quả
Phần tiêu đề “Hậu quả”Tích cực
Phần tiêu đề “Tích cực”- Tính nhất quán: Tất cả modules đều sử dụng các mẫu giống nhau
- Bảo mật: Tự động thoát ngăn chặn việc tiêm SQL
- Đơn giản: Các thao tác thông thường yêu cầu mã tối thiểu
- Khả năng bảo trì: Các thay đổi đối với lớp cơ sở dữ liệu không ảnh hưởng đến modules
- Khả năng kiểm tra: Trình xử lý có thể bị mô phỏng để kiểm tra
Tiêu cực
Phần tiêu đề “Tiêu cực”- Hiệu suất: Chi phí trừu tượng bổ sung
- Độ phức tạp: Đường cong học tập dành cho nhà phát triển mới
- Hạn chế: Các truy vấn phức tạp có thể cần SQL thô
- Vấn đề N+1: Không có tính năng tải háo hức tích hợp
Biện pháp giảm nhẹ
Phần tiêu đề “Biện pháp giảm nhẹ”- Hiệu suất: Lưu vào bộ nhớ đệm các đối tượng được truy cập thường xuyên
- Truy vấn phức tạp: Cho phép SQL thô khi cần
- N+1: Sử dụng getAll() với tiêu chí phù hợp
Tiến hóa lên XOOPS 4.0
Phần tiêu đề “Tiến hóa lên 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 --> GGói XOOPS 4.0:
- Học thuyết DBAL để trừu tượng hóa cơ sở dữ liệu
- Mẫu lưu trữ thay thế trình xử lý
- Trình tạo truy vấn cho các truy vấn phức tạp
- Tích hợp container PSR-11 đầy đủ
Ví dụ về mã
Phần tiêu đề “Ví dụ về mã”CRUD cơ bản
Phần tiêu đề “CRUD cơ bản”$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);Truy vấn phức tạp
Phần tiêu đề “Truy vấn phức tạp”$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);Các quyết định liên quan
Phần tiêu đề “Các quyết định liên quan”- ADR-001: Kiến trúc mô-đun
- ADR-003: Công cụ mẫu Smarty
Tài liệu tham khảo
Phần tiêu đề “Tài liệu tham khảo”- Martin Fowler - Các mô hình kiến trúc ứng dụng doanh nghiệp
- Khái niệm thiết kế hướng tên miền
- Mẫu bản ghi hoạt động và bản đồ dữ liệu
#xoops #architecture #adr #database #handler #design-decision