·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> php网站开发 >> Yii的学习(3)--查询生成器 (Query Builder)

Yii的学习(3)--查询生成器 (Query Builder)

作者:佚名      php网站开发编辑:admin      更新时间:2022-07-23
Yii的学习(3)--查询生成器 (Query Builder)

原文地址:http://www.yiiframework.com/doc/guide/1.1/en/database.query-builder

不过原文是英文的,Yii的官网没有翻译这一章,自己就尝试着翻译了一下,有很多地方时会按自己的理解写,不一定完全按原文翻译。。。

Yii的查询生成器提供了用面向对象的方式写SQL语句。它允许开发人员使用类的方法和属性来指定一个SQL语句的各个部分。然后,组装成一个有效的SQL语句,可以通过调用DAO数据访问对象的描述方法为进一步执行。以下显示了一个典型的使用查询生成器建立一个select语句:

$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();

当你在应用程序中需要组装SQL语句的程序,或基于一些条件逻辑时,最好使用查询生成器。使用查询生成器的好处主要包括:

  • 它可以建立复杂的SQL语句编程。

  • 它会自引用表名和列名防止SQL保留字和特殊字符的冲突。

  • 它还可以引用参数值和使用参数绑定,这有助于减少SQL注入攻击的风险。

  • 它提供了一定程度的数据库抽象,简化了迁移到不同的数据库平台的成本。

它不强制使用查询生成器。事实上,如果你的查询是简单的,它是更容易和更快的直接写SQL语句。

注:查询生成器不能用于修改现有的查询指定为SQL语句。例如,下面的代码将不能工作:

$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));

换句话说,不要混合使用普通的SQL和查询生成器。

1. 制备查询生成器(Preparing Query Builder)

Yii的查询生成器是从 CDbCommand提供主要数据库查询类,描述数据访问对象。

开始使用查询生成器,我们创造了CDbCommand的一个新实例,

$command = Yii::app()->db->createCommand();

我们使用Yii::app()->db来获得数据库连接,然后调用CDbConnection::createCommand()创建所需的命令实例。

请注意,将整个SQL语句放入 createcommand() ,叫做数据访问对象,我们需呀把设置它为空。这是因为我们将在下面的解释中使用查询生成器添加SQL语句的各个部分的方法。

2. 建立数据检索查询(Building Data Retrieval Queries)

数据检索查询是指选择SQL语句。查询生成器提供了一套方法来建立一个SELECT语句的各个部分。因为所有这些方法返回CDbCommand的实例,我们可以使用方法链调用他们,如图所示,在本节开头的例子。

  • select(): 指定查询的选择部分 specifies the SELECT part of the query
  • selectDistinct(): 指定查询不重复的选择部分 specifies the SELECT part of the query and turns on the DISTINCT flag
  • from(): 指定查询的FROM specifies the FROM part of the query
  • where(): 指定查询的WHERE specifies the WHERE part of the query
  • andWhere(): 用and的方式添加到WHERE的条件中 appends condition to the WHERE part of the query withANDOperator
  • orWhere(): 用or的方式添加到WHERE的条件中 appends condition to the WHERE part of the query withORoperator
  • join(): 添加一个内部联接的查询片段 appends an inner join query fragment
  • leftJoin(): 追加一个左外连接查询片段 appends a left outer join query fragment
  • rightJoin(): 追加一个右外部联接查询片段 appends a right outer join query fragment
  • crossJoin(): 追加一个交叉连接查询片段 appends a cross join query fragment
  • naturalJoin(): 追加一个自然连接查询片段 appends a natural join query fragment
  • group(): 指定查询的GROUP BY specifies the GROUP BY part of the query
  • having(): 指定查询的HAVING specifies the HAVING part of the query
  • order(): 指定查询的ORDER BY specifies the ORDER BY part of the query
  • limit(): 指定查询的LIMIT specifies the LIMIT part of the query
  • offset(): 指定查询的OFFSET specifies the OFFSET part of the query
  • union(): 添加查询的UNION appends a UNION query fragment

在下面,我们将解释如何使用这些查询生成器方法。为简单起见,我们假设底层数据库是MySQL。注意:如果你使用的是其他数据库,表/列/值引用的例子可能是不同的。

