Query XML
Trong Zittme, bạn không viết SQL trực tiếp mà khai báo bảng và truy vấn bằng XML. Dù loại DB khác nhau, cùng một mã vẫn chạy được, và vì giá trị được bind tự động nên không phải lo SQL injection.
Khai báo bảng: schemas/*.xml
Tên tệp chính là tên bảng. Lõi sẽ tạo bảng khi cài mô-đun.
<table name="mymodule_item">
<column name="item_srl" type="bigint" notnull="notnull" primarykey="primarykey" />
<column name="member_srl" type="bigint" notnull="notnull" index="idx_member_srl" />
<column name="title" type="varchar" size="250" notnull="notnull" />
<column name="content" type="bigtext" />
<column name="status" type="varchar" size="10" notnull="notnull" default="open" index="idx_status" />
<column name="regdate" type="char" size="14" index="idx_regdate" />
</table>- Các kiểu chính:
number/bigint/varchar(bắt buộc size) /char/text/bigtext/date/float - Theo quy ước, ngày được lưu dưới dạng chuỗi
YYYYMMDDHHIISStrongchar(14)(date('YmdHis')). - Số định danh duy nhất được cấp bằng
getNextSequence()rồi đưa vào cột*_srl.
Thêm cột khi đang vận hành: lõi không tự thêm cột mới vào bảng đã được tạo. Bạn phải làm đồng thời hai việc: sửa XML schema + gọi addColumn() trong moduleUpdate của Install.
Khai báo truy vấn: queries/*.xml
SELECT
<query id="getItems" action="select">
<tables>
<table name="mymodule_item" />
</tables>
<columns>
<column name="*" />
</columns>
<conditions>
<condition operation="equal" column="status" var="status" default="open" />
<condition operation="like" column="title" var="s_title" pipe="and" />
<condition operation="more" column="regdate" var="start_regdate" pipe="and" />
</conditions>
<navigation>
<index var="sort_index" default="item_srl" order="desc" />
<list_count var="list_count" default="20" />
<page var="page" default="1" />
</navigation>
</query>varlà tên của giá trị được truyền từ PHP. Nếu không truyền giá trị, toàn bộ điều kiện đó bị bỏ qua. Với điều kiện bắt buộc, hãy thêmnotnull="notnull".defaultlà giá trị mặc định khi không có giá trị.pipelà liên kết (and/or) với điều kiện phía trước. Không dùng cho điều kiện đầu tiên.
Toàn bộ operation có thể dùng:
| operation | SQL | Ý nghĩa |
|---|---|---|
equal | = | Bằng |
notequal (=not_equal) | != | Khác |
more (=gte) | >= | Lớn hơn hoặc bằng |
excess (=gt) | > | Lớn hơn |
less (=lte) | <= | Nhỏ hơn hoặc bằng |
below (=lt) | < | Nhỏ hơn |
like / notlike | LIKE '%value%' | Chứa / không chứa |
like_prefix (=like_head) | LIKE 'value%' | Bắt đầu bằng ~ |
like_tail (=like_suffix) | LIKE '%value' | Kết thúc bằng ~ |
search | LIKE '%value%' theo từng từ | Tách từ khóa thành từng từ và so khớp từng từ |
in / notin | IN (...) | Có trong / loại khỏi danh sách |
between | BETWEEN | Khoảng |
null / notnull | IS (NOT) NULL | Kiểm tra null |
regexp / notregexp | REGEXP | Biểu thức chính quy |
- Nếu đặt
list_countvàpagetrong<navigation>, kết quảexecuteQueryArraysẽ kèm thông tin phân trang (page_navigation).
INSERT / UPDATE / DELETE
<query id="insertItem" action="insert">
<tables>
<table name="mymodule_item" />
</tables>
<columns>
<column name="item_srl" var="item_srl" notnull="notnull" filter="number" />
<column name="title" var="title" notnull="notnull" />
<column name="content" var="content" />
<column name="status" var="status" default="open" />
<column name="regdate" var="regdate" />
</columns>
</query><query id="updateItemStatus" action="update">
<tables>
<table name="mymodule_item" />
</tables>
<columns>
<column name="status" var="status" notnull="notnull" />
</columns>
<conditions>
<condition operation="equal" column="item_srl" var="item_srl" filter="number" notnull="notnull" />
</conditions>
</query>filter="number"là bước kiểm tra chỉ cho phép số đi qua.- Với delete, chỉ cần
action="delete"và conditions. Để tránh delete/update không có điều kiện, hãy luôn thêm notnull cho điều kiện cốt lõi.
Chạy từ PHP
$args = new \stdClass;
$args->status = 'open';
$args->page = (int)\Context::get('page') ?: 1;
$output = executeQueryArray('mymodule.getItems', $args);
if (!$output->toBool())
{
return $output; // DB 오류
}
$items = $output->data; // 항상 배열
$paging = $output->page_navigation; // navigation 선언 시executeQuerymang tính một bản ghi, cònexecuteQueryArrayluôn trả kết quả dưới dạng mảng. Với danh sách, hãy dùng phiên bản Array.- Nếu cần join, đặt hai bảng trong
<tables>và nối chúng trong<conditions>, hoặc dùng<table type="left join">với khai báo<conditions>con. Với join phức tạp, cách nhanh nhất là tham khảo XML truy vấn của các mô-đun lõi (board, document).
Cạm bẫy phổ biến nhất
Cột không có trong <columns> sẽ bị bỏ qua âm thầm. Dù bạn truyền $args->new_column = 'value' từ PHP, nếu cột đó không được khai báo trong <columns> của XML truy vấn insert/update thì nó bị bỏ qua mà không báo lỗi. Nếu "rõ ràng đã đưa vào mà DB không có", gần như chắc chắn là trường hợp này.
Khi thêm cột, hãy sửa đồng thời ba chỗ.
- Thêm cột vào
schemas/table.xml - addColumn trong moduleUpdate của Install (cho website đã cài trước đó)
- Thêm vào
<columns>của XML truy vấn insert/update liên quan