Active Record 類別

CodeIgniter 使用一個 Active Record 資料庫模式的修改版本。這個模式允許資訊在你的資料庫中靠最少的程式被接收、新增與更新。在一些狀況下, 只需要一兩行的程式就足以執行資料庫動作。 CodeIgniter 不需要每個資料表擁有他自己的類別檔案, 它取而代之提供一個更簡單的介面。

不只是簡單, 既然查詢語法是由各個資料庫界面所產生的, 一個使用 Active Record 功能的重大的益處是它允許你建立不依賴特定資料庫的應用程式。既然所有的值都會由系統自動跳脫(escape), 它也讓查詢更安全。

注意: 如果你想寫自己的查詢, 你可以在資料庫設定檔裡取消使用這個類別。這樣可以讓核心的資料庫程式庫以及界面耗用更少的資源。

 挑選(Selecting)資料

以下函數讓你建立 SQL SELECT 語句。

注意:如果你使用 PHP 5, 那你可以使用方法串接(method chaining)來讓語法更精簡。這在本頁最後會說明。

$this->db->get();

執行select查詢並返回結果。可以用來取得資料表中所有紀錄:

$query = $this->db->get('mytable');

// 產生: SELECT * FROM mytable

第二與第三個參數讓你可以設定 limit 與 offset 子句:

$query = $this->db->get('mytable', 10, 20);

// 產生: SELECT * FROM mytable LIMIT 20, 10 (使用MySQL。其它資料庫有不太一樣的語法。)

你會注意到, 上面的函數賦值給一個叫做 $query 的變數, 它可以用來顯示結果:

$query = $this->db->get('mytable');

foreach ($query->result() as $row)
{
    echo $row->title;
}

請訪問 result 函數 頁面來獲得關於產生結果的討論。

$this->db->get_where();

下面可以取代 db->where() 函數, 除了可以讓你在第二個參數加上 "where" 子句以外, 其餘與上面這個函數相同:

$query = $this->db->get_where('mytable', array('id' => $id), $limit, $offset);

請參閱底下關於 "where" 函數的詳細資訊。

注意: get_where() 之前叫做 getwhere(), 舊的函數名稱已經被移除。

$this->db->select();

允許你自訂查詢中的 "select" 部份:

$this->db->select('title, content, date');

$query = $this->db->get('mytable');

// 產生: SELECT title, content, date FROM mytable

注意: 如果你要選擇資料表中所有欄位(*), 那你不需要使用這個函數。當省略時, CodeIgniter 假設你要的是 SELECT * 。

