使用Query Builder
关于Query Builder
查询构建器调用的方法CDbConnection::createCommand()
, 可以先通过以下代码得到:
/**
* @var $db CDbConnection
*/
$db = Yii::app()->db;
/**
* @var $command CDbCommand
*/
$command = $db->createCommand();
查询构建器的获取结果有以下几种方法
query
: 返回一个CDbDataReader
对象, 需要自己去获取结果queryAll
: 返回一个包含所有结果的二维数组, 如果没有查询到数据,返回一个空数组queryRow
: 返回一个包含所有结果的一维数组, 如果没有查询到数据,返回falsequeryScalar
返回第一行第一列的值, 如果没有查询到数据, 返回falsequeryColumn
返回包含第一列的一维数组。如果没有查询到数据,则为空数组。execute
执行语句, 无结果,返回受影响的行数, 有异常则抛出异常
使用自定义的sql
// 方法1
$result = Yii::app()->db->createCommand('select * from tbl_user')->queryAll();
// 方法2, 使用参数绑定
$command->text = 'select * from tbl_user where id = :id';
$result = $command->queryAll(true, [':id' => 5]);
// 方法3
$result = $command->setText('select * from tbl_user')->queryAll();
使用构建器
使用select()方法
echo $command->select('id, name')->getText();
// SELECT `id`, `name`
echo $command->select("id, name, FROM_UNIXTIME(created_at, '%Y-%m-%d') as create_time")->getText(); // 使用mysql表达式
// SELECT id, name, FROM_UNIXTIME(created_at, '%Y-%m-%d') as create_time
// 使用数组
echo $command->select(['id, name'])->getText();
// SELECT `id`, `name`
echo $command->select(['id', 'name username', 'count(*) as count'])->getText();
// SELECT `id`, `name` AS `username`, count(*) as count
// 此处使用数组时, 如果元素包含`()`括号, 则不会被转义, 如果不包含括号, 但是包含空格, 会被`as`替换
使用selectDistinct()方法
echo $command->selectDistinct(['id', 'name'])->getText();
// SELECT DISTINCT `id`, `name`
echo $command->selectDistinct('id, name, now() now_time')->getText();
SELECT DISTINCT id, name, now() now_time
使用from()方法
echo $command->from('tbl_user')->getText();
// SELECT * FROM `tbl_user`
echo $command->from('{{user}}')->getText(); // 使用表前缀, 需要先配置`db.tablePrefix`
// SELECT * FROM `tbl_user`
echo $command->from('{{user}} u')->getText();// 使用别名
// SELECT * FROM `tbl_user` `u`
echo $command->from('{{user}} u, {{user_profile}} p')->getText(); // 多张表
// SELECT * FROM `tbl_user` `u`, `tbl_user_profile` `p`
echo $command->from('tbl_user, (select * from tbl_user_profile) p')->getText(); // 使用子查询
// SELECT * FROM tbl_user, (select * from tbl_user_profile) p
// 使用数组
echo $command->from(['tbl_user u'])->getText(); // 使用别名
// SELECT * FROM `tbl_user` `u`
echo $command->from(['tbl_user u', '(select * from {{user_profile}}) p'])->getText(); // 使用子查询
//SELECT * FROM `tbl_user` `u`, (select * from tbl_user_profile) p
使用where()方法
where方法有两个参数, 第一个是条件
, 第二个是绑定参数
, 如果第一个参数中使用了占位符
, 则可以在第二个参数中绑定参数, 如果不在第二个参数中绑定参数, 也可以单独调用 bindValues()
或者bindParam()
这两个方法来绑定
where
的第1个参数可以为字符串或者数组, 说明如下:
字符串: 当为字符串时, 直接写条件就可以了,如: id=1 and username=:username
数组: 当为数组时, 为以下格式
array(操作符, 操作数1, 操作数2, ... )
其中, 操作符可以是以下几种之一, 操作数可以是数组也可以是字符串, 当为数组时, 规则与此相同:
and
:操作数应该连接在一起使用AND
。例如,array('and', 'id=1', 'id=2')
将生成id=1 AND id=2
。如果操作数是一个数组,它将使用此处描述的相同规则转换为字符串。例如,array('and', 'type=1', array('or', 'id=1', 'id=2'))
将生成type=1 AND (id=1 OR id=2)
。该方法不会进行任何引用或转义。or
:与and
运算符类似,只是操作数使用OR
连接。in
:操作数1应该是列或DB表达式,操作数2是一个数组,表示列或DB表达式应该在的值的范围。例如,array('in', 'id', array(1,2,3))
将生成id IN (1,2,3)
。该方法将正确引用范围中的列名和转义值。not in
:与in
运算符类似,但在生成的条件中IN
替换为运算符NOT IN
。like
:操作数1应该是列或DB表达式,操作数2是字符串或表示列或DB表达式应该类似的值范围的数组。例如,array('like', 'name', '%tester%')
将生成name LIKE '%tester%'
。当值范围作为数组给出时,LIKE将生成多个谓词并使用连接AND。例如,array('like', 'name', array('%test%', '%sample%'))
将生成name LIKE '%test%' AND name LIKE '%sample%'
。该方法将正确引用范围中的列名和转义值。not like
:与like
运算符类似,但在生成的条件中LIKE替换为运算符NOT LIKE
。or like
:类似于like
运算符,除了OR
用于连接多个LIKE
谓词。or not like
:类似于not like
运算符,除了OR
用于连接多个NOT LIKE
谓词。
使用示例
echo $command->where('id=1 or id=2')->getText();
// SELECT * WHERE id=1 or id=2
echo $command->where('id=:id1 and id=:id2', [':id1' => 1, ':id2' => 2])->getText(); // 使用参数绑定
// SELECT * WHERE id=1 AND id=2
echo $command->where('id BETWEEN :startId AND :endId', [':startId' => 1, ':endId' => 10])->getText(); // 使用 BETWEEN
// SELECT * WHERE id BETWEEN 1 AND 10
echo $command->where(['and', 'id=1', ['or', 'id=3', 'id=4']])->getText(); // 使用 and
// SELECT * WHERE (id=1) AND ((id=3) OR (id=4))
echo $command->where(['in', 'id', [1, 2, 3, 4]])->getText(); // 使用 in
// SELECT * WHERE `id` IN (1, 2, 3, 4)
echo $command->where(['like', 'name', '%zhang'])->getText(); // 使用like
// SELECT * WHERE `name` LIKE '%zhang'
echo $command->where(['like', 'name', ['%zhang', 'wang']])->getText(); // 使用like
// SELECT * WHERE `name` LIKE '%zhang' AND `name` LIKE 'wang'
echo $command->where(['or not like', 'name', ['%zhang', '%wang%']])->getText(); // or not like
// SELECT * WHERE `name` NOT LIKE '%zhang' OR `name` NOT LIKE '%wang%'
使用andWhere()
该方法是用来追加查询条件的, 他的使用方法和 where()
一样
public function andWhere($conditions, $params = array());
使用orWhere()
该方法是用来追加查询条件的, 不同的是追加的条件为or
, 他的使用方法和 where()
一样
public function orWhere($conditions, $params = array());
使用order()
order方法指定ORDER BY查询的一部分
echo $command->order('id, name')->getText();
// SELECT * ORDER BY `id`, `name`
echo $command->order('id, name desc')->getText();
// SELECT * ORDER BY `id`, `name` DESC
echo $command->order(['tbl_user.name desc', 'id asc'])->getText();
// SELECT * ORDER BY `tbl_user`.`name` DESC, `id` ASC
limit() and offset()
其中limit有两个参数, 第一个为limit
, 第二个为offset
可以通过再次调用offset()
方法来覆盖
echo $command->limit(1)->getText();
// SELECT * LIMIT 1
echo $command->limit(1, 5)->getText();
// SELECT * LIMIT 1 OFFSET 5
echo $command->limit(1, 5)->offset(10)->getText();
// SELECT * LIMIT 1 OFFSET 10
join() 及 leftjoin(), rightjoin(), crossJoin(), naturalJoin()
- function join($table, $conditions, $params = array())
- function leftJoin($table, $conditions, $params = array())
- function rightJoin($table, $conditions, $params = array())
- function crossJoin($table)
- function naturalJoin($table)
其中,
$table
为表名,$conditions
为连接条件,$params
为绑定参数
echo $command->from('tbl_user u')->join('tbl_user_profile p', 'u.id=p.id and u.id=10')->getText();
// SELECT * FROM `tbl_user` `u` JOIN `tbl_user_profile` `p` ON u.id=p.id and u.id=10
echo $command->from('tbl_user u')->leftJoin('tbl_user_profile p', 'u.id=p.id and u.id=:id', [':id' => 10])->getText();
// SELECT *FROM `tbl_user` `u`LEFT JOIN `tbl_user_profile` `p` ON u.id=p.id and u.id=:id. Bound with:id=10
group()
echo $command->from('tbl_user')->group('tbl_user.id, name')->getText(); // 简单使用
// SELECT * FROM `tbl_user` GROUP BY `tbl_user`.`id`, `name`
echo $command->from('tbl_user')->group(['tbl_user.id', 'name'])->getText();
// SELECT * FROM `tbl_user` GROUP BY `tbl_user`.`id`, `name`
having()
having()
方法指定查询的HAVING部分。
它的用法与where()
相同。
union()
union()
方法指定查询的UNION部分。
它使用UNION运算符将$ sql附加到现有SQL。
多次调用union()
会将多个SQL附加到现有SQL。
echo $command->from('tbl_user')->group(['tbl_user.id', 'name'])->union($command1->select('id')->getText())->getText();
// SELECT * FROM `tbl_user` GROUP BY `tbl_user`.`id`, `name` UNION ( SELECT `id`)
快速构建查询
调用 CDbConnection :: createCommand()
时, 可以传一个数组作为参数, 数组的键
就是上述的方法, 将用于初始化创建的CDbCommand实例的属性。这意味着,我们可以使用以下代码来构建查询:
$command = Yii::app()->db->createCommand([
'select' => 'id, username',
'from' => 'tbl_user',
'limit' => 5,
'offset' => 0,
'where' => [
'and',
'id=:id1',
[
'like',
'username',
'%zhang%'
]
],
'order' => ['id desc'],
'params' => [
':id1' => 1,
],
]);
echo $command->getText();
// SELECT `id`, `username` FROM `tbl_user` WHERE (id=:id1) AND (`username` LIKE '%zhang%') ORDER BY `id` DESC LIMIT 5
多次构建查询
一个CDbCommand实例可以多次重复使用,以建立多个查询。但是,在构建新查询之前,必须调用CDbCommand :: reset()方法来清理以前的查询。例如:
$command = Yii::app()->db->createCommand();
$users = $command->select('*')->from('tbl_users')->queryAll();
$command->reset(); // clean up the previous query
$posts = $command->select('*')->from('tbl_posts')->queryAll();
插入数据, insert()
insert
方法有两个参数, 第一个为要插入的表, 第二个参数为数据(name=>value
), 返回受影响的行数
function insert($table, $columns);
// build and execute the following SQL:
// INSERT INTO `tbl_user` (`username`, `password`, `email`,`count`) VALUES (:username, :password, :email, count+:num). Bound with:username='Tester', :password='', :email='tester@example.com',:num=5
// 可以使用表前缀写法
$command->insert('{{user}}', array(
'username' => 'Tester',
'password' => '',
'email' => 'tester@example.com',
// 可以使用mysql表达式
'count' => new CDbExpression('count+:num', [':num' => 5]),
));
批量更新数据, update()
update
方法有4个参数,
- 第一个为要更新的表,
- 第二个参数为更新的数据(
name=>value
), - 第三个参数为更新条件, 写法和 查询构建器的
where()
一样 - 第四个参数是绑定参数
function update($table, $columns, $conditions='', $params=array())
// build and execute the following SQL:
// UPDATE `tbl_user` SET `username`=:username, `count`=count +:num WHERE (id=:id). Bound with :id=1, :username='new username', :num=3
$command->update('tbl_user', [
'username' => 'new username',
'count' => new CDbExpression('count + :num', [':num' => 3]),
], ['and', 'id=:id'], [':id' => 1]);
批量删除数据, delete()
delete
方法有3个参数,
- 第一个为要更新的表,
- 第二个参数为更新条件, 写法和 查询构建器的
where()
一样 - 第三个参数是绑定参数
function delete($table, $conditions='', $params=array())
// build and execute the following SQL:
// DELETE FROM `tbl_user` WHERE (id=:id). Bound with :id=3
$command->delete('tbl_user', ['and', 'id=:id'], [':id' => 3]);