Truy vấn dữ liệu trong Cakephp

Giống nhưng những framework khác. Cakephp hỗ trợ chúng ta 2 cách để truy vấn dữ liệu một là từ câu lệnh query trực tiếp và hai là thông qua hàm mà cakephp hỗ trợ.

1. Hàm find() – Truy vấn dữ liệu tự động

Cú pháp:

  •       $this->Model->find($type,$params);
    
    

##### Trong đó:
- ```PHP
        - $type là phương thức truy vấn dữ liệu, có thể là: 'all', 'first', 'count', 'list', 'neighbors' hoặc 'threaded', giá trị mặc định là 'first'.
        - $params là mảng tập hợp các điều kiện lấy dữ liệu, gom cụm dữ liệu, sắp xếp hoặc thể hiện dữ liệ.
        - array(
            //array of condition.
            'condition' => array( 'Model.field' => $this.value),
            'recursive' => 1,
            //array of field names
            'fields' => array( 'Model.field1', 'DISTINCT Model.field2',),
            //string of array defining order
            'order' => array( 'Model.created', 'Model.field2 DESC'),
            'group' => array( 'Model.field'),
            'limit' => n,
            'page' => n,
            'offset' => n,
            'callbacks' => true   //other possible values ore false, 'before', 'after'
        )
Để dễ dàng hơn chúng ta sẽ đi vào một ví dụ sau: Tạo bảng post với một vài dữ liệu đơn giản ()
  •       /*First, create our posts table:*/
          CREATE TABLE posts (
              id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
              title VARCAR(50),
              body TEXT,
              created DATETIME DEFAULT NULL,
              modified DATETIME DEFAULT NULL
          );
    
          /*Then insert some posts for testing*/
          INSERT INTO posts (title, body, created)
          VALUES
              ('The title', 'This is the post body.', NOW()),
              ('A title once again', 'And the post body follows.,', NOW()),
              ('Title strikes back', 'This is really exciting! Not.', NOW());
    
    

a. findAll()

Thêm vào PostsController function index:

  •       /*Select all post*/
          public function index() {
              $this->set('posts', $this->Post->find('all'));
          }
    
    
Bạn có thể thấy ở đây tôi sử dụng kiểu truy vấn tự động với type là “all” mà không cần dùng param nào. Hãy xem kết quả là gì:

    ![19.png](/uploads/images/430f69e148c3513e5689a7bbd194bbe880e88f71/5092590b4f04490a4112ecae4ac6bc2fbfad2760.png)

    Dữ liệu cấu trúc:
```PHP

        Array (
            [0] => Array (
                [Post] => Array (
                    [id] => 1
                    [title] => The title
                    [body] => This is the post body.
                    [created] => 2008-02-13 18:34:55
                    [modified] =>
                )
            )
            [1] => Array (
                [Post] => Array (
                    [id] => 2
                    [title] => A title once again
                    [body] => And the post body follows.
                    [created] => 2008-02-13 18:34:56
                    [modified] =>
                )
            )
            [2] => Array (
                [Post] => Array (
                    [id] => 3
                    [title] => Title strikes back
                    [body] => This is really exciting! Not.
                    [created] => 2008-02-13 18:34:57
                    [modified] =>
                )
            )
        )

Nếu muộn bạn có thể them param vào sử dụng fields để lấy ra các trường và conditions là điều kiện lọc của bạn:


        $this->Post->find('all',array('fields'=>array('Post.id','Post.title'), 'conditions'=>array('Post.id'=>2)));

b. find(‘first’):

  • Trả về kết quả đầu tiên tìm thấy, dữ liệu lấy ra thường lấy theo id.
  • Bạn cũng có thể truyền param và để lấy ra trường dữ liệu hay điều kiện để lọc.

c. find(‘count’):

  • Trả lại số kết quả truy vấn đúng.

d. find(‘list’):

  • Trả về một mảng danh sách kết quả thường là các id nếu bạn không đưa param vào.

  • Trường hợp muốn hiển thị kết quả là một trường dữ liệu khách bạn sử dụng fields để lấy ra trường cần thiết:

  •       $this-> Post->find('list',array('fields'=>array(‘Post.title’)));
    