$this->db->select() 可額外接受第二個參數。如果你傳入 FALSE, CodeIgniter 將不使用反單引號(`, 在英文鍵盤左上方)來保護你的欄位或資料表名稱。這在你需要一個合成的 select 敘述時會很有用。

$this->db->select('(SELECT SUM(payments.amount) FROM payments WHERE payments.invoice_id=4') AS amount_paid', FALSE);
$query = $this->db->get('mytable');

$this->db->select_max();

可以為你的查詢做出 "SELECT MAX(欄位)" 的部份。你可以額外加入第二個參數來重新命名結果欄位。

$this->db->select_max('age');
$query = $this->db->get('members');
// 產生: SELECT MAX(age) as age FROM members

$this->db->select_max('age', 'member_age');
$query = $this->db->get('members');
// 產生: SELECT MAX(age) as member_age FROM members

$this->db->select_min();

可以為你的查詢做出 "SELECT MIN(欄位)" 的部份。如同 select_max() , 你可以額外加入第二個參數來重新命名結果欄位。

$this->db->select_min('age');
$query = $this->db->get('members');
// 產生: SELECT MIN(age) as age FROM members

$this->db->select_avg();

可以為你的查詢做出 "SELECT AVG(欄位)" 的部份。如同 select_max() , 你可以額外加入第二個參數來重新命名結果欄位。

$this->db->select_avg('age');
$query = $this->db->get('members');
// 產生: SELECT AVG(age) as age FROM members

$this->db->select_sum();

可以為你的查詢做出 "SELECT SUM(欄位)" 的部份。如同 select_max() , 你可以額外加入第二個參數來重新命名結果欄位。

$this->db->select_sum('age');
$query = $this->db->get('members');
// 產生: SELECT SUM(age) as age FROM members

$this->db->from();

允許你撰寫查詢的 FROM 部份:

$this->db->select('title, content, date');
$this->db->from('mytable');

$query = $this->db->get();

// 產生: SELECT title, content, date FROM mytable

注意: 如同之前看到的, 你的查詢的 FROM 部份可以在 $this->db->get() 函數中指定, 所以喜歡哪個就用哪個。

$this->db->join();

允許你撰寫查詢的 JOIN 部份:

$this->db->select('*');
$this->db->from('blogs');
$this->db->join('comments', 'comments.id = blogs.id');

$query = $this->db->get();

// 產生:
// SELECT * FROM blogs
// JOIN comments ON comments.id = blogs.id

如果你需要在一個查詢中使用多個 JOIN , 你可以多次呼叫這個函數。

你可以透過函數的第三個參數來指定 join 的型態。可用的選項有: left、right、outer、inner、left outer 以及 right outer 。

$this->db->join('comments', 'comments.id = blogs.id', 'left');

// 產生: LEFT JOIN comments ON comments.id = blogs.id

$this->db->where();

This function enables you to set WHERE clauses using one of four methods: 這個函數讓你能用以下四個方法之一來設定 WHERE 子句:

注意: 所有傳到這個函數的值都會自動跳脫(escape), 以產生更安全的查詢。

  1. 簡單的 鍵/值 方法: $this->db->where('name', $name);

    // 產生: WHERE name = 'Joe'

    注意它會為你加上等於符號。

    如果你多次呼叫這個函數, 那它會把這些用 AND 串在一起:

    $this->db->where('name', $name);
    $this->db->where('title', $title);
    $this->db->where('status', $status);

    // WHERE name = 'Joe' AND title = 'boss' AND status = 'active'
  2. 自訂的 鍵/值 方法:

    你可以在第一個參數包含一個運算子來控制比較的方法:

    $this->db->where('name !=', $name);
    $this->db->where('id <', $id);

    // 產生: WHERE name != 'Joe' AND id < 45
  3. 關聯陣列方法: $array = array('name' => $name, 'title' => $title, 'status' => $status);

    $this->db->where($array);

    // 產生: WHERE name = 'Joe' AND title = 'boss' AND status = 'active'

    你也可以在這個方法包含你要用的運算子:

    $array = array('name !=' => $name, 'id <' => $id, 'date >' => $date);

    $this->db->where($array);
  4. 自訂字串:

    你可以手動撰寫你要的子句:

    $where = "name='Joe' AND status='boss' OR status='active'";

    $this->db->where($where);

$this->db->where() 可接受額外的第三個參數。如果你傳入 FALSE, CodeIgniter 將不會嘗試使用反單引號(`, 在英文鍵盤左上方)來保護你的欄位或資料表名稱。

$this->db->where('MATCH (field) AGAINST ("value")', NULL, FALSE);

$this->db->or_where();

除了使用 OR 來串接傳入的查詢條件, 這個函數與上面的相同:

$this->db->where('name !=', $name);
$this->db->or_where('id >', $id);

// 產生: WHERE name != 'Joe' OR id > 50

注意: or_where() 之前叫做 orwhere() , 舊的函數名稱已經移除。

$this->db->where_in();

產生一個 WHERE field IN ('item', 'item') 的 SQL 查詢, 如果合適的話就用 AND 來串接。

$names = array('Frank', 'Todd', 'James');
$this->db->where_in('username', $names);
// 產生: WHERE username IN ('Frank', 'Todd', 'James')

$this->db->or_where_in();

產生一個 WHERE field IN ('item', 'item') 的 SQL 查詢, 如果合適的話就用 OR 來串接。

$names = array('Frank', 'Todd', 'James');
$this->db->or_where_in('username', $names);
// 產生: OR username IN ('Frank', 'Todd', 'James')

$this->db->where_not_in();

產生一個 WHERE field NOT IN ('item', 'item') 的 SQL 查詢, 如果合適的話就用 AND 來串接。

$names = array('Frank', 'Todd', 'James');
$this->db->where_not_in('username', $names);
// 產生: WHERE username NOT IN ('Frank', 'Todd', 'James')

$this->db->or_where_not_in();

產生一個 WHERE field NOT IN ('item', 'item') 的 SQL 查詢, 如果合適的話就用 OR 來串接。

$names = array('Frank', 'Todd', 'James');
$this->db->or_where_not_in('username', $names);
// 產生: OR username NOT IN ('Frank', 'Todd', 'James')

$this->db->like();

這個函數讓可能產生 LIKE 子句, 可用來做搜尋。

