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

王朝学院·作者佚名  2016-05-25
窄屏简体版  字體: 小  |  中  |  大  |  超大  

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 queryselectDistinct(): 指定查询不重复的选择部分 specifies the SELECT part of the query and turns on the DISTINCT flagfrom(): 指定查询的FROM specifies the FROM part of the querywhere(): 指定查询的WHERE specifies the WHERE part of the queryandWhere(): 用and的方式添加到WHERE的条件中 appends condition to the WHERE part of the query withANDOperatororWhere(): 用or的方式添加到WHERE的条件中 appends condition to the WHERE part of the query withORoperatorjoin(): 添加一个内部联接的查询片段 appends an inner join query fragmentleftJoin(): 追加一个左外连接查询片段 appends a left outer join query fragmentrightJoin(): 追加一个右外部联接查询片段 appends a right outer join query fragmentcrossJoin(): 追加一个交叉连接查询片段 appends a cross join query fragmentnaturalJoin(): 追加一个自然连接查询片段 appends a natural join query fragmentgroup(): 指定查询的GROUP BY specifies the GROUP BY part of the queryhaving(): 指定查询的HAVING specifies the HAVING part of the queryorder(): 指定查询的ORDER BY specifies the ORDER BY part of the querylimit(): 指定查询的LIMIT specifies the LIMIT part of the queryoffset(): 指定查询的OFFSET specifies the OFFSET part of the queryunion(): 添加查询的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

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航