### e. find(‘neighbors’)

- Trả về kết quả là dữ liệu phía trước và sau điều kiện tìm kiếm.

- Ví dụ: $this->Post->find('neighbors', array('field' => 'id', 'value' => 2)) thì dữ liệu đổ về chính là 2 bài post có id là 1 và 3;

- Để có được kết quả chính xác nên sử dụng param cho trường hợp này.

### f. Ngoài ra có rất nhiều cách để find ra dữ liệu mong muốn. Chúng ta có thể sử dụng findAllBy() hoặc findBy()

- findAllBy() làm việc giống như find(‘all’)

#### >>>> Cách sử dụng

- findAllBy<fieldName>(string $value, array $fields, array $order, int $limit, int $page, int $recursive)

    _Trong bảng post của tôi gồm các trường dữ liệu: Id, title, body, created, modify._

    _Tôi sẽ có những hàm sau:_

    - $this-> Post ->findAllByTitle(“string”);
    - $this-> Post ->findAllByBody(“string”);

    - …

    _Đặc biệt hơn. Tôi có thể ghép các <fieldname> lại với nhau_

    - $this-> Post ->findAllByTitleOrBody(“string”, “string”);

    - $this-> Post ->findAllByTitleAndBody(“string”, “string”);
    - ...
- findBy() làm việc giống như find(‘count’)

    Cách dung: findB<fieldName>(string $value[, mixed $fields[, mixed $order]]);

    Kết hợp với <fieldname> để có các hàm find giống như findAllBy().

    Một ví dụ đó là: findById($id)

    Đó chính là function view của chúng ta:

```PHP
        public function view($id = null) {
            if (!$id) {
                throw new NotFoundException(_('Invalid post'));
            }
            $post = $this->Post->findById($id);
            if (!$post) {
                throw new NotFoundException(_('Invalid post'));
            }
            $this->set('post', $post);
        }
![view1.png](/uploads/images/430f69e148c3513e5689a7bbd194bbe880e88f71/c1e9f5479448d48501f05751ebf9f6a6b7819cdb.png)

2. Truy vấn với câu lệnh query

  •       $sql = "SELECT * FROM posts LIMIT 2;"
          $this->Post->query($sql);
    
    

### 3. Ưu nhược điểm:

### a. Truy vấn tự động với find();

- Ưu điểm:
    - Được thực hiện thông quan khai báo quan hệ ở model, khi them hay thay đổi quan hệ giữa các bảng thì không ảnh hưởng đến code.
    - Dễ dàng hơn trong việc phần trang.
    - Kiểu dữ liệu truy xuất ra có cấu trúc mảng, cây dễ dàng cho việc thao tác để hiển thị.
    - Tránh các lỗi không đáng có như khi viết sql thuần.
    - Có thể khó khan cho người mới bắt đầu với cake và thường dung các câu sql thuần.

- Nhược điểm:
    - Việc truy vấn nhiều hơn.
    - Phải sử dụng hợp lý recursive và bindModel, quan hệ 1-1, 1-n, n-n.

### b. Sử dụng câu lệnh query:

- Ưu điểm:
    -  Không phụ thuộc vào quan hệ, chỉ là việc join giữa các bảng bằng câu sql thuần.
    -  Tốt độ truy vấn là nhanh hơn.

- Nhược điểm:
    - Phải nắm rõ quan hệ và thành thạo về các lệnh truy vấn để thao tác tốt nhất có thể để không lấy thừa, thiếu hay sai xót về dữ liệu.
    - Khi thay đổi quan hệ các bảng sẽ phải thay đổi, chỉnh sửa lại code. Nếu sử dụng nhiều câu lệnh sql thuần thì việc bảo trì, phát triển hệ thống sẽ rất khó khan.
    - Dữ liệu lấy ra phức tạp hơn, không dễ để sắp xếp theo cấu trúc.

### 4. Via:
- http://book.cakephp.org/