Yii2 查询构建器 QueryBuilder
查询构造器 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