Yii definitive guide 翻译之二 query builder:查询语句的生成

本文详细介绍了Yii框架中查询生成器的各种方法及其用法,包括select、from、where等,并通过具体示例展示了如何构建复杂的SQL查询。

本文由Yii官方网站尚未汉化的the definitive guide to Yii翻译而来,译文为原创,转载请标注本博客地址。

英文版原文地址


        也就是说我们将要生成一个select的SQL语句。查询生成器提供了一系列方法来建立一个select的语句的各个部分。由于这些方法返回的都是CDbCommand的实例,所以我们可以通过函数链来调用各个方法,就像这一章刚开始的那样。


            select():指定查询的时候使用select语句。 
            selectDistinct(): 指定了select部分的修饰,开启DISTINCT标识。
            from(): 指定from部分的语句。
            where(): 指定where部分的语句。
            join(): 加上内链接。
            leftJoin(): 加上左链接。
            rightJoin():加上右链接。 
            crossJoin():加上交叉链接。 
            naturalJoin(): 加上自然链接。
            group(): 加上GROUP BY。
            having(): 指定查询语句中的HAVING部分。
            order(): 指定查询语句中的ORDER BY部分。
            limit(): 指定查询语句中的LIMIT部分。
            offset(): 指定查询语句中的OFFSET部分。
            union(): 加上UNION。

        接下来,我们就来解释一下怎么使用这些查询生成方法。方便起见,我们假设您使用的数据库是MySQL。注意如果你用的是其他的数据库系统,表达例子中表达数据表/列/值的方法可能会不一样。


    select()

        function select($columns='*')


        select()方法指定了一个查询语句的select部分。$columns参数指定需要选择的列,它既可以是一个由逗号分割的列名字符串,也可以是一个存放列名的数组。列名也可以包含表前缀或者列别名。这个方法会自动地用引号包装列名,除非这个列名中含有括号(这意味着列是由数据库生成的)。

    下面是一些例子:

        // 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()

            function selectDistinct($columns)
        这个函数类似于select(),但是它开启了DISTINCT功能。这个函数将会生成下面的SQL语句:        
SELECT DISTINCT `id`, `username`

    from()
        function from($tables)

        from()方法指定了查询中的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指定条件中需要绑定的参数。$conditions参数能够是一个字符串,也能是一个数组,但必须按照下面给出的格式:

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

            where操作符可以是按照下面这样的格式来写:

            

            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

                    第二个参数应该是一个列名,或者查询语句,第三个参数应该是一个关于列名值的范围的数组。例如:array('in', 'id', array(1,2,3))将会生成 id IN (1,2,3)。这个方法会正确地将列名用引号包起来,以及正确处理范围数组中的特殊字。

            not in

                    类似于in,也就是把in换成not in而已。

            like

                    第二个参数应当是一个列名或者查询语句,第三个参数是一个字符串或者是由数组表达的列名的值应该符合的式子。例如:array('like', 'name', '%tester%')就会生成name LIKE '%tester%'。当式子是由数组给出的一个范围时,多个式子就由AND串联起来。例如:array('like', 'name', array('%tester%','%sample%'))将会生成name LIKE'%tester%' AND name LIKE '%sample%'。这个方法会正确地将列名应引号包起来,以及正确处理范围数组中的特殊字。

            not like

                    类似于like,也就是把like 换成 not like。

            or like

                    类似于like,只不过是用or来链接多个like式子。

            or not like

                    类似于not like,只不过是用or来链接多个式子。



            下面是一些使用where方法的例子:
                // 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操作数的时候,我们必须要在式子中明显地指定通配符(%或者_)。如果式子是由用户输入的,我们也应该使用下面的代码来处理特殊符号,防止出现一些不必要的安全问题。
                $keyword=$_GET['q'];
                // escape % and _ characters
                $keyword=strtr($keyword, array('%'=>'\%', '_'=>'\_'));
                $command->where(array('like', 'title', '%'.$keyword.'%'));

    order()
        function order($columns)
        order()方法指定了查询中的ORDER BY部分。$columns参数指定了需要排序的列名,列名可以用逗号隔开,以字符串的方式表达,然后加上排序顺序。或者将列名和排序顺序放入数组中。列名可以包括前缀。这个方法会自动将列名用引号包起来,除非列名是由自查询得到的。
        下面是一些例子:
            // ORDER BY `name`, `id` DESC
            order('name, id desc')
            // ORDER BY `tbl_profile`.`name`, `id` DESC
            order(array('tbl_profile.name', 'id desc'))

    limit() and offset()
        function limit($limit, $offset=null)
        function offset($offset)
        limit()和offset()函数指定了查询中的LIMIT和OFFSET部分。注意有些数据库系统可能不支持LIMIT和OFFSET语法。在这种情况下,查询生成器将会重写整个SQL语句去模仿完成limit和offset的功能。

       下面是一些例子:
            // LIMIT 10
            limit(10)
            // LIMIT 10 OFFSET 20
            limit(10, 20)
            // OFFSET 20
            offset(20)

    join()和它的其他变种
        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, or NATURAL JOIN进行表的链接。$table参数指定了需要链接的表。表名可以包含前缀,或者别名,或者两者都可以。这个方法会将表名用引号包起来,除非表名是由子查询获得的。$condition参数指定了链接条件。它的语法就跟where()一样。然后$params参数指定了在整个查询中需要绑定的变量。
        注意:跟其他的查询生成方法不同,每次调用join方法的时候都是针对上一个查询调用的。


        下面是一些例子:
            // 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))

    group()
        function group($columns)
            group()方法指定了查询中的GROUP BY部分。$columns参数指定了需要合并分组的列。它可以是用逗号分割的列名字符串,也可以是存放列名的数组。列名可以包括前缀。这个方法会自动地用引号包围列名。除非列名是由子查询给出的。
            下面是一些例子:
                // GROUP BY `name`, `id`
                group('name, id')
                // GROUP BY `tbl_profile`.`name`, `id`
                group(array('tbl_profile.name', 'id')

    having()
        function having($conditions, $params=array())
        having()方法指定了查询中的HAVING部分,他的用法就跟where一样。
        下面是一些例子:
            // 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'))

    union()
        function union($sql)
        union()方法指定了查询中的UNION部分。它使用UNION操作符将$sql中的查询挂在一个现有的SQL查询中去。多次调用union()方法你就能够在现有的SQL查询中再挂上一堆查询。
        下面是一些例子:
        // UNION (select * from tbl_profile)
        union('select * from tbl_profile')

本文由Yii官方网站尚未汉化的the definitive guide to Yii翻译而来,译文为原创,转载请标注本博客地址。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值