徐善通的随笔

千里之行, 始于足下



yii1.1查询构建器使用方法


使用Query Builder

关于Query Builder

查询构建器调用的方法CDbConnection::createCommand(), 可以先通过以下代码得到:

/**
 * @var $db CDbConnection
 */
$db = Yii::app()->db;

/**
 * @var $command CDbCommand
 */
$command = $db->createCommand();

查询构建器的获取结果有以下几种方法

  • query: 返回一个CDbDataReader对象, 需要自己去获取结果
  • queryAll: 返回一个包含所有结果的二维数组, 如果没有查询到数据,返回一个空数组
  • queryRow: 返回一个包含所有结果的一维数组, 如果没有查询到数据,返回false
  • queryScalar 返回第一行第一列的值, 如果没有查询到数据, 返回false
  • queryColumn 返回包含第一列的一维数组。如果没有查询到数据,则为空数组。
  • 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]);

作者: 徐善通
地址: https://www.xstnet.com/article-112.html
声明: 除非本文有注明出处,否则转载请注明本文地址


我有话说



最新回复


正在加载中....

Copyrights © 2016-2019 醉丶春风 , All rights reserved. 皖ICP备15015582号-1