欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

选择方法

最编程 2024-04-15 20:00:24
...
    • select方法的使用
        • 1、 功能:根据查询器条件,生在查询SQL语句
        • 2、源码位置:/thinkphp/library/think/db/Builder.php
        • 3、参数和返回值
        • 4、适用环境或条件
        • 5、调用语法:
        • 6、实例:查询id=1006的员工姓名和工资
        • 1.字符串做select参数
        • 2.  数组做select参数
        • 3、布尔值做select参数
        • 4.  闭包做select参数
      • 总结:

select方法的使用

1、 功能:根据查询器条件,生在查询SQL语句

2、源码位置:/thinkphp/library/think/db/Builder.php

1、其实在Query.php查询类中也有一个select方法,使用是产生子查询;
 2、该方法要产生查询结果,本质还是调用SQL生成器类Builder.php中select方法;
 3、该类不是我们教学内容,等用到时再详细说明,本处不做过多介绍。

/**
     * 生成查询SQL
     * @access public
     * @param array $options 表达式
     * @return string
     */
    public function select($options = [])
    {
        $sql = str_replace(
            ['%TABLE%', '%DISTINCT%', '%FIELD%', '%JOIN%', '%WHERE%', '%GROUP%', '%HAVING%', '%ORDER%', '%LIMIT%', '%UNION%', '%LOCK%', '%COMMENT%', '%FORCE%'],
            [
                $this->parseTable($options['table'], $options),
                $this->parseDistinct($options['distinct']),
                $this->parseField($options['field'], $options),
                $this->parseJoin($options['join'], $options),
                $this->parseWhere($options['where'], $options),
                $this->parseGroup($options['group']),
                $this->parseHaving($options['having']),
                $this->parseOrder($options['order'], $options),
                $this->parseLimit($options['limit']),
                $this->parseUnion($options['union']),
                $this->parseLock($options['lock']),
                $this->parseComment($options['comment']),
                $this->parseForce($options['force']),
            ], $this->selectSql);
        return $sql;
    }


  • 源码分析:


    • 参数为数组,可以为空,即可不传入任何参数;
    • 返回是一个由各个条件组合而成的,完整的SELECT查询语句字符串;
    • 内部是通过一个str_replace()字符串替换函数实现,该函数有二个参数,均是数组形式;
    • 从字符替换函数第二个参数可以看出该select方法支持的连贯方法有哪些?
    • 方法有下面这些:
       tabble,distinct,field,join,where,group,having,order,limit,union,lock,comment,force等,这些方法,后面我们都将一一讲到。
    • 在源码中,没有列出的连贯方法,就是不支持的方法,在select方法之前不要使用;
    • 这些方法,全部会拼接成查询选项,最终放在Query类的静态options属性数组中。
    • Query 类中,有并查询要用的属性如下:



class Query
{
    // 数据库Connection对象实例
    protected $connection;
    // 数据库驱动类型
    protected $builder;
    // 当前模型类名称
    protected $model;
    // 当前数据表名称(含前缀)
    protected $table = '';
    // 当前数据表名称(不含前缀)
    protected $name = '';
    // 当前数据表主键
    protected $pk;
    // 当前数据表前缀
    protected $prefix = '';
    // 查询参数
    protected $options = [];
    // 参数绑定
    protected $bind = [];
    // 数据表信息
    protected static $info = [];
  • 是不是很眼熟呢?对,我们之前学习过table和name方法,就是完成给静态属性$table和$name赋值的。

    3、参数和返回值

  • 还记得SELECT语句最简单的形式吗?我们从此入手:

    • SELECT 字段列表  FROM 表名  WHERE  查询条件
    • 字段列表由:field方法提供;
    • 数据表由:table方法、name方法或者db助手函数提供;
    • select 可接受Query类中$options查询参数属性做为参数;
    • 更多情况,查询条件由select之前的查询器方法提供;
    • select方法的参数推荐不填写,全部由前面查询器提供。
  • select方法返回一个结果集,以二维数据表示;

    4、适用环境或条件

    • select方法是我们操作数据库时最重要的一方法
    • 该方法不是连贯操作(链式方法),在3.2.3中叫终级方法;
    • 该方法定义在SQL生成器类中,一定要注意与普通连贯方法的区别;
    • 该方法最典型的用法,就是放在所有连贯操作最后,用来生成SQL语句。

    5、调用语法:

  • 静态调用:用Db类静态方法实现

 Db::table(完整表名)->field(字段列表)->select(查询条件);

