[TOC]
## select方法的使用
#### 1、 功能:根據查詢器條件,生在查詢SQL語句
#### 2、源碼位置:/thinkphp/library/think/db/Builder.php
>[success] 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%', '', '%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;
}
~~~
* 源碼分析:
>[info] * 參數為數組,可以為空,即可不傳入任何參數;
* 返回是一個由各個條件組合而成的,完整的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語句最簡單的形式嗎?我們從此入手:
* <font color="forestgreen">SELECT 字段列表 FROM 表名 WHERE 查詢條件</font>
* 字段列表由:field方法提供;
* 數據表由:table方法、name方法或者db助手函數提供;
* select 可接受Query類中$options查詢參數屬性做為參數;
* 更多情況,查詢條件由select之前的查詢器方法提供;
* select方法的參數推薦不填寫,全部由前面查詢器提供。
* select方法返回一個結果集,以二維數據表示;
#### 4、適用環境或條件
>[success] * 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的員工姓名和工資
> <font color="DeepPink">特別提示:</font> 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)
}
}
~~~
>[info] 如果根據主鍵同時查詢多條記錄,可將多個主鍵寫在一個字符串。
下面我們將代碼中查詢語句修改一下:
~~~
//查詢條件為多個主鍵組成的字符串:
dump(Db::table('tp5_staff')->field('id,name,salary')->select('1006,1008,1010'));
~~~
>[success]這時,應該返回主鍵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']));
}
}
~~~
>[success] 可以看出,與字符串做參數相比,區別僅僅是把主鍵字符串做為元素,放在了索引數組中
查詢結果如下:
~~~
array(1) {
[0] => array(3) {
["id"] => int(1006)
["name"] => string(9) "西門慶"
["salary"] => float(19801)
}
}
~~~
>[success] 同字符串做參數類似,多個主鍵查詢時,只需要把多個主鍵值做為數組元素即可
我們改寫一下上面代碼中關鍵語句:
~~~
//查詢條件為多個主鍵字符串組成的索引數組:
dump(Db::table('tp5_staff')->field('id,name,salary')->select(['1006','1008','1010']));
~~~
>[success] 返回的查詢結果與上面是一樣的:
~~~
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)
}
}
~~~
>[success] 采用數組做為參數,可以構造更為復雜的查詢條件,下面我們演示一下,在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']]));
}
}
~~~
>[info] 有的同學,看到這里,可能有點發懵,這不是多此一舉嗎?明明一個字符串就可以解決的事,干嗎整得這么復雜?那么問題來了:
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參數
>[warning] 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參數
>[info] 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 中大量的應用到了閉包查詢,從現在起,同學們一定要適應這種變化
* * * * *
### 總結:
>[success]1、select方法,除閉包外,不推薦使用參數;
2、所有查詢條件,應該在前面用鏈式操作構成~~</font>
- 前言[隨時更新]
- ThinkPHP 5數據庫重構
- 開發環境
- 1.ThinkPHP5開發環境(Mac版)
- 2.ThinkPHP5開發環境(Win版)
- MySQL快速復習
- 1.數據庫操作
- 2.數據表操作
- 1.創建數據表 (重點)
- 2.添加數據表記錄
- 3.查詢數據表(重點)
- 4.更新數據表
- 5.編輯數據表結構(重點)
- 6_復制數據表
- 7.刪除數據和表
- 連接數據庫
- 1.數據庫配置文件database.php
- 2.Db類靜態方法connect()
- 3.模塊中的配置文件config.php
- MySQL原生查詢
- 1.讀操作query
- 2.寫操作execute
- 選擇數據表
- 1.table與setTable方法
- 2.name方法
- 3.db助手函數
- 4.alias方法
- 結果集查詢
- 1.find方法
- 2.select方法
- 3.fetchSql方法
- 4.value方法
- 5.column方法
- 6.field方法
- 新增數據
- 1.insert_單條添加
- 2.insertAll_批量添加
- 3_db_助手函數添加
- 更新數據
- 1.update方法
- 2.setField更新字段
- 3_自增自減與延時更新
- 刪除數據
- 1.delete方法
- 查詢方法
- 1.getTableInfo方法
- 2.where方法
- 3.whereOr方法
- 4.混合查詢(閉包實現)
- 表達式查詢
- 1.表達式查詢(重點)
- 2.exp通用查詢
- 分組查詢
- 1.group方法
- 2.having方法
- 排序分頁查詢
- 1.order方法
- 2.limit方法
- 3.page方法
- 聚合查詢
- 時間查詢
- 1.where方法
- 2.whereTime方法
- 高級查詢
- 1.快捷查詢
- 2.區間查詢
- 3.批量查詢
- 4.Query對象查詢
- 5.混合查詢
- 視圖查詢
- view方法
- 子查詢
- 1.select方法
- 2.fetchSql方法
- 3.buildSql方法
- 4.閉包子查詢
- 總結/參考
- 1.方法參數類型總結
- 2.查詢/子查詢/連接查詢