Tag Archive pagination

Byphunsanit

Codeigniter reused active record query

ในการเขียน query บางครั้งก็ต้องเขียนคิวรี่ที่ต่างกันเล็กๆ น้อยๆ เช่น ต้องแบ่ง list ข้อมูลออกเป็นหน้า ๆ หรือที่เรียกกันว่า pagination จะมี 2 query ที่ต้องใช้คือ query ที่นับ ข้อมูลที่มีทั้งหมด
record count

SELECT `d`.`district_id`,
       `d`.`enable`,
       `d`.`district_code`,
       `d`.`district_name`,
       `p`.`province_name`
FROM   `district` AS `d`
       LEFT JOIN `province` AS `p`
              ON `d`.`province_id` = `p`.`province_id`

และ query ที่ดึงข้อมูลเฉพาะช่วงที่กำหนด
results

SELECT `d`.`district_id`,
       `d`.`enable`,
       `d`.`district_code`,
       `d`.`district_name`,
       `p`.`province_name`
FROM   `district` AS `d`
       LEFT JOIN `province` AS `p`
              ON `d`.`province_id` = `p`.`province_id`
LIMIT  0, 10

จะเห็นว่า ต่างกันแค่ LIMIT 0, 10 เท่านั้น แต่เพราะว่า ไม่ควร query ข้อมูล ที่ไม่ได้ใช้ จึงเปลี่ยน
record count

SELECT COUNT(district_id) AS recordsTotal
FROM   `district` AS `d`
       LEFT JOIN `province` AS `p`
              ON `d`.`province_id` = `p`.`province_id`

แก้ select ให้เป็น SELECT COUNT(DISTRICT_ID) AS recordsTotal แทนที่จะเลือกหลายๆ column หลาย row มาเพื่อแค่จะนับว่ามีข้อมูลกี่ record แค่นั้นเอง

ยังยุ่งไม่พอ เมื่อทำเป็น data table หรือ grid จะมีเงื่อนไขอย่าง เช่น filter ข้อมูล หรือ order ข้อมูลใหม่ตาม column ต่างๆ ที่ user ปลับเปลี่ยนเวลาใช้งาน ถ้าต้องเขียนเงื่อนใขเพิ่ม ถ้าเป็น query string อย่าง DISTRICT_ID = ‘xxx’ ก็พอจะเก็บในตัวแปรแล้วเอามาต่อกันได้ แต่ถ้าเขียนเป็น active record ก็ลำบากมากที่ต้องมาเขียนใหม่หลายๆจุด แต่ Codeigniter มีวิธี reused active record มาใช้ใหม่ได้ลดความซับซ้อนลงไปได้เยอะเลย

วิธีการคือเขียน query ส่วนที่ใช้ ร่วมกัน ระหว่าง ->start_cache(); และ ->stop_cache(); จากนั้นเขียน ส่วนอื่นเพิ่มเข้าไป เป็นวิธีที่ฉลาดมาก ๆ
/application/models/DatabasecachingModel.php

<?php
 
class DatabasecachingModel extends CI_Model
{
 
    public function __construct()
    {
        // Call the CI_Model constructor
        parent::__construct();
 
        $this->db = $this->load->database('db', true);
    }
 
    public function getPagination()
    {
        $post = $this->input->post();
 
        // Turn caching on
        $this->db->start_cache();
 
        $this->db->from('district AS d');
        $this->db->join('province AS p', 'd.PROVINCE_ID = p.PROVINCE_ID', 'left');
 
        if (isset($post['DISTRICT_ID'])) {
            $this->db->where('DISTRICT_ID', $post['DISTRICT_ID']);
        }
 
        if (isset($post['PROVINCE_ID'])) {
            $this->db->where('PROVINCE_ID', $post['PROVINCE_ID']);
        }
 
        $this->db->stop_cache();
 
        $this->db->select('COUNT(DISTRICT_ID) AS recordsTotal');
        $recordsTotal = $this->db->get()->row()->recordsTotal;
 
        echo '<br><br> query string for count = ' . $this->db->last_query();
        echo '<br> records total = ' . $recordsTotal;
 
        $this->db->select('d.DISTRICT_ID, d.enable, d.DISTRICT_CODE, d.DISTRICT_NAME, p.province_NAME');
        $this->db->limit(10, 0);
        $results = $this->db->get()->result_array();
 
        echo '<br><br> query string for results = ' . $this->db->last_query();
        echo '<pre>', print_r($results, true), '<pre>';
 
    }
 
}