## SQL支持及關聯實現
本章將介紹sp框架數據SQL操作的使用方法,以及關聯查詢。
### 一、SQL查詢方法 query()
**用法:** query($sql, $params = array())
**參數:**
- $sql參數是需要查詢的SQL語句,SQL中輸入參數值需要用類似“:foo”、“:bar”的綁定標識來代替。
- $params是參數綁定值列表,鍵是類似“:foo”、“:bar”的綁定標識,值是輸入數據。
**返回值**
query()返回查詢結果的二維數組,跟findAll()結果一樣。
**舉例:**
子查詢
$obj->query(
"select tbl_student.* from tbl_student, (select student_id from tbl_score where examdate = ':examdate') sc where sc.student_id = tbl_student.student_id group by tbl_student.student_id",
array(
":examdate" => "2010-10-12"
)
);
UNION聯合查詢
$obj->query(
"(SELECT a FROM t1 WHERE a=:v1 AND B=:v2 ORDER BY a LIMIT 10) UNION (SELECT a FROM t2 WHERE a=:v3 AND B=:v4 ORDER BY a LIMIT 10)",
array(
":v1" => 10,
":v2" => 2,
":v3" => 20,
":v4" => 3,
)
);
JOIN連接查詢
$obj->query("SELECT t1.id,t2.id,t3.id FROM t1,( t2 LEFT JOIN t3 ON (t3.id=t1.id) ) WHERE t1.id=t2.id");
> 對比舊版的findSql()來說,新版的query()最大的不同是通過綁定參數來輸入數據的,更加安全。
### 二、SQL操作方法 execute()
**用法:** execute($sql, $params = array())
**參數:**
- $sql參數是需要查詢的SQL語句,SQL中輸入參數值需要用類似“:foo”、“:bar”的綁定標識來代替。
- $params是參數綁定值列表,鍵是類似“:foo”、“:bar”的綁定標識,值是輸入數據。
請注意query()和execute()方法之間的區別:query()是SQL語句查找時使用的,而execute()是SQL語句更新/刪除/新建的時候使用的。
> 通俗點說,query()中的SQL語句主要以“SELECT”為開頭,而execute()中的SQL語句以“UPDATE/DELETE/CREATE”開頭。
> 而且兩者的返回值是最大的不同。
**返回值**
execute()返回影響行數,跟update()/delete()方法結果一樣。
**舉例**
增刪改create,update,delete
$obj->execute("INSERT INTO table_name (col1, col2) VALUES(:col1, col1*2)", array(
":col1" => 15,
));
$obj->execute("UPDATE table_name SET col1=:col1, col2 = col1*2 WHERE col3 > :col3", array(
":col1" => 100,
":col3" => 100,
));
$obj->execute("DELETE table_name where col1 > :col1 AND col2 < :col2", array(
":col1" => 30,
":col2" => 50,
));
建表,改變表
$obj->execute("CREATE TABLE tbl_topic(tid int NOT NULL AUTO_INCREMENT,topic VARCHAR(200) NOT NULL,clicks BIGINT NOT NULL DEFAULT 0,PRIMARY KEY (tid)) DEFAULT CHARSET utf8");
$obj->execute("ALTER TABLE t1 RENAME t2");
其他操作
$obj->execute("REPLACE INTO mysql.user (Host,User,Password) VALUES('%', :username,PASSWORD(:password)) ", array(
":username" => "jake",
":password" => "123456"
));
### 三、事務支持
支持SQL就能支持數據庫事務,當然數據庫類型需要是innoDB。
$g = new Model("lib_guestbook");
// 開啟事務
$g->execute("START TRANSACTION"); // 或者是$g->execute("BEGIN");
// 這里是很多的插入或修改操作等,一般來說查詢不需要用事務的。
$result1 = $g->create(xxx);
$result2 = $g->update(xxx);
...
// 這里判斷操作是否成功,然后回滾或提交事務
if( false == $result1 || false == $result2 || ... ){ // create、update之類的返回false即是操作失敗,也有可能是字段錯誤
$g->execute("ROLLBACK"); // 出現問題,事務回滾
}else{
$g->execute("COMMIT"); // 沒有問題,那么事務提交。
}
以上就是事務的實現,不過一般情況下不需要使用到這些,只有在大并發或數據庫管理的時候才需要用到,請謹慎。
> 開發者可以自行覆蓋Model的方法來對事務進行封裝,因為Model本身的絕大部分函數,對數據庫的操作都是一條SQL的,所以對事務的封裝沒有很大的必要。
> 如果應用程序內,Model的派生類內,有比較復雜的數據處理,那么將這個處理和事務封裝到覆蓋的方法里,這是更輕便的OOP做法。
### 四、數據關聯查詢
跟舊版框架不一樣的地方是,新版sp框架提倡數據庫關聯直接通過SQL來進行查詢,新版代碼也沒有對關聯進行封裝。
理由:
- 封裝關聯操作,是通過所謂的ORM方式封裝一些很古怪的函數和方法來實現。但是這樣學習成本非常高。
- 封裝關聯后,不利于更細致的操作。
- 封裝關聯后,不能直觀地看出查詢的條件。在理解代碼上存在比較大的困難。
- 封裝關聯性能方面會比較差,相對直接用SQL的話。
所以:
- 使用query()方法,直接使用SQL語句進行關聯查詢。
- 關聯查詢一般只是SQL的join語法,很容易理解,直接把代碼功能寫出來,也很直觀。
- SQL語句是比較基礎的web開發知識,普通開發者不用再學習一門ORM封裝語言。
- 執行效率非常高。
> 其實換句話來說,SQL語句并非復雜到不敢面對的事情,過度把它封裝起來是不是很多舊余。
- 自述
- 一、入門教程
- 1. 開始使用SpeedPHP
- 2. Hello World
- 3. 理解MVC
- 4. 制作留言本
- 5. 數據操作及Ajax
- 二、框架概述
- 1. 特色
- 2. 版權及開源協議
- 3. 開發環境
- 4. 編碼版本
- 5. SAE平臺使用
- 三、開發指南
- 1. 開發流程
- 2. 架構及擴展
- 3. 程序目錄結構
- 4. 命名建議
- 5. 安全建議
- 6. 用戶自定義
- 7. 模塊modules
- 四、訪問交互
- 1. 表單提交及數據獲取
- 2. session/cookie的使用
- 3. 偽靜態及URL跳轉
- 4. 使用frameset
- 5. 模板引擎特性和使用方法
- 五、數據操作
- 1. 建立數據模型類
- 2. 數據操作教程
- 3. 分頁
- 4. SQL支持及關聯實現
- 5. 多數據庫、主從庫配置