1. DATABASE ABSTRACTION LAYER.
+ Drupal sẽ biết database nào dùng để kết nối và username, password cần để thiết lập kết nối với database bằng cách tìm kiếm trong file settting.php. File này đặc thù sẽ nằm ở drupal\sites\default. Dòng định nghĩa kết nối với database như sau :
Code: Chọn hết
$db_url = 'mysql://username:password@localhost/databasename';
+ Đã bao giờ bạn có một project và bạn cần thay đổi hệ thống database, bạn phải bỏ ra rất nhiều thời gian để chỉnh sửa code? Với database abstraction layer, bạn sẽ ko còn phải làm những công việc này, ví dụ : khi chuyển từ MySQL sang PostgreSQL bạn sẽ phải thay đổi mysql_quer() thành pg_query(), Drupal sẽ sử dụng db_query() và bạn không cần quan tâm đến hệ thống database đang sử dụng nữa.
+ Lớp Database abstraction được đưa ra với 2 mục đích chính :
- Giúp cho code của bạn tương thích với bất kỳ hệ thống database nào.
- Ngăn chặn các cuộc tấn công bằng lỗi SQL-injection.
+ Drupal xác định kiểu database để kết nối thông qua biến $db_url bên trong file setting.php. Ví dụ : nếu biến $db_url bắt đầu với mysql, Drupal sẽ include file includes/database.mysql.inc, nếu nó bắt đầu với pgsql Drupal sẽ include file includes/database.pgsql.inc
Hình ảnh
2. THỰC HIỆN TRUY VẤN
+ Drupal sẽ tự động kết nối với database và bạn sẽ không cần phải lo lắng về điều này.
+ Hàm db_query() của Drupal thường được dùng để để truy vấn với kết nối database đã active. Những truy vấn này bao gồm SELECT, UPDATE, INSERT và DELETE.
+ Ví dụ : lấy tất cả các dòng và các fields của bảng joke với field vid và nó cùng trị với $node->vid :
Code: Chọn hết
db_query('SELECT * FROM {joke} WHERE vid = %d', $node->vid);
+ Thêm vào 1 dòng :
Code: Chọn hết
db_query("INSERT INTO {joke} (nid, vid, punchline) VALUES (%d, %d, '%s')",
$node->nid, $node->vid, $node->punchline);
+ Cập nhật :
Code: Chọn hết
db_query("UPDATE {joke} SET punchline = '%s' WHERE vid = %d", $node->punchline,
$node->vid);
+ Xóa :
Code: Chọn hết
db_query('DELETE FROM {joke} WHERE nid = %d', $node->nid);
+ Đây là những cú pháp của Drupal mà bạn cần biết khi viết câu truy vấn SQL. Sau đây là bản tham số của Drupal SQL :
Hình ảnh
+ Tham số đầu tiên của db_query() luôn luôn là câu truy vấn, những cái còn lại là những giá trị động, nó sẽ được validate và thêm vào câu truy vấn.
3. NHÂN KẾT QUẢ TRUY VẤN.
+ Có nhiều cách để nhận kết quả truy vấn, phụ thuộc vào việc bạn cần 1 dòng hay toàn bộ tập kết quả hoặc bạn cũng có thể mở rộng kết quả.
+ Để lấy một giá trị đơn :
Code: Chọn hết
$sql = "SELECT COUNT(*) FROM {node} WHERE type = 'blog' AND status = 1";
$total = db_result(db_query($sql));
+ Để lấy nhiều dòng :
Code: Chọn hết
$sql = "SELECT * FROM {node} WHERE type = 'blog' AND status = 1";
$result = db_query(db_rewrite_sql($sql));
while ($data = db_fetch_object($result)) {
$node = node_load($data->nid);
print node_view($node, TRUE);
}
+ Lấy kết quả có giới hạn :
Code: Chọn hết
$sql = "SELECT * FROM {node} n WHERE type = 'blog' AND status = 1 ORDER BY
n.created DESC";
$result = db_query_range(db_rewrite_sql($sql), 0, 10);
Thay vì sử dụng từ khóa LIMIT trong câu truy cấn, chúng ta lại dùng db_query_range(). Tại sao lại dùng như vậy? Bởi vì không phải tất cả các hệ quản trị dữ liệu đều cung cấp từ khóa LIMIT.
+ Lấy kết quả để thể hiện thành trang (kĩ thuật dàn trang) :
Code: Chọn hết
$sql = "SELECT * FROM {node} n WHERE type = 'blog' AND status = 1 ORDER BY n.created DESC"
$result = pager_query(db_rewrite_sql($sql), 0, 10);
while ($data = db_fetch_object($result)) {
$node = node_load($data->nid);
print node_view($node, TRUE);
}
// Add links to remaining pages of results.
print theme('pager', NULL, 10);.
Hàm theme('pager') sẽ hiện thị các link đến các trang khác.
4. SỬ DỤNG BẢNG TEMPORARY
+ Nếu bạn làm việc với nhiều tiến trình, bạn có thể tạo bản Temporary (bảng tạm) trong suốt quá trình truy vấn. Bạn có thể dùng hàm db_query_temporary() với cú pháp như sau :
Code: Chọn hết
$result = db_query_temporary($sql, $arguments,
$temporary_table_name);
+ Sau khi tạo bảng temporary, bạn có thể dùng nó. Ví dụ: trong hàm do_search() của module Search, việc tìm kiếm được thực hiện qua nhiều giai đoạn bằng cách dùng các bảng tạm để lưu trữ thông tin trung gian :
Code: Chọn hết
// Select initial search results into temporary table named 'temp_search_sids'.
$result = db_query_temporary("
SELECT i.type, i.sid, SUM(i.score * t.count) AS relevance, COUNT(*) AS matches
FROM {search_index} i
INNER JOIN {search_total} t ON i.word = t.word $join1
WHERE $conditions
GROUP BY i.type, i.sid
HAVING COUNT(*) >= %d",
$arguments, 'temp_search_sids');
...
// Later: calculate maximum relevance, to normalize it, using temporary table.
$normalize = db_result(db_query('SELECT MAX(relevance) FROM temp_search_sids'));
...
// Still later: create a temporary search results table named 'temp_search_results'.
$result = db_query_temporary("
SELECT i.type, i.sid, $select2
FROM temp_search_sids i
INNER JOIN {search_dataset} d
ON i.sid = d.sid AND i.type = d.type $join2
WHERE $conditions $sort_parameters",
$arguments, 'temp_search_results');
...
// Finally: do actual search query.
$result = pager_query("SELECT * FROM temp_search_results", 10, 0, $count_query);
5. ĐẶT CÁC CÂU TRUY VẤN VÀO CÁC MODULE KHÁC VỚI HOOK_DB_REWRITE_SQL().
+ Các hook dùng để thay đổi các câu truy vấn được tạo ra ở một nơi khác trong Drupal để bạn không phải thay đổi các module một các trực tiếp.
+ Nếu bạn gởi một câu truy vấn đến hàm db_query() và bạn nghĩ rằng những người khác muốn thay đổi nó, bạn nên sử dụng db_rewrite_sql() để làm cho câu truy vấn có thể được tương tác bởi những người phát triển khác.
+ Khi một câu truy vấn được thực thi, đầu tiên nó sẽ kiểm tra xem tất cả các module có cài đặt hook db_rewrite_sql hay không, nếu có nó sẽ đưa cho chúng thay đổi câu query.
+ Ví dụ : module node sẽ thay đổi các câu truy vấn để liệt kê danh sách các node và ngăn chặn các node đã được bảo vệ bởi accsess rule.
+ Nếu bạn không đưa ra các câu truy vấn và muốn module của mình có thể thay đổi các câu truy vấn khác, bạn hãy cài đặt hook này trong module của bạn.
+ Để ghi đè các câu truy vấn :
Code: Chọn hết
function hook_db_rewrite_sql($query, $primary_table = 'n',
$primary_field = 'nid',$args = array())