 //如定义了表前缀,可用name方法
  Db::name(去前缀表名)->field(字段列表)->select(查询条件);
  • 动态调用:用助手函数db实现
db(去前缀表名)field(字段列表)->select(查询条件);
  • 参数部分,如表名、字段列表、查询条件可以使用以下类型:
序号 参数类型 说明
1 字符串 这是最常用的,简单,直观
2 数组 推荐使用,严谨规范,扩展性强
3 布尔 false:不执行查询,仅返回SQL语句,无true值
3 闭包 即匿名函数,可支持更多的查询方法

6、实例:查询id=1006的员工姓名和工资

特别提示: select参数仅限主键查询

目前表中数据如下:

1.字符串做select参数

<?php
namespace app\index\controller;
use think\Db;
class Index {
    public function index(){ 

        //查询条件为字符串:
        dump(Db::table('tp5_staff')->field('id,name,salary')->select('1006'));
        } 
}

查询结果如下:

array(1) {
  [0] => array(3) {
    ["id"] => int(1006)
    ["name"] => string(9) "西门庆"
    ["salary"] => float(19801)
  }
}

如果根据主键同时查询多条记录,可将多个主键写在一个字符串。
 下面我们将代码中查询语句修改一下:

//查询条件为多个主键组成的字符串:
        dump(Db::table('tp5_staff')->field('id,name,salary')->select('1006,1008,1010'));

这时,应该返回主键id为1006、1008和1010三条记录

array(3) {
  [0] => array(3) {
    ["id"] => int(1006)
    ["name"] => string(9) "西门庆"
    ["salary"] => float(19801)
  }
  [1] => array(3) {
    ["id"] => int(1008)
    ["name"] => string(6) "宋江"
    ["salary"] => float(9261)
  }
  [2] => array(3) {
    ["id"] => int(1010)
    ["name"] => string(9) "欧阳峰"
    ["salary"] => float(4900)
  }
}

2.  数组做select参数

<?php
namespace app\index\controller;
use think\Db;
class Index {
    public function index(){ 

        //查询条件为字符串:
        dump(Db::table('tp5_staff')->field('id,name,salary')->select(['1006']));
        } 
}

可以看出,与字符串做参数相比,区别仅仅是把主键字符串做为元素,放在了索引数组中

查询结果如下:

array(1) {
  [0] => array(3) {
    ["id"] => int(1006)
    ["name"] => string(9) "西门庆"
    ["salary"] => float(19801)
  }
}

同字符串做参数类似,多个主键查询时,只需要把多个主键值做为数组元素即可
 我们改写一下上面代码中关键语句:

//查询条件为多个主键字符串组成的索引数组:
        dump(Db::table('tp5_staff')->field('id,name,salary')->select(['1006','1008','1010']));

返回的查询结果与上面是一样的:

array(3) {
  [0] => array(3) {
    ["id"] => int(1006)
    ["name"] => string(9) "西门庆"
    ["salary"] => float(19801)
  }
  [1] => array(3) {
    ["id"] => int(1008)
    ["name"] => string(6) "宋江"
    ["salary"] => float(9261)
  }
  [2] => array(3) {
    ["id"] => int(1010)
    ["name"] => string(9) "欧阳峰"
    ["salary"] => float(4900)
  }
}

采用数组做为参数,可以构造更为复杂的查询条件,下面我们演示一下,在select方法中,用关联数组,构造更为复杂些查询表达式。

  • 我们做关联数组方式,将上面的例子再次改写一下
<?php
namespace app\index\controller;
use think\Db;
class Index {
    public function index(){ 

        //查询条件关联数组,键名为表主键,后面紧跟着给出条件:
        dump(Db::table('tp5_staff')->field('id,name,salary')->select(['id'=>['=','1010']]));
 } 
}

有的同学,看到这里,可能有点发懵,这不是多此一举吗?明明一个字符串就可以解决的事,干吗整得这么复杂?那么问题来了:
 1、如果要查询id大于1010的员工信息,怎么办?
 2、如果要查询id号位于1010到1015之间的员工信息怎么办?
 显然,字符串仅提供了简单的相等查询,更为复杂的查询,就无能为力了。

  • 实例:查询id大于1010的员工信息

明白上以上内容,现在就简单多了,只需要把比较运算符由“=”,换成“>”就行了

<?php
namespace app\index\controller;
use think\Db;
class Index {
    public function index(){ 

        //查询条件关联数组,键名为表主键,后面紧跟着给出条件:
        dump(Db::table('tp5_staff')->field('id,name,salary')->select(['id'=>['>','1010']]));
 } 
}
  • 查询结果如下:
array(2) {
  [0] => array(3) {
    ["id"] => int(1011)
    ["name"] => string(9) "李云龙"
    ["salary"] => float(4800)
  }
  [1] => array(3) {
    ["id"] => int(1012)
    ["name"] => string(9) "楚云飞"
    ["salary"] => float(4800)
  }
}

3、布尔值做select参数

1.只能填false,不能填:true
 2.false:不执行查询,返回查询SQL语句

  • Index.php :
<?php
namespace app\index\controller;
use think\Db;
class Index {
    public function index(){ 

        // 1.获取工资大于5000的员工信息
        $result = Db::table('tp5_staff')  //指定tp5_staff表
        ->field(['id'=>'编号','name'=>'姓名','salary'=>'工资'])    //设置返回字段
        ->where('salary','>',5000)  //设置查询条件
        ->select(false);    //  生成SQL语句字符串

        // 2、输出查询SQL字符串     
        echo $result;
 } 
}
  • 运行结果:
SELECT `id` AS `编号`,`name` AS `姓名`,`salary` AS `工资` FROM `tp5_staff` WHERE `salary` > 5000

4.  闭包做select参数

1、补充知识:闭包就是匿名函数,所谓匿名,就是没有名字。
 2、我们知道,变量或函数,都是按名调用,没有名称,如何调用呢?
 3、匿名并不是没有名字,而是指名字不固定,是一个可随意变化的值;
 4、匿名函数,一句话概括:就是用变量名来调用的函数。

  • 实例:查询工资大于5000无的员工基本信息
<?php
namespace app\index\controller;
use think\Db;
class Index {
    public function index(){ 

        //闭包参数支持更多的查询方法,可以构造更加复杂的查询器
        dump(Db::select(function ($query){
            $query->table('tp5_staff')->field('id,name,salary')->where('salary >= 5000');

        }));
 } 
}
  • 代码中的闭包函数部分,将select方法之前的所有查询器方法全部集成到了闭包中:
$query->table('tp5_staff')->field('id,name,salary')->where('salary >= 5000');
  • ThinkPHP 5 中大量的应用到了闭包查询,从现在起,同学们一定要适应这种变化

总结:

1、select方法,除闭包外,不推荐使用参数;
 2、所有查询条件,应该在前面用链式操作构成~~

上一篇: 摘星子论酒

下一篇: SQLite 简介