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), 以產生更安全的查詢。
- 簡單的 鍵/值 方法:
$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' - 自訂的 鍵/值 方法:
你可以在第一個參數包含一個運算子來控制比較的方法:
$this->db->where('name !=', $name);
$this->db->where('id <', $id);
// 產生: WHERE name != 'Joe' AND id < 45 - 關聯陣列方法:
$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); - 自訂字串:
你可以手動撰寫你要的子句:
$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)。
- 簡單的 鍵/值 方法:
$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');
如果你想要控制萬用字元 (%)出現的位置, 你可以使用額外的第三個參數。可以使用的選項有 'before'、'after' 以及 'both' (這是預設值)。
$this->db->like('body', 'match');
// 產生: WHERE title LIKE '%match%' AND body LIKE '%match%$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%' - 關聯陣列方法:
$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 子句。第一個參數包含你要排序的欄位, 第二個參數則讓你指定排序的方向。可用的選項有 asc、desc 或 random 。
$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
留言列表