select()
function select($columns='*')

该select()方法指定一个查询的选择部分。$columns参数指定要选择的列,它可以是一个字符串,用逗号分隔列,或者一个数组的列名称。列的名称可以包含表的前缀和 / 或列别名。该方法将自动引用列名,除非一列包含一些括号(这意味着这个列是一个DB的表达式)。

下面是一些例子:

// 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 numselect(array('id', 'count(*) as num'))
selectDistinct()
function selectDistinct($columns)

selectdistinct()方法类似于select(),除了它打开了DISTINCT的标志。例如,selectdistinct('id,用户名”)会产生以下SQL:

SELECT DISTINCT `id`, `username`
from()
function from($tables)

from()方法指定来了一个查询的FROM部分。$tables参数指定表的选择。这可以是一个字符串,用逗号分隔的表的名称,或表名数组。表的名称可以包含架构前缀(例如公共。tbl_user)和/或表的别名(e.g.tbl_user U)。该方法将自动引用表的名称,除非它包含一些括号(即表是一个给定的子查询或DB的表达式)。

下面是一些例子:

// 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) pfrom(array('tbl_user', '(select * from tbl_profile) p'))
where()
function where($conditions, $params=array())

where()方法指定查询的WHERE。$conditions 参数指定查询条件的同时,$params 指定参数绑定到整个查询。$conditions参数可以是一个字符串(例如id =1)或一个数组中的格式:

array(operator, operand1, operand2, ...)

operator可以是以下的任何一个:

  • and: operands应该使用 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 操作,除了operands是使用 OR 连接的。

  • in: operand 1应是一个列或DB表达式,而 operand 2是代表值的范围的数组,列或 DB 表达式应在这个数组的范围内。例如,array('in', 'id', array(1,2,3))将生成id IN (1,2,3)

  • not in: 类似 in 操作,除了用 NOT IN 代替 IN 去生成SQL。

  • like: operand 1应是一个列或DB 表达式,而operand 2是代表值的范围的数组,列或 DB 表达式应在这个数组的范围内。例如,array('like', 'name', '%tester%')会生成name LIKE '%tester%'。当规定值的范围为一个数组时,多个 LIKE 生成SQL时会用 AND 连接。例如,array('like', 'name', array('%test%', '%sample%'))会生成name LIKE '%test%' AND name LIKE '%sample%'

  • not like:类似 like 的操作,除了用 NOT LIKE代替 LIKE 去生成SQL。

  • or like: 类似 like 的操作,除了多个 like 生成 SQL 时用OR连接。

  • or not like: 类似 not like 的操作,除了多个 like 生成 SQL 时用OR连接。

下面是一些例子,使用的地方:

// WHERE id=1 or id=2where('id=1 or id=2')// WHERE id=:id1 or id=:id2where('id=:id1 or id=:id2', array(':id1'=>1, ':id2'=>2))// WHERE id=1 OR id=2where(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时,我们必须明确指定的通配符(如%和_)的模式。如果参数是从用户的输入,我们也应该使用下面的代码转义特殊字符,以防止他们被当作通配符:

$keyWord=$_GET['q'];// escape % and _ characters$keyword=strtr($keyword, array('%'=>'\%', '_'=>'\_'));$command->where(array('like', 'title', '%'.$keyword.'%'));
andWhere()
function andWhere($conditions, $params=array())

用 and 的方式添加到WHERE的条件中。此方法的行为几乎是 where() 相同,除了它只是添加条件不能取代它。在where()文档中有该方法参数的详细信息。

orWhere()
function orWhere($conditions, $params=array())

用 or 的方式添加到WHERE的条件中。此方法的行为几乎是 where() 相同,除了它只是添加条件不能取代它。在where()文档中有该方法参数的详细信息。

order()
function order($columns)

order() 方法指定查询的ORDER BY部分。$columns参数指定列进行排序,这可以是一个包含用逗号分隔列和order的方向(ASC 或DESC)的字符串,或者一个列和order的方向的数组。列名称可以包含表前缀。该方法将自动引用列名,除非一列包含一些括号(即给出一个DB表达式)。

下面是一些例子:

// ORDER BY `name`, `id` DE