<br>
<br>
The Yii framework's Query Builder provides an object-oriented way to write SQL statements, allowing developers to use class methods and properties to specify SQL statements. independent parts, and assemble these different parts into a SQL statement that can be executed by calling the DAO method as described in the previous section. The following shows a typical way to use Query Builder to build a SELECT SQL statement:
<br>
$user = Yii::app()->db->createCommand() ->select('id, username, profile') ->from('tbl_user u') ->join('tbl_profile p', 'u.id=p.user_id') ->where('id=:id', array(':id'=>$id)) ->queryRow();
When you need to assemble the chunked assembly It is best to use Query Builder when using SQL statements or special conditions based on applications. The biggest benefit of using Query Builder is:
You can build complex SQL statements.
Automatically quote table names and column names to avoid conflicts with SQL reserved words and special characters.
If possible, you can also use parameter values for parameter binding, which can reduce SQL injection attack.
Supports a certain degree of database abstraction, which can simplify database migration between different database platforms.
Use Query Builder It is not mandatory. In fact, if your query is very simple, it will be simpler and faster to use SQL statements directly.<br>Note: Query builder cannot modify existing queries that specify SQL statements, such as , the following code is invalid:
<br>
$command = Yii::app()->db->createCommand('SELECT * FROM tbl_user'); // the following line will NOT append WHERE clause to the above SQL $command->where('id=:id', array(':id'=>$id));
In other words, do not fix native SQL and SQL and query builder Use.
The Query Builder of Yii framework is supported in the form of CDbCommand. This database query class has been described in the DAO chapter.
Before using Query Builder, we must first create an instance of CDbCommand, as shown below,
<br>
$command = Yii::app()->db->createCommand();
That is to say We use Yii::app()->db
to obtain the DB connection, and then call CDbConnection::createCommand() to create the required command instance.
Note that we are not like In DAO, pass the entire SQL statement into the createCommand() method and call
without passing in any parameters. This is because we will use the Query Builder method to build an independent SQL statement. .
Data retrieval query uses SELECT statement. The query builder provides a series of methods to build independent SELECT statements. Because these methods return CDbCommand instances , so we can use method chaining, as shown at the beginning of our chapter.
select(): Specify the SELECT part of the query
selectDistinct(): Specify the SELECT part of the query and enable the DISTINCT identifier
from(): Specify the FROM part of the query
where(): Specify the WHERE part of the query
<br>
##function select($columns='*')
select() method specifies the
of the query SELECT part. $columns
The parameter specifies the column to be queried, which can be a comma-separated string or an array containing column names. The column name can include table prefixes and column aliases. This method automatically quotes the column name unless the column is a DB expression.Here is an example:
<br>
// SELECT * select() // SELECT `id`, `username` select('id, username') // SELECT `tbl_user`.`id`, `username` AS `name` select('tbl_user.id, username as name') // SELECT `id`, `username` select(array('id', 'username')) // SELECT `id`, count(*) as num select(array('id', 'count(*) as num'))
selectDistinct()
<br>##
function selectDistinct($columns)
DISTINCT
. For example,selectDistinct('id, username') will generate the following SQL:
SELECT DISTINCT `id`, `username`
from()
<br>
function from($tables)
##
// FROM `tbl_user` from('tbl_user') // FROM `tbl_user` `u`, `public`.`tbl_profile` `p` from('tbl_user u, public.tbl_profile p') // FROM `tbl_user`, `tbl_profile` from(array('tbl_user', 'tbl_profile')) // FROM `tbl_user`, (select * from tbl_profile) p from(array('tbl_user', '(select * from tbl_profile) p'))
where( )
function where($conditions, $params=array())
where() 方法指定了查询的 WHERE
部分. $conditions
指定查询的条件,$params
指定查询条件中的参数.e $conditions参数可能是一个字符串也可能是数组如下所示
:
<br>
array(operator, operand1, operand2, ...)
里面的 operator
可以下列所示的任意一个:
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
: 第一个操作数operand1应该是一个列名或者DB expression, 第二个操作数operand2是一个表示该列或DB expression所在范围的数组, array('in', 'id', array(1,2,3))
将会生成 id IN (1,2,3)
. 这个方法将会引用列名并转义取值范围中的值.
not in
: 和in
操作符类似,不同之处是在生成条件语句中将 IN
换成 NOT IN
.
like
: 操作符operand 1应该是一个列或者 DB expression, 操作符operand 2是一个表示与列或者DB expression相似的字符串或数组. 例如,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
操作符类似
or like
: 和 like
操作符类似,不同之处是多个LIKE之间使用 OR
连接.
or not like
: 和 not like
操作符类似.
下面是使用 where的一些示例
:
<br>
// WHERE id=1 or id=2 where('id=1 or id=2') // WHERE id=:id1 or id=:id2 where('id=:id1 or id=:id2', array(':id1'=>1, ':id2'=>2)) // WHERE id=1 OR id=2 where(array('or', 'id=1', 'id=2')) // WHERE id=1 AND (type=2 OR type=3) where(array('and', 'id=1', array('or', 'type=2', 'type=3'))) // WHERE `id` IN (1, 2) where(array('in', 'id', array(1, 2)) // WHERE `id` NOT IN (1, 2) where(array('not in', 'id', array(1,2))) // WHERE `name` LIKE '%Qiang%' where(array('like', 'name', '%Qiang%')) // WHERE `name` LIKE '%Qiang' AND `name` LIKE '%Xue' where(array('like', 'name', array('%Qiang', '%Xue'))) // WHERE `name` LIKE '%Qiang' OR `name` LIKE '%Xue' where(array('or like', 'name', array('%Qiang', '%Xue'))) // WHERE `name` NOT LIKE '%Qiang%' where(array('not like', 'name', '%Qiang%')) // WHERE `name` NOT LIKE '%Qiang%' OR `name` NOT LIKE '%Xue%' where(array('or not like', 'name', array('%Qiang%', '%Xue%')))
值得注意的是当操作符包含like的时候
,我们必须在patterns明确指定通配符字符串 (such as %
and _
). 如果 patterns 来自用户输入,我们还要使用下面的代码来转义特殊字符以避免被作为通配符处理:
<br>
$keyword=$_GET['q']; // escape % and _ characters $keyword=strtr($keyword, array('%'=>'\%', '_'=>'\_')); $command->where(array('like', 'title', '%'.$keyword.'%'));
<br>
function andWhere($conditions, $params=array())
addWhere() 方法通过AND操作符添加额外的条件到查询的WHERE部分,这个方法和行为和where()几乎一样,不同之处是它追加条件而不是替换.
<br>
function orWhere($conditions, $params=array())
orWhere() 方法通过OR操作符添加额外的条件到查询的WHERE部分, 这个方法和行为和where()几乎一样,不同之处是它追加条件而不是替换.
<br>
function order($columns)
order() 方法指定查询的 ORDER BY
部分. $columns
参数指定要排序的列, 可以是以逗号分隔的列和排序方向(ASC
or DESC
)字符串,或者包含列和排序方向的数组. 列名可能包含表前缀. 该方法会自动引用列名,除非该列名是一些插入语句 (如DB expression).
下面是一些示例:
<br>
// ORDER BY `name`, `id` DESC order('name, id desc') // ORDER BY `tbl_profile`.`name`, `id` DESC order(array('tbl_profile.name', 'id desc'))
<br>
function limit($limit, $offset=null) function offset($offset)
limit() 和 offset() 方法指定查询的 LIMIT
和 OFFSET
部分. 注意一些 DBMS 可能不支持 LIMIT
和 OFFSET
语法. 在这种情况下, Query Builder 将会重写整个 SQL 语句来模拟limit 和 offset的功能.
下面是一些示例:
<br>
// LIMIT 10 limit(10) // LIMIT 10 OFFSET 20 limit(10, 20) // OFFSET 20 offset(20)
<br>
function join($table, $conditions, $params=array()) function leftJoin($table, $conditions, $params=array()) function rightJoin($table, $conditions, $params=array()) function crossJoin($table) function naturalJoin($table)
join() 方法及其变种指定了使用 INNER JOIN
, LEFT OUTER JOIN
,RIGHT OUTER JOIN
, CROSS JOIN
, 或者 NATURAL JOIN联接其他表进行查询
. $table
参数指定了要联接的表名. 表名可以包含作用域前缀及别名. 这个方法将会引用表名(除非表名是DB expression或者子查询). $conditions参数指定了联接条件,
它的语法和where()类似. $params
指定了整个查询的参数绑定.
注意不同于其他 query builder 方法, 每一次调用 join 方法都会追加到前一个上去.
下面是一些示例:
<br>
// JOIN `tbl_profile` ON user_id=id join('tbl_profile', 'user_id=id') // LEFT JOIN `pub`.`tbl_profile` `p` ON p.user_id=id AND type=1 leftJoin('pub.tbl_profile p', 'p.user_id=id AND type=:type', array(':type'=>1))
<br>
function group($columns)
group() 方法指定查询的 GROUP BY
部分. $columns
参数指定分组的列, 可以是以逗号分隔的列字符串, 也可以是列数组。列名可能包含表前缀. 这个方法会自动引用列名,除非列是插入语句(which means the column is given as a DB expression).
下面是一些示例:
<br>
// GROUP BY `name`, `id` group('name, id') // GROUP BY `tbl_profile`.`name`, `id` group(array('tbl_profile.name', 'id'))
<br>
function having($conditions, $params=array())
having() 方法指定了查询的 HAVING
部分. 它的使用 where()类似.
下面是一些示例:
<br>
// HAVING id=1 or id=2 having('id=1 or id=2') // HAVING id=1 OR id=2 having(array('or', 'id=1', 'id=2'))
<br>
function union($sql)
union() 方法指定了查询的 UNION
部分. 它使用UNION操作符追加 $sql
到已存在的 SQL. 调用 union()
多次将会追加多个 SQLs 到已存在的SQL上.
下面是一些示例:
<br>
// UNION (select * from tbl_profile) union('select * from tbl_profile')
在调用上述的查询构建方法构建一个查询之后, 我们可以调用如上一章节DAO中所述的DAO方法来执行查询. 例如, 我们可以调用 CDbCommand::queryRow() 来获取一行的结果, 或者 CDbCommand::queryAll() 来一次获取所有结果. 例子:
<br>
$users = Yii::app()->db->createCommand() ->select('*') ->from('tbl_user') ->queryAll();
除了执行 Query Builder构建的查询之外, 我们还可以检索相应SQL语句的结果. 这可以通过调用 CDbCommand::getText()方法来解决.
<br>
$sql = Yii::app()->db->createCommand() ->select('*') ->from('tbl_user') ->text;
如果有多个参数绑定到一个查询上, 那么它们可以通过 CDbCommand::paramsproperty来获取结果.
有时候, 使用方法链来构建查询并不是一个明智的选择. Yii框架的 Query Builder允许一个查询使用简单对象属性赋值的方式来构建 . 特别地,对每一个查询构建方法,有一个同名的相应属性. 赋值到该属性等价于调用相应的方法. 例如,下面的两个语句是等价的($command
代表 CDbCommand 对象):
<br>
$command->select(array('id', 'username')); $command->select = array('id', 'username');
此外, CDbConnection::createCommand()方法可以传入一个数组参数. 数组中的键值对会被用来初始化已创建的CDbCommand实例的属性.这意味着,我们可以使用下面的代码来构建查询:
<br>
$row = Yii::app()->db->createCommand(array( 'select' => array('id', 'username'), 'from' => 'tbl_user', 'where' => 'id=:id', 'params' => array(':id'=>1), ))->queryRow();
一个DbCommand 实例可以被多次复用来构建多个查询. 在构建一个新的查询之前一定要调用 CDbCommand::reset() 方法来清除上一个查询. 例如:
<br>
$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();
数据操纵查询指的是SQL语句中数据库表格记录的插入、更新和删除. 与之相应的,查询构建器提供了insert,update和delete方法. 不同于 SELECT 查询方法,每一个数据操纵查询方法都会构建一个完整的SQL语句,并且立即执行.
insert(): 在数据表中插入一行
update(): 更新数据表数据
delete(): 从数据表删除数据
下面我们阐述数据操纵查询方法.
<br>
function insert($table, $columns)
insert() 方法构建并执行一个 INSERT
SQL 语句. $table参数指定要插入的数据表
, $columns是一个键值对数组,指定了插入的列及对应的值
. 这个方法会引用表名并且使用绑定参数.
Below is an example:
<br>
// build and execute the following SQL: // INSERT INTO `tbl_user` (`name`, `email`) VALUES (:name, :email) $command->insert('tbl_user', array( 'name'=>'Tester', 'email'=>'tester@example.com', ));
<br>
function update($table, $columns, $conditions='', $params=array())
update() 方法构建并执行一个UPDATE
SQL语句. $table参数指定要更新的表
; $columns是一个键值对数组,该数组指定了要更新的列及其对应的值
;$conditions
和 $params
和 where()中的类似, 指定了UPDATE语句中的 WHERE部分
. 这个方法会自动引用相应的列名并且使用参数绑定.
Below is an example:
<br>
// build and execute the following SQL: // UPDATE `tbl_user` SET `name`=:name WHERE id=:id $command->update('tbl_user', array( 'name'=>'Tester', ), 'id=:id', array(':id'=>1));
<br>
function delete($table, $conditions='', $params=array())
delete() 方法构建并执行一个DELETE
SQL语句. $table参数指定要删除的表
; $conditions
和 $params
和 where()中的类似, 指定了DELETE语句中的 WHERE部分
. 这个方法会自动引用相应的列名.
下面是示例:
<br>
// build and execute the following SQL: // DELETE FROM `tbl_user` WHERE id=:id $command->delete('tbl_user', 'id=:id', array(':id'=>1));
除了正常的数据取回和操纵查询, query builder 还提供了一系列的方法来构建和执行操作数据库层面的SQL操作. 特殊地,它支持下列查询:
createTable(): 创建表
renameTable(): 重命名表
dropTable(): 删除表
truncateTable(): 清空表
addColumn(): 新增表的列
renameColumn(): 重命名表的列
alterColumn(): 修改表的列
addForeignKey(): 添加外键(版本1.1.6起生效)
dropForeignKey(): 删除外键 (版本1.1.6起生效)
dropColumn(): 删除表列
createIndex(): 创建索引
dropIndex(): 删除索引
Info: 尽管实际的SQL语句在不同的DBMS中操作数据库的方法不尽相同,但是查询构建器试图提供一个统一接口来构建查询。这极大简化了数据库迁移时带来的麻烦。
query builder 介绍了一系列抽象数据类型用来定义数据表的列. 不同于物理数据类型用来指定特殊的DBMS而且在不同的DBMS中不一样,这里的抽象数据类型独立于DBMS. 当抽象数据类型用于定义表的列时,查询构建器将会将其转化为相应的物理数据类型.
下面的抽象数据类型都被 query builder 所支持.
pk
: 一个通用的主键类型, 在MySQL中将会被转化为 int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY
;
string
: 字符串类型, 在MySQL中将会被转化为 varchar(255)
;
text
: 文本类型 (长字符串), 在MySQL中将会被抓化为 text
;
integer
: 整型, 在MySQL中将会被转化为 int(11)
;
float
: 浮点数类型, 在MySQL中将会被转化为will be converted into float
;
decimal
: 小数类型, 在MySQL中将会被转化为 decimal
;
datetime
: 日期时间类型, 在MySQL中将会被转化为 datetime
;
timestamp
: 时间戳类型,在MySQL中将会被转化为 timestamp
;
time
: 时间类型, 在MySQL中将会被转化为 time
;
date
: 日期类型, 在MySQL中将会被转化为 date
;
binary
: 二进制数据类型, 在MySQL中将会被转化为 blob
;
boolean
: 布尔类型, 在MySQL中将会被转化为tinyint(1)
;
money
: 金钱/货币类型, 在MySQL中将会被转化为 decimal(19,4)
. 这个类型从Yii版本1.1.8起生效.
<br>
function createTable($table, $columns, $options=null)
createTable() 方法构建和执行创建数据表的 SQL语句. $table参数指定了要创建的表名
. $columns
参数指定了新表中的列. 它们必须定义为 name-definition 对 (e.g. 'username'=>'string'
). $options
参数指定任意额外的应该追加到已生成的SQL语句的SQL 片段 . query builder 将会引用表名和合适的列名.
当指定一个列定义时,可以使用上述所叙的抽象数据类型. query builder 会基于当前使用的DBMS转化抽象数据类型为相应的物理数据类型。<br>
一个列定可以包含非抽象数据类型或者指定. 它们将会毫无改变的生成 SQL 语句。例如, point
不是一个抽象数据类型, 如果用在了列定义中, 它将会出现在结果SQL语句中,同时string NOT NULL
将会转化为 varchar(255) NOT NULL
.
下面的例子展示了如何创建新表:
<br>
// CREATE TABLE `tbl_user` ( // `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, // `username` varchar(255) NOT NULL, // `location` point // ) ENGINE=InnoDB createTable('tbl_user', array( 'id' => 'pk', 'username' => 'string NOT NULL', 'location' => 'point', ), 'ENGINE=InnoDB')
<br>
function renameTable($table, $newName)
renameTable() 方法构建并执行重命名表的SQL语句. $table参数指定了要重命名的表,
$newName参数指定了表的新名称
. 查询构建器将会引用合适的表名.
下面的示例展示了如何重命名一个表:
<br>
// RENAME TABLE `tbl_users` TO `tbl_user` renameTable('tbl_users', 'tbl_user')
<br>
function dropTable($table)
dropTable() 方法构建并执行删除表的SQL语句. $table
参数指定要删除的表名. query builder将会引用合适的表名.
下面是展示如何删除表的示例:
<br>
// DROP TABLE `tbl_user` dropTable('tbl_user')
<br>
function truncateTable($table)
truncateTable() 方法会构建并执行清空表的SQL语句. $table参数指定要清空的表名
.query builder将会引用合适的表名.
下面是展示如何清空表的示例:
<br>
// TRUNCATE TABLE `tbl_user` truncateTable('tbl_user')
<br>
function addColumn($table, $column, $type)
addColumn() 方法构建并执行 SQL语句来添加一个新的列,$table参数指定新增列的表名
. $column
参数指定新增列的名称. $type
指定了新增列的定义. 列定义可能包含抽象数据类型, 这在 "createTable"里已经说明过. query builder 将会引用表名和合适的列名.
下面展示的是如何为表新增列的例子:
<br>
// ALTER TABLE `tbl_user` ADD `email` varchar(255) NOT NULL addColumn('tbl_user', 'email', 'string NOT NULL')
<br>
function dropColumn($table, $column)
dropColumn() 方法构建并执行删除表的列的SQL语句. $table参数指定了要删除列的表名
. $column
参数指定了要删除的列名. query builder 将会引用表名和合适的列名.
下面是如何删除表列的例子:
<br>
// ALTER TABLE `tbl_user` DROP COLUMN `location` dropColumn('tbl_user', 'location')
<br>
function renameColumn($table, $name, $newName)
renameColumn() 方法构建并执行重命名表的列的SQL语句. $table参数指定了要重命名列的表名. $name参数指定了旧的列名
. $newName
参数指定了新的列名. query builder 将会引用表名和合适的列名.
下面展示了如何重命名一个表的列:
<br>
// ALTER TABLE `tbl_users` CHANGE `name` `username` varchar(255) NOT NULL renameColumn('tbl_user', 'name', 'username')
<br>
function alterColumn($table, $column, $type)
alterColumn() 方法构建并执行修改表列的 SQL 语句 . $table参数指定了将要被修改列的表名
. $column
参数指定了将要被修改的列名.$type
指定了列的新定义,列定义可能包含抽象数据类型. query builder将会引用表名和合适的列名.
下面展示了如何修改一个表的列:
<br>
// ALTER TABLE `tbl_user` CHANGE `username` `username` varchar(255) NOT NULL alterColumn('tbl_user', 'username', 'string NOT NULL')
<br>
function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete=null, $update=null)
addForeignKey() 方法构建并执行为一个表新增外键约束的SQL语句. $name
参数指定外键名称. $table
和 $columns
参数指定表名和添加外键的列名. 如果有多个列, 它们必须由逗号分隔. $refTable和
$refColumns
参数指定了外键指向的表名和对应的列名.$delete
和 $update
参数分别指定SQL语句中的ON DELETE
和 ON UPDATE
操作. 大多数 DBMS 支持这些操作:RESTRICT
, CASCADE
, NO ACTION
, SET DEFAULT
, SET NULL
. query builder 将会引用表名,索引名和列名
下面的例子展示了如何该表添加外键约束,
<br>
// ALTER TABLE `tbl_profile` ADD CONSTRAINT `fk_profile_user_id` // FOREIGN KEY (`user_id`) REFERENCES `tbl_user` (`id`) // ON DELETE CASCADE ON UPDATE CASCADE addForeignKey('fk_profile_user_id', 'tbl_profile', 'user_id', 'tbl_user', 'id', 'CASCADE', 'CASCADE')
<br>
function dropForeignKey($name, $table)
dropForeignKey() 方法构建和执行删除外键约束的 SQL 语句. $name
参数指定了要删除的外键名. $table
参数指定了外键所在的表名. query builder 将会引用表名和合适的约束名.
下面的例子展示了如何删除外键约束:
<br>
// ALTER TABLE `tbl_profile` DROP FOREIGN KEY `fk_profile_user_id` dropForeignKey('fk_profile_user_id', 'tbl_profile')
<br>
function createIndex($name, $table, $column, $unique=false)
createIndex() 方法构建并执行创建索引的 SQL语句. $name
参数指定了要创建的索引名称. $table
参数指定了创建索引的表名. $column
参数指定了被索引的列名. $unique参数指定了是否要创建
unique索引. 如果索引包含多个列,按么必须通过逗号分隔. query builder 将会引用表名, 索引名和列名.
下面的例子展示了如何创建索引:
<br>
// CREATE INDEX `idx_username` ON `tbl_user` (`username`) createIndex('idx_username', 'tbl_user', 'username')
<br>
function dropIndex($name, $table)
dropIndex() 方法构建并执行了删除索引的 SQL 语句. $name
参数指定要删除的索引名. $table
参数指定了索引所在的表名. query builder 将会引用表名和合适的索引名.
下面的例子展示了如何删除索引:
// DROP INDEX `idx_username` ON `tbl_user` dropIndex('idx_username', 'tbl_user')
以上就是Yii框架官方指南系列24——使用数据库:Query Builder的内容,更多相关内容请关注PHP中文网(www.php.cn)!
<br>
<br>