注意: 所有傳到這個函數的值都會自動跳脫(escape)。

  1. 簡單的 鍵/值 方法: $this->db->like('title', 'match');

    // 產生: WHERE title LIKE '%match%'

    If you use multiple function calls they will be chained together with AND between them: 如果你多次呼叫這個函數, 它會把這些用 AND 串接在一起:

    $this->db->like('title', 'match');
    $this->db->like('body', 'match');

    // 產生: WHERE title LIKE '%match%' AND body LIKE '%match%
    如果你想要控制萬用字元 (%)出現的位置, 你可以使用額外的第三個參數。可以使用的選項有 'before'、'after' 以及 'both' (這是預設值)。 $this->db->like('title', 'match', 'before');
    // 產生: WHERE title LIKE '%match'

    $this->db->like('title', 'match', 'after');
    // 產生: WHERE title LIKE 'match%'

    $this->db->like('title', 'match', 'both');
    // 產生: WHERE title LIKE '%match%'
  2. 關聯陣列方法: $array = array('title' => $match, 'page1' => $match, 'page2' => $match);

    $this->db->like($array);

    // 產生: WHERE title LIKE '%match%' AND page1 LIKE '%match%' AND page2 LIKE '%match%'

$this->db->or_like();

除了使用 OR 來串接傳入的條件, 著個函數與上面的相同:

$this->db->like('title', 'match');
$this->db->or_like('body', $match);

// 產生: WHERE title LIKE '%match%' OR body LIKE '%match%'

注意: or_like() 之前叫做 orlike(), 舊的函數名稱已經移除。

$this->db->not_like();

除了會產生 NOT LIKE 敘述之外, 這個函數與 like() 相同。

$this->db->not_like('title', 'match');

// 產生: WHERE title NOT LIKE '%match%

$this->db->or_not_like();

除了使用 OR 來串接傳入的條件, 這個函數與 not_like() 相同。

$this->db->like('title', 'match');
$this->db->or_not_like('body', 'match');

// 產生: WHERE title LIKE '%match% OR body NOT LIKE '%match%'

$this->db->group_by();

Permits you to write the GROUP BY portion of your query: 讓你撰寫你查詢中的 GROUP BY 部份:

$this->db->group_by("title");

// 產生: GROUP BY title

你也可以用正列傳給它多個值:

$this->db->group_by(array("title", "date"));

// 產生: GROUP BY title, date

注意: group_by() 之前叫做 groupby(), 舊的函數名稱已經移除。

$this->db->distinct();

在查詢中加入"DISTINCT" 關鍵字

$this->db->distinct();
$this->db->get('table');

// 產生: SELECT DISTINCT * FROM table

$this->db->having();

允許你撰寫你查詢中的 HAVING 部份。有兩種可用的語法, 使用一個或兩個參數:

$this->db->having('user_id = 45');
// 產生: HAVING user_id = 45

$this->db->having('user_id', 45);
// 產生: HAVING user_id = 45

你也可以用陣列來傳給它多個值:

$this->db->having(array('title =' => 'My Title', 'id <' => $id));

// 產生: HAVING title = 'My Title', id < 45

如果你在使用的資料庫 CodeIgniter 會幫你跳脫(escape)查詢, 你可以透過傳給它額外的第三個參數為 FALSE 來避免跳脫內容。

$this->db->having('user_id', 45);
// 產生: HAVING `user_id` = 45 in some databases such as MySQL
$this->db->having('user_id', 45, FALSE);
// 產生: HAVING user_id = 45

$this->db->or_having();

與 haveing() 相同, 但是使用 "OR" 來分隔多個子句。

$this->db->order_by();

讓你設定 ORDER BY 子句。第一個參數包含你要排序的欄位, 第二個參數則讓你指定排序的方向。可用的選項有 ascdescrandom

$this->db->order_by("title", "desc");

// 產生: ORDER BY title DESC

你也能傳入你自訂的字串當作第一個參數:

$this->db->order_by('title desc, name asc');

// 產生: ORDER BY title DESC, name ASC

如果你需要對多個欄位排序, 也可以多次呼叫這個函數。

$this->db->order_by("title", "desc");
$this->db->order_by("name", "asc");

// 產生: ORDER BY title DESC, name ASC

注意: order_by() 之前叫做 orderby(), 舊的函數名稱已經移除。

注意: 亂數排序(radom ordering) 目前在 Oracle 與 MSSQL 上面還沒有支援, 它們預設會改用 'ASC' 。

