查詢構造器 QueryBuilder
1、什么是查詢構建器
- 查詢構建器也是建立在 DAO 基礎之上,可讓你創建程序化的、DBMS 無關的 sql 語句,並且這樣創建的 sql 語句比原生的
- sql 語句更易讀、更安全。
$rows = (new yii\db\Query()) // 以下為構建查詢
->select(['id','email']) // 查詢的字段 ->from('user') ->where(['last_name' => 'Carroll]) ->orderBy(id) ->limit(10) ->indexBy(id) // 將 id 作為數組的鍵 ->all(); // 這就是執行查詢
2、使用查詢構建器的步驟
a、構建查詢。創建一個 yii\db\Query 對象來代表一條 SELECT SQL 語句,然后通過調用一套可以串起來的方法,
比如 select 方法,from 方法,where 方法等這些方法,構建出可以滿足一定要求的查詢條件。
(1)select() 方法, 使用字符串或者一個數組來指定需要查詢的字段
$query -> select('id,email'); // 字符串形式
$query -> select(['id','email']) // 數組形式
$query -> select('user.id AS user_id, email') // 還可以是設定字段的別名形式
$query -> select(["CONTACT(first_name,' ',last_name) AS full_name",'email']) //支持 SQL 的表達式
(2) 子查詢 。
SELECT id,(SELECT COUNT() FROM user) AS count FROM post //子查詢方法為: $subQuery = (new Query()) -> select('COUNT()') -> from('user'); $query = (new Query()) -> select(['id','count' => $subQuery] -> from('post');
(3)可以調用 yii\db\Query::addSelect() 方法來選取附加字段
$query -> select(['id','username']) -> addSelect(['email']); // 如果程序需要執行到某個判斷之后才能決定是否需要更多的查詢字段,此時使用 addSelect()
(4) 若沒有寫 select() 方法,就相當於 select()
b、 from() 方法
(1)from 方法指定了 SQL 語句當中的 FROM 子句。
SELECT FROM user $query -> from('user');
(2)from 中的表名可包含數據庫前綴,以及表別名。
$query -> from(['public.user u',public.post p]); // 包含數據庫前綴, 數組形式
$query -> from('public.user u,public.post p'); // 包含數據庫前綴, 字符串形式
(3)可以使用子查詢的結果作為表名
SELECT FROM (SELECT id FROM user WHERE status=1) u // 子查詢方法為:
$subQuery = (new Query()) -> select('id') -> from('user') -> where('status=1'); $query = (new Query()) -> from(['u'=>$subQuery]);
c、where() 方法
- 字符串格式 'status=1'
- 鍵值對數組格式 ['status' => 1,'type'=>2]
- 操作符格式 ['like','name','test']
d、要注意 sql 安全問題:
$query -> where('status=$status'); // 一定要寫成:
$query -> where('status=:status)-> addParams([':status'=>$status]);
e、orderBy() 方法
(1) 數組形式:
$query -> orderBy([ 'id' => SORT_ASC, // 升序
'name' => SORT_DESC, // 降序
])
(2)字符串形式
$query -> orderBy('id ASC,name DESC');
(3)limit() 和 offset() 方法,用來指定 SQL 語句當中的 LIMIT 和 OFFSET 子句的。
// ...... limit 10 offset 20
$query -> limit(10) -> offset(20)
(4)groupBy()
// .....groupBy(['id','status']);
$query -> groupBy(['id','status']);
可以調用 addGroupBy()來為 groupBy子句添加額外的字段
$query -> addGroupBy('age')
(5) having()
// ...... HAVING status = 1 $query -> having(['status' => 1]);
可以調用 andHaving() 或 orHaving() 方法來為 HAVING 子句追加額外的條件
// HAVING(status = 1) AND (age > 30) $query -> having(['status' => 1]) -> andHaving(['>','age',30);
(6) join()
// ..... LEFT JOIN post ON post.user_id = user.id
$query -> join('LEFT JOIN','post','post.user_id = user.id'); // 依次為:關聯類型,關聯的表名,關聯條件,后面還可以接可選參數 $params [與連接條件綁定的參數]
(7)union(),用來指定 SQL 語句當中的 UNION 子句的
$query1 = (new yii\db\query()) ->select('id, category_id AS type,name') ->from('post') ->limit(10); $query2 = (new yii\db\query()) ->select('id, type,name') ->from('user') ->limit(10); $query1 -> union($query2);
(8) indexBy 索引查詢結果
當在調用 all() 方法時,它將返回一個以連續的整數值為索引的數組。而有時候希望使用一個特定的字段或者表達式的值
來作為索引結果集數組,那么在調用 yii\db\Query::all() 之前使用 yii\db\Query::indexBy() 方法來達到這個目的。
3、執行查詢。執行 yii\db\Query 的一個查詢方法從數據庫當中檢索數據。比如 all(),one(),column()等這些查詢方法。
yii\db\Query 提供了一套用於不同查詢目的的方法:
- all() ----------- 返回一個由行組成的數組,每一行是一個由名稱和值構成的關聯數組
- one() ----------- 返回結果集的第一行
- column() ----------- 返回結果集的第一列
- scalar() ----------- 返回結果集的第一行第一列的標量值
- exists() ----------- 返回一個表示該查詢是否包含結果集的值
- count() ----------- 返回 COUNT 查詢的結果
- sum() ----------- 返回指定列的和值
- average() ----------- 返回指定列的平均值
- max() ----------- 返回指定列的最大值
- min() ----------- 返回指定列的最小值
4、數據庫查詢總結
查詢方式 | 構建查詢 | 返回值(all, one 方法) |
Command 對象 | SQL 語句 | 數組 |
AR 的 findBySql 方法 | SQL 語句 | 對象 |
Query 對象 | 查詢構建器 | 數組 |
1、可程序化構建 | ||
2、DBMS無關 | ||
3、易讀 | ||
4、更安全 | ||
AR 的 find 方法 | 查詢構建器 | 對象 |
1、可程序化構建 | ||
2、DBMS無關 | ||
3、易讀 | ||
4、更安全 |
動態設置數據庫連接
在controller的beforeAction里面,重新設置db組件。
/** * @Purpose : 動態設置數據庫連接 */
public function beforeAction($action) { if(parent::beforeAction($action)){ \Yii::$app->set('db', [ 'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=' . $dbHost . ';dbname=' . $dbName,
'enableSchemaCache' => YII_DEBUG ? false : true,
'username' => $dbUser,
'password' => $dbPassword,
'charset' => 'utf8',
'emulatePrepare' => true,
'tablePrefix' => 'xx_', ]); return true; } return false; }
注:本文為作者(44106-kangaroo) 看完魏羲教你學Yii2.0 視頻后所記,如有轉載請注明出處:http://www.cnblogs.com/chrdai/p/8006695.html