Comments
Bài viết rất hay
Thanks,
Bạn có thể viết một bài về tạo một module và khi cài đặt module thì tự động cài đặt table cho module đó, khi xóa module thì xóa table và xóa thư mục của module đó luôn được không?
Xin cảm ơn!
HOANG BIEN
Tôi thấy có hàm
Tôi thấy có hàm hook_uninstall() bạn có thể dùng để xoá table nhé !
Mời truy cập Vietdex.com là mạng hỏi đáp trực tuyến, Vietdex.net là mạng xã hội viết blog !
BÀi viết của bạn rất xúc
BÀi viết của bạn rất xúc tích, cảm ơn rất nhiều vì tinh thần chia sẻ của bạn...
Cảm ơn !
Cảm ơn vì những đóng góp to lớn cho cộng đồng Drupal Việt của bạn !
Tôi đang học Drupal và thấy bài viết rất có ích và dễ hiểu !
My blog: Jamviet.com, Hỏi đáp trực tuyến, váy dài
Mình cũng đang tìm hiểu về
Mình cũng đang tìm hiểu về các hàm trong drupal, bài viết này đúng là rất có ích. Thank chủ thớt!
My Blog, Thiết kế nội thất chung cư giá rẻ, Thiết kế và thi công chung cư
Chào bạn, mình muốn thực hiện
Chào bạn, mình muốn thực hiện import dự liễu từ bảng này sang bảng khác trong drupal có hỗ trợ ko?
Ví dụ bảng A là chi tiết của cả tháng, bảng B mình chỉ muốn lưu thông tin sau khi đã đc group by và count khi insert sang bảng B sợ có lỗi. Nếu lỗi pải rollback và thông báo lỗi.
Dịch vụ chụp ảnh cưới
Thắc mắc về cơ sở dữ liệu của Drupal
E mới tìm hiểu về Drupal, nhưng chỉ biết sử dụng một số module căn bản để vận dụng làm bài toán. Hiện tại bài toán của e có chức năng thống kê, nghĩa là có một danh sách hợp đồng, có ngày thực hiện cụ thể, căn cứ vào ngày bắt đầu và ngày kết thúc thì mình có thể liệt kê ra danh sách hợp đồng đang thực hiện, hợp đồng đã hết hạn, cái này e dùng bộ lọc của có sẵn của Drupal và làm được rồi. Còn phần liệt kê danh sách hợp đồng đã thực hiện trong 1 khoảng thời gian (ví dụ như 2 tháng, 3 tháng ) e chưa biết làm kiểu gì, k biết có module có sẵn k? E có ý tưởng là sử dụng câu lệnh truy vấn trong cơ sở dữ liệu để đưa ra view, nhưng chưa rõ là phải thực hiện như thế nào, thay đổi cái gì, nên hi vọng các bậc tiền bối có thể chỉ cho e hướng làm được k ạ. Cảm ơn nhiều ạ.