Site icon PlusMagi's Blog By Pitt Phunsanit

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>';
 
 }
 
}
Exit mobile version