$this->db->limit();

讓你限制查詢要返回的列數:

$this->db->limit(10);

// 產生: LIMIT 10

第二個參數讓你設定結果的偏移。

$this->db->limit(10, 20);

// 產生: LIMIT 20, 10 (使用 MySQL 。其他資料庫有稍微不同的語法)

$this->db->count_all_results();

讓你可以判斷特定的 Active Record 查詢的結果列數。查詢可接受 Active Record 的限制條件, 像是 where()、or_where()、like()、or_like() 等。查詢範例:

echo $this->db->count_all_results('my_table');
// 產生整數結果, 像是 25

$this->db->like('title', 'match');
$this->db->from('my_table');
echo $this->db->count_all_results();
// 產生整數結果, 像是 17

$this->db->count_all();

讓你可以判斷特定資料表的列數。提供資料表名稱作為它的第一個參數。參考範例:

echo $this->db->count_all('my_table');

// 產生整數結果, 像是 25
 

新增(Inserting)資料

$this->db->insert();

根據你提供的資料產生一個 insert 字串, 然後執行查詢。你可以傳入一個 陣列 或是一個 物件 給函數。這是一個使用陣列的範例:

$data = array(
   'title' => 'My title' ,
   'name' => 'My Name' ,
   'date' => 'My date'
);

$this->db->insert('mytable', $data);

// 產生: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date')

第一個參數要包含資料表的名稱, 第二個參數是一個包含要存入值的關聯陣列。

這是一個使用物件的範例:

/*
    class Myclass {
        var $title = 'My Title';
        var $content = 'My Content';
        var $date = 'My Date';
    }
*/

$object = new Myclass;

$this->db->insert('mytable', $object);

// 產生: INSERT INTO mytable (title, content, date) VALUES ('My Title', 'My Content', 'My Date')

第一個參數會包含資料表名稱, 第二個參數是包含要存入值的物件。

注意:所有的值都會自動跳脫(escape)以產生較安全的語法。

$this->db->insert_batch();

根據你提供的資料產生一個 insert 字串, 然後執行新增。你可以傳入一個 陣列 或是一個 物件 給函數。這是一個使用陣列的範例:

$data = array(
   array(
      'title' => 'My title' ,
      'name' => 'My Name' ,
      'date' => 'My date'
   ),
   array(
      'title' => 'Another title' ,
      'name' => 'Another Name' ,
      'date' => 'Another date'
   )
);

$this->db->update_batch('mytable', $data);

// 產生: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date'), ('Another title', 'Another name', 'Another date')

第一個參數會包含資料表名稱,第二個參數是一個包含要存入值的關聯陣列。

注意: 所有的值都會自動跳脫(escape)以產生較安全的語法。

$this->db->set();

這個函數讓你能設定要 新增(insert) 或是 更新(update) 的值。

你也可以直接傳入一個資料陣列給新增(insert)或是更新(update)的函數:

$this->db->set('name', $name);
$this->db->insert('mytable');

// 產生: INSERT INTO mytable (name) VALUES ('{$name}')

如果你多次呼叫這個函數, 它會在新增或是更新時適當地組合:

$this->db->set('name', $name);
$this->db->set('title', $title);
$this->db->set('status', $status);
$this->db->insert('mytable');

set() 也可以接收額外的第三個參數 ($escape) , 如果你傳入 FALSE , 可以防止它跳脫你的資料。為了顯示這樣會有什麼不同, 以下是使用與不使用這個參數的例子:

$this->db->set('field', 'field+1', FALSE);
$this->db->insert('mytable');
// 產生: INSERT INTO mytable (field) VALUES (field+1)

$this->db->set('field', 'field+1');
$this->db->insert('mytable');
// 產生: INSERT INTO mytable (field) VALUES ('field+1')

你也可以傳入一個關聯陣列給這個函數:

$array = array('name' => $name, 'title' => $title, 'status' => $status);

$this->db->set($array);
$this->db->insert('mytable');

或是一個物件:

/*
    class Myclass {
        var $title = 'My Title';
        var $content = 'My Content';
        var $date = 'My Date';
    }
*/

$object = new Myclass;

$this->db->set($object);
$this->db->insert('mytable');
 

更新(Updating)資料

$this->db->update();

產生一個更新字串, 並根據你提供的資料來執行查詢。你可以傳一個 陣列(array) 或是一個 物件(object)給這個函數。這裡有一個使用陣列的例子:

$data = array(
               'title' => $title,
               'name' => $name,
               'date' => $date
            );

$this->db->where('id', $id);
$this->db->update('mytable', $data);

// 產生:
// UPDATE mytable
// SET title = '{$title}', name = '{$name}', date = '{$date}'
// WHERE id = $id

或是傳給它物件:

/*
    class Myclass {
        var $title = 'My Title';
        var $content = 'My Content';
        var $date = 'My Date';
    }
*/

$object = new Myclass;

$this->db->where('id', $id);
$this->db->update('mytable', $object);

// 產生
// UPDATE mytable
// SET title = '{$title}', name = '{$name}', date = '{$date}'
// WHERE id = $id

注意: 所有的值都會自動跳脫以產生較安全的查詢。

你要注意到 $this->db->where() 函數的使用, 它能讓你設定 WHERE 子句。你也可以直接用字串方式傳遞這個資訊給更新函數:

$this->db->update('mytable', $data, "id = 4");

或是用一個陣列:

$this->db->update('mytable', $data, array('id' => $id));

你也可以用前面介紹過的 $this->db->set() 函數來進行更新。

 

刪除(Deleting)資料

$this->db->delete();

產生刪除的 SQL 字串並執行查詢。

$this->db->delete('mytable', array('id' => $id));

// 產生:
// DELETE FROM mytable
// WHERE id = $id

第一個參數是資料表名稱。第二個參數是 where 子句。你也可以使用 where() 或是 or_where() 函數, 而不是用第二個參數傳資料給它:

$this->db->where('id', $id);
$this->db->delete('mytable');

// 產生:
// DELETE FROM mytable
// WHERE id = $id

如果你想刪除不只一個資料表的資料, 你也可以傳遞資料表名稱的陣列給 delete() 。

$tables = array('table1', 'table2', 'table3');
$this->db->where('id', '5');
$this->db->delete($tables);

如果你要刪除一個資料表中的所有資料, 你可以使用 truncate() 函數或是 empty_table()

$this->db->empty_table();

產生一個刪除(delete)的 SQL 字串並且執行查詢。 $this->db->empty_table('mytable');

// 產生:
// DELETE FROM mytable

$this->db->truncate();

產生一個刪除資料表(truncate)的 SQL 字串並且執行查詢。

$this->db->from('mytable');
$this->db->truncate();
// or
$this->db->truncate('mytable');

// 產生:
// TRUNCATE mytable

注意: 如果 TRUNCATE 命令無法使用, truncate() 會執行 "DELETE FROM table" 。

 方法串接

方法串接可以利用連接多個函數來讓你你的語法更為簡化。考慮一下這個參考範例:

$this->db->select('title')->from('mytable')->where('id', $id)->limit(10, 20);

$query = $this->db->get();

注意: 方法串接只有在 PHP 5 以上才能使用。

 

 Active Record 快取

雖然不是"真"的快取, Active Record 讓你能儲存(或是"快取")查詢的特定部份讓接下來的程式可以重複使用。正常狀況下, 當 Active Record 呼叫執行完畢時, 所有的資訊都會為了下一次呼叫而重置。使用快取, 你可以避免這個重置, 讓資訊可以簡單地重複使用。

快取的呼叫是會累積的。如果你做了兩次快取的 select() 呼叫然後兩次非快取的 select() 呼叫, 結果會是四次 select() 呼叫。

$this->db->start_cache()

這個函數必須在快取前呼叫。所有類型正確的的 Active Record 查詢都會被儲存起來以備使用。

$this->db->stop_cache()

呼叫這個函數可以停止快取。

$this->db->flush_cache()

這個函數可以刪除所有 Active Record 快取中的資料。

這是參考範例:

$this->db->start_cache();
$this->db->select('field1');
$this->db->stop_cache();

$this->db->get('tablename');

//產生: SELECT `field1` FROM (`tablename`)

$this->db->select('field2');
$this->db->get('tablename');

//產生: SELECT `field1`, `field2` FROM (`tablename`)

$this->db->flush_cache();

$this->db->select('field2');
$this->db->get('tablename');

//產生: SELECT `field2` FROM (`tablename`)

注意:以下的敘述可以被快取:select、from、join、join、where、like、group by、having、order by、set 。

 

源:http://www.codeigniter.org.tw/user_guide/database/active_record.html

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 惡魔php獵人 的頭像
    惡魔php獵人

    惡魔php獵人的部落格

    惡魔php獵人 發表在 痞客邦 留言(0) 人氣()