ThinkPHP5.1學習筆記 數據庫操做

數據庫

參見《Thinkphp5.1徹底開發手冊》學習
Mirror王宇陽php

數據庫鏈接

  • ThinkPHP採用內置抽象層對數據庫操做進行封裝處理;且基於PDO模式,能夠適配各類數據庫。mysql

  • 數據庫鏈接的配置文件(config/database.php)設置數據庫的鏈接信息sql

    class DataTest extends Controller// 數據庫鏈接
    { // url => http://localhost/tp5.1/public/index.php/index/data_test
        public function index()
        {
            $data = Db::table('tp_access')->select();
            $data = Db::name('access')->select();
            return json($data);
    
        }
    }

查詢控制器(數據庫操做)

想要查看SQL的執行語句細節能夠配置:config/app.php -> app_trace => true;thinkphp

開啓後就能夠在HTML頁面右下角打開SQL語句的具體執行過程數據庫

注意:json輸出的數據沒法使用這一功能哦!json

查詢數據

查詢單個數據使用find方法:數組

// table方法必須指定完整的數據表名
Db::table('think_user')->where('id',1)->find();

最終生成的SQL語句多是:緩存

SELECT * FROM `think_user` WHERE  `id` = 1 LIMIT 1

find 方法查詢結果不存在,返回 null,不然返回結果數組安全

V5.1.23+版本開始,支持findOrEmpty方法,當查詢不存在的時候返回空數組而不是Null。服務器

// table方法必須指定完整的數據表名
Db::table('think_user')->where('id',1)->findOrEmpty();

若是沒有查找到數據,則會拋出一個think\db\exception\DataNotFoundException異常。

try{ //捕獲異常
    // table方法必須指定完整的數據表名
    $data = Db::table('think_user')->where('id',1)->findOrEmpty();
} catch (DataNotFoundException $err) {
    return '數據查詢發送異常!'
}

查詢多個數據(數據集)使用select方法:

Db::table('think_user')->where('status',1)->select();

最終生成的SQL語句多是:

SELECT * FROM `think_user` WHERE `status` = 1

select 方法查詢結果是一個二維數組,若是結果不存在,返回空數組

若是但願在沒有查找到數據後拋出異常可使用

try{ //捕獲異常
    $data = Db::table('think_user')->where('status',1)->selectOrFail();
} catch (DataNotFoundException $err) {
    return '數據查詢發送異常!'
}

默認狀況下,findselect方法返回的都是數組,區別在於後者是二維數組。

系統提供了一個db助手函數,能夠更方便的查詢:

db('user')->where('id',1)->find();
db('user')->where('status',1)->select();

db方法的第一個參數的做用和name方法同樣,若是須要使用不一樣的數據庫鏈接,可使用:

db('user','db_config1')->where('id', 1)->find();

查詢某個字段的值能夠用 value(‘字段名’)

// 返回某個字段的值
Db::table('think_user')->where('id',1)->value('name');

value 方法查詢結果不存在,返回 null

查詢某一列的值能夠用 colum('字段名/列名')

// 返回數組
Db::table('think_user')->where('status',1)->column('name');
// 指定id字段的值做爲索引
Db::table('think_user')->where('status',1)->column('name','id');

若是要返回完整數據,而且添加一個索引值的話,可使用

// 指定id字段的值做爲索引 返回全部數據
Db::table('think_user')->where('status',1)->column('*','id');

column 方法查詢結果不存在,返回空數組

數據分批處理可使用 chunk

咱們能夠所有用戶表數據進行分批處理,每次處理 100 個用戶記錄:

Db::table('think_user')->chunk(100, function($users) {
    foreach ($users as $user) {
        //
    }
});
// 或者交給回調方法myUserIterator處理
Db::table('think_user')->chunk(100, 'myUserIterator');

你能夠經過從閉包函數中返回false來停止對後續數據集的處理:

Db::table('think_user')->chunk(100, function($users) {
    foreach ($users as $user) {
        // 處理結果集...
        if($user->status==0){
            return false;
        }
    }
});

也支持在chunk方法以前調用其它的查詢方法,例如:

Db::table('think_user')
->where('score','>',80)
->chunk(100, function($users) {
    foreach ($users as $user) {
        //
    }
});

chunk方法的處理默認是根據主鍵查詢,支持指定字段,例如:

Db::table('think_user')->chunk(100, function($users) {
    // 處理結果集...
    return false;
},'create_time');

而且支持指定處理數據的順序。

Db::table('think_user')->chunk(100, function($users) {
    // 處理結果集...
    return false;
},'create_time', 'desc');

chunk方法通常用於命令行操做批處理數據庫的數據,不適合WEB訪問處理大量數據,很容易致使超時。

大批量數據處理

若是你須要處理大量的數據,可使用新版提供的遊標查詢功能,該查詢方式利用了PHP的生成器特性,能夠大幅減小大量數據查詢的內存佔用問題。

$cursor = Db::table('user')->where('status', 1)->cursor();
foreach($cursor as $user){
    echo $user['name'];
}

cursor方法返回的是一個生成器對象,user變量是數據表的一條數據(數組)。

JSON類型數據查詢(mysql

// 查詢JSON類型字段 (info字段爲json類型)
Db::table('think_user')
    ->where('info->email','thinkphp@qq.com')
    ->find();
鏈式查詢簡單認識
  • 查詢規則

    • 經過指向符號 -> 屢次連續的調用方法

      Db::table('think_user')
          ->where('status',1)
          ->order('create_time')
          ->limit(10)
          ->select();
    • 屢次i的調用使用返回的都是數據庫對象,能夠屢次的鏈式查詢數據對象的方法

    • 最後的數據庫對象可使用 find()、select() 等結果方法,返回數據結果

    • find()、select()、value()、column() 是結果查詢方法,並非鏈式查詢方法

  • 鏈式查詢方法

    系統支持的鏈式操做方法包含:

    連貫操做 做用 支持的參數類型
    where* 用於AND查詢 字符串、數組和對象
    whereOr* 用於OR查詢 字符串、數組和對象
    wheretime* 用於時間日期的快捷查詢 字符串
    table 用於定義要操做的數據表名稱 字符串和數組
    alias 用於給當前數據表定義別名 字符串
    field* 用於定義要查詢的字段(支持字段排除) 字符串和數組
    order* 用於對結果排序 字符串和數組
    limit 用於限制查詢結果數量 字符串和數字
    page 用於查詢分頁(內部會轉換成limit) 字符串和數字
    group 用於對查詢的group支持 字符串
    having 用於對查詢的having支持 字符串
    join* 用於對查詢的join支持 字符串和數組
    union* 用於對查詢的union支持 字符串、數組和對象
    view* 用於視圖查詢 字符串、數組
    distinct 用於查詢的distinct支持 布爾值
    lock 用於數據庫的鎖機制 布爾值
    cache 用於查詢緩存 支持多個參數
    relation* 用於關聯查詢 字符串
    with* 用於關聯預載入 字符串、數組
    bind* 用於數據綁定操做 數組或多個參數
    comment 用於SQL註釋 字符串
    force 用於數據集的強制索引 字符串
    master 用於設置主服務器讀取數據 布爾值
    strict 用於設置是否嚴格檢測字段名是否存在 布爾值
    sequence 用於設置Pgsql的自增序列名 字符串
    failException 用於設置沒有查詢到數據是否拋出異常 布爾值
    partition 用於設置分表信息 數組 字符串

    全部的連貫操做都返回當前的模型實例對象(this),其中帶*標識的表示支持屢次調用。

  • 更多查詢

    屢次查詢並不須要每次都建立一個實例;能夠保存實例對象進行反覆調用:

    $user = Db::name('user');
    $data = $user->select();
    public function getModelData()
        {
            $book = Db::table('tp_book');     // 建立tp_book的實例並保持$book
            $data = $book->select();
            return json($data);
            $data1 = $book->where('id',1)->column('title');
            //使用被保持的實例
            return json($data1); // 結果返回 莎士比亞
            $data2 = $book->column('title');
            // 被保存的實例會保留上一個查詢結果(對象)
            return json($data3); // 結果返回 與 $data2 一致
        }

    實例會保存上一個查詢對象結果,但使用removerOption()方法能夠清理上一個保留的值

    $data3 = $book->removeOption('where')->column('title');
    return json($data3); // 結果返回 沒有where條件限制了
增刪改操做
新增數據

ThinkPHP5.1使用insert()insertGetId()方法向數據表添加一條數據

使用 Db 類的 insert 方法向數據庫提交數據

$data = ['foo' => 'bar', 'bar' => 'foo'];
// 筆者在insert()的時候,發現中文內容添加後會在數據庫中顯示空白
Db::name('user')->insert($data);

insert 方法添加數據成功返回添加成功的條數,一般狀況返回 1

// 新增數據到數據表中
    public function insert()
    {
        $book = Db::table('tp_book');
        // 匹配添加數據
        $data = [ // 可爲空Null的、自動增補的能夠忽略不添加
            'user_id'    =>  '66',
            'title'      =>  'Mirror'
        ];

        $book->insert($data);

        $select = $book->select();
        return json($select);
    }

或者使用data方法配合insert使用。

$data = ['foo' => 'bar', 'bar' => 'foo'];
Db::name('user')
    ->data($data)
    ->insert();

若是你的數據表裏面沒有foo或者bar字段,那麼就會拋出異常。

若是不但願拋出異常,可使用下面的方法:

$data = ['foo' => 'bar', 'bar' => 'foo'];
Db::name('user')->strict(false)->insert($data);

不存在的字段的值將會直接拋棄。

若是是mysql數據庫,支持replace寫入,例如:

$data = ['foo' => 'bar', 'bar' => 'foo'];
Db::name('user')->insert($data, true);

添加數據後若是須要返回新增數據的自增主鍵,可使用insertGetId方法新增數據並返回主鍵值:

$userId = Db::name('user')->insertGetId($data);

insertGetId 方法添加數據成功返回添加數據的自增主鍵

添加多條數據直接向 Db 類的 insertAll 方法傳入須要添加的數據便可

public  function insertAll()//批量添加到數據表
    {
        $dataAll = [
            [
                'user_id'    =>  '66',
                'title'      =>  '《白帽子講Web安全》'
            ],
            [
                'user_id'   => '88',
                'title'     => '《喬布斯傳》'
            ],
            [
                'user_id'   => '99',
                'title'     => '《白夜行》'
            ],
        ];


        $kk = Db::table('tp_book')->insertAll($dataAll);
        return $kk;
    }

insertAll 方法添加數據成功返回添加成功的條數

若是批量插入的數據比較多,能夠指定分批插入,使用limit方法指定每次插入的數量限制。

$data = [
    ['foo' => 'bar', 'bar' => 'foo'],
    ['foo' => 'bar1', 'bar' => 'foo1'],
    ['foo' => 'bar2', 'bar' => 'foo2']
    ...
];
// 分批寫入 每次最多100條數據
Db::name('user')->data($data)->limit(100)->insertAll();
修改數據
// 修改數據
    public function update()
    {
        $date = [
            'title'     =>  '《解憂雜貨鋪》'
        ];

        $kk = Db::table('tp_book')->where('user_id','99')->update($date);
        return $kk;
    }

update 方法返回影響數據的條數,沒修改任何數據返回 0

若是數據中包含主鍵,能夠直接使用:

Db::name('user')
    ->update(['name' => 'thinkphp','id'=>1]);

若是要更新的數據須要使用SQL函數或者其它字段,可使用下面的方式:

Db::name('user')
    ->where('id',1)
    ->inc('read_time') //對字段增值
    ->dec('score',3) //對字段減值
    ->exp('name','UPPER(name)') // 在字段中使用mysql函數
    ->update();

可使用setInc/setDec方法自增或自減一個字段的值( 如不加第二個參數,默認步長爲1)。

// score 字段加 1
Db::table('think_user')
    ->where('id', 1)
    ->setInc('score');
// score 字段加 5
Db::table('think_user')
    ->where('id', 1)
    ->setInc('score', 5);
// score 字段減 1
Db::table('think_user')
    ->where('id', 1)
    ->setDec('score');
// score 字段減 5
Db::table('think_user')
    ->where('id', 1)
    ->setDec('score', 5);

setInc/setDec支持延時更新,若是須要延時更新則傳入第三個參數,下例中延時10秒更新。

Db::name('user')->where('id', 1)->setInc('score', 1, 10);

V5.1.7+版本之後,支持使用raw方法進行數據更新,適合在數組更新的狀況。

Db::name('user')
    ->where('id', 1)
    ->update([
        'name'      =>  Db::raw('UPPER(name)'),
        'score'     =>  Db::raw('score-3'),
        'read_time' =>  Db::raw('read_time+1')
    ]);

字段值更新 setField('原字段名','新字段名')

Db::name('user')
    ->where('id',1)
    ->setField('name', 'thinkphp');
刪除數據
// 根據主鍵刪除
Db::table('think_user')->delete(1);
Db::table('think_user')->delete([1,2,3]);

// 條件刪除    
Db::table('think_user')->where('id',1)->delete();
Db::table('think_user')->where('id','<',10)->delete();

// 無條件刪除全部數據
Db::name('user')->delete(true);
查詢表達式
比較查詢
Db::name('book')->where('id',80)->find();       //簡寫
Db::name('book')->where('id','=',80)->find();   //完整;且與第一條贊成義

5.1還支持新的查詢方法

whereField('表達式','查詢條件');
whereOrField('表達式','查詢條件');

Field使用字段的駝峯命名方式。

  • where() 格式

    where( 字段名 , 表達式 , 查詢條件);

    表達式包含如下:

    表達式 含義 快捷查詢方法
    = 等於
    <> 不等於
    > 大於
    >= 大於等於
    < 小於
    <= 小於等於
    [NOT] LIKE 模糊查詢 whereLike/whereNotLike
    [NOT] BETWEEN (不在)區間查詢 whereBetween/whereNotBetween
    [NOT] IN (不在)IN 查詢 whereIn/whereNotIn
    [NOT] NULL 查詢字段是否(不)是NULL whereNull/whereNotNull
    [NOT] EXISTS EXISTS查詢 whereExists/whereNotExists
    [NOT] REGEXP 正則(不)匹配查詢 (僅支持Mysql)
    [NOT] BETWEEM TIME 時間區間比較 whereBetweenTime
    > TIME 大於某個時間 whereTime
    < TIME 小於某個時間 whereTime
    >= TIME 大於等於某個時間 whereTime
    <= TIME 小於等於某個時間 whereTime
    EXP 表達式查詢,支持SQL語法 whereExp
區間查詢(建議使用快捷)
  • link 表達式進行模糊查詢

    $data = Db::table('tp_book')->where('title','like','%白%')->column('title');
    return json($data);

    支持使用數組

    // 查詢 title中包含 白和M開頭的書籍
    $data = Db::table('tp_book')
        ->where('title','like',['%白%','M%'],'OR')
        ->column('title');
    return json($data);

    爲了更加方便,應該直接使用whereLike方法

    Db::name('user')->whereLike('name','thinkphp%')->select();
    Db::name('user')->whereNotLike('name','thinkphp%')->select();
  • between 指定區間範圍查找

    查詢條件支持字符串或者數組,例如:

    Db::name('user')->where('id','between','1,8')->select();

    和下面的等效:

    Db::name('user')->where('id','between',[1,8])->select();

    最快捷的查詢方法是:

    Db::name('user')->whereBetween('id','1,8')->select();
    Db::name('user')->whereNotBetween('id','1,8')->select();
  • in 指定索引查找

    // in、not in 指定全部查找
    $data = Db::table('tp_book')->where('id','in','1,2,23')->column('title');
    $data = Db::table('tp_book')->where('id','in','[1,2,23]')->column('title');
    
    $data = Db::table('tp_book')->whereIn('id','1,2,34')->column('title');
    $data = Db::table('tp_book')->whereNotIn('id','1,2,3,4,44')->column('title');
    return json($data);
  • Null 查詢字段是否(不)是Null

    // null、not null 查詢指定字段是否能夠爲Null/Not Null
    $data = Db::table('tp_access')->where('details','null')->column('user_id');
    $data = Db::table('tp_access')->where('details','notnull')->column('user_id');
    $data = Db::table('tp_access')->whereNull('details')->column('user_id');
    $data = Db::table('tp_access')->whereNotNull('details')->column('user_id');
    return json($data);
EXP:其它查詢

支持更復雜的查詢狀況 例如:

Db::name('user')->where('id','in','1,3,8')->select();

能夠改爲:

Db::name('user')->where('id','exp',' IN (1,3,8) ')->select();

exp查詢的條件不會被當成字符串,因此後面的查詢條件可使用任何SQL支持的語法,包括使用函數和字段名稱。

$data = Db::table('tp_access')->where('id','exp','in (1,2,3,4)')->column('user_id');// 快捷 ↓
$data = Db::table('tp_access')->whereExp('id','in (1,2,3,4)')->column('user_id');
// 等效於 ==> SELECT `user_id` FROM `tp_access` WHERE ( `id` in (1,2,3,4) )

$data = Db::table('tp_book')->whereExp('id','>=20 and user_id =88 ')->column('title');
$data = Db::table('tp_book')->whereExp('','id >=20 and user_id =88 ')->column('title');
// 等效於 ==> SELECT `title` FROM `tp_book` WHERE ( `id` >=20 and user_id =88 )
print_r($data);
時間查詢
  • 傳統查詢 where()

    where方法支持時間比較,例如:

    // 採用比較符號比較時間
    $data = Db::table('tp_one')->where('create_time','< time','2016-10-10 00:00:00')->select();
    // ==> SELECT * FROM `tp_one` WHERE `create_time` < '2016-10-10 00:00:00'
    // 在第二參數明確 time 的時候,第三個參數會自動按照完整的time格式填充(年-月-日 時:分:秒)
    
    // 時間區間查詢
    where('create_time', 'between time', ['2015-1-1', '2016-1-1']);

    第三個參數能夠傳入任何有效的時間表達式,會自動識別你的時間字段類型,支持的時間類型包括timestampsdatetimedateint

    區間查詢 whereTime()/wherebetween()/wherebetweenTime():

    // 採用whereTime()區間查詢時間 (whereTime()和between time 結果是同樣的,推薦後者)
    $data = Db::table('tp_one')
        ->where('create_time','between time',['2018-01-01','2019-01-01'])
        ->select();
    $data = Db::table('tp_one')
        ->whereTime('create_time',['2018-01-01','2019-01-01'])
        ->select();
    // ==> SELECT * FROM `tp_one` WHERE `create_time` BETWEEN '2018-01-01 00:00:00' AND '2019-01-01 00:00:00'
    // wherebetween() 也支持如上的區間Time查詢
    $data = Db::table('tp_one')
        ->whereBetween('create_time',['2018-01-01','2019-01-01'])
        ->select();
    // wherebetweenTime() 也是一個支持時間起始查詢函數
    $data = Db::table('tp_one')
        ->whereBetweenTime('create_time','2018-01-01','2019-01-01')
        ->select();
    // 若是第三個參數爲空則表明查詢當天(一天)

    whereTime()還支持時間便捷固定查詢:

    關鍵字 (whereTime()的第三個參數值) 說明
    today 今天
    yesterday 昨天
    week 本週
    last week 上週
    month 本月
    last month 上月
    year 本年
    last year 去年

    同時還支持指定的時間數據查詢;例如兩小時內就是:-2 hour

    whereBetweenTimeField()多時間(字)段查詢

    V5.1.17+版本開始,能夠支持對兩個時間字段的區間比較

    // 查詢有效期內的活動
    Db::name('event')
      ->whereBetweenTimeField('start_time','end_time')
        ->select();

    上面的查詢至關於

    // 查詢有效期內的活動
    Db::name('event')
      ->whereTime('start_time', '<=', time())
        ->whereTime('end_time', '>=', time())
        ->select();
聚合查詢

在應用中咱們常常會用到一些統計數據,例如當前全部(或者知足某些條件)的用戶數、全部用戶的最大積分、用戶的平均成績等等,ThinkPHP爲這些統計操做提供了一系列的內置方法,包括:

方法 說明
count 統計數量,參數是要統計的字段名(可選)
max 獲取最大值,參數是要統計的字段名(必須)
min 獲取最小值,參數是要統計的字段名(必須)
avg 獲取平均值,參數是要統計的字段名(必須)
sum 獲取總分,參數是要統計的字段名(必須)

聚合方法若是沒有數據,默認都是0,聚合查詢均可以配合其它查詢條件

V5.1.5+版本開始,聚合查詢能夠支持JSON字段類型(MySQL5.7+開始支持JSON)

count()統計數量: 能夠根據表的行數或根據字段的行數

$data = Db::table('tp_book')->count();
// ==> SELECT COUNT(*) AS tp_count FROM `tp_book`
$data = Db::table('tp_book')->count('id');
// ==> SELECT COUNT(`id`) AS tp_count FROM `tp_book`

max()/min()獲取最值:能夠根據字段名獲取字段列中最值;若是字段中的不是數值,函數會自動強制轉換,能夠經過定義第二參數爲「false」來取消強制轉換的行爲

// max()/min() 最值函數
$data = Db::table('tp_book')
    ->max('user_id');
// ==> SELECT MAX(`user_id`) AS tp_max FROM `tp_book`
$data = Db::table('tp_book')
    ->max('title');
$data = Db::table('tp_book')
    ->max('title',false); // 和↑條同做用,可是這條將不強制轉換,按照編碼進行
// ==> SELECT MAX(`title`) AS tp_max FROM `tp_book`

avg()平均值計算

$data = Db::table('tp_book')->avg('user_id');
// ==> SELECT AVG(`user_id`) AS tp_avg FROM `tp_book`

sum()求和計算

$data = Db::table('tp_book')->sum('user_id');
// ==> SELECT SUM(`user_id`) AS tp_sum FROM `tp_book`
子查詢
  • 使用fetchSql()方法,不執行SQL語句而是返回SQL語句,默認True

    $subQuery = Db::table('think_user')
        ->field('id,name')
        ->where('id', '>', 10)
        ->fetchSql(true)
        ->select();

    生成的subQuery結果爲:

    SELECT `id`,`name` FROM `think_user` WHERE `id` > 10
  • 使用buidSql()方法,返回SQL語句且不須要執行select()同時添加兩側括號

    $subQuery = Db::table('think_user')
        ->field('id,name')
        ->where('id', '>', 10)
        ->buildSql();

    生成的subQuery結果爲:

    ( SELECT `id`,`name` FROM `think_user` WHERE `id` > 10 )

在SQL語句中咱們須要用到子查詢的功能,就是利用SQL1語句的查詢結果給SQL2語句使用

原生SQL語句:(具有子查詢)

SELECT * FROM `tp_one` WHERE id in (SELECT uid FROM tp_two where gender = '男');

構造ThinkPHP的子查詢代碼:

$sql_1 = Db::table('tp_two')
    ->field('uid')
    // field()方法主要做用是標識要返回或者操做的字段,能夠用於查詢和寫入操做。
    ->where('gender','男')
    ->buildSql();
$sql = Db::table('tp_one')
    ->whereIn('id',$sql_1)
    ->select();
// ==> SELECT * FROM `tp_one` WHERE `id` = ( SELECT `uid` FROM `tp_two` WHERE `gender` = '男' )
// 這裏使用WhereIn出現的問題就是本來應該是 IN 卻變成了 = 符號

$sql_exp =  Db::table('tp_one')
    ->whereExp('id','IN'.$sql_1)
    ->select();
// ==> SELECT * FROM `tp_one` WHERE ( `id` IN( SELECT `uid` FROM `tp_two` WHERE `gender` = '男' ) )
// 因爲whereIn沒法正確的使用,因而採用whereExp()方法構造IN並使用鏈接符鏈接$sql_1

使用閉包構造子查詢

IN/NOT INEXISTS/NOT EXISTS之類的查詢能夠直接使用閉包做爲子查詢,例如:

Db::table('think_user')
    ->where('id', 'IN', function ($query) {
        $query->table('think_profile')->where('status', 1)->field('id');
    })
    ->select();
原生查詢
query()/讀操做

query方法用於執行SQL查詢操做,若是數據非法或者查詢錯誤則返回false,不然返回查詢結果數據集(同select方法)。

使用示例:

Db::query("select * from think_user where status=1");
execute()/寫操做

execute用於更新和寫入數據的sql操做,若是數據非法或者查詢錯誤則返回false,不然返回影響的記錄數。

使用示例:

Db::execute("update think_user set name='thinkphp' where status=1");
鏈式查詢-建議參考手冊
where
  • 表達式查詢:即以前的那些普通的多個表達式組合的查詢方式

    例如:where比較查詢、whereIn、whereLike……

  • 關聯數組查詢:等值AND和IN函數條件

    // Where數組關聯查詢能夠等值AND和IN函數條件
    $data = Db::table('tp_one')->where([
        'math'      =>  88,
        'chinese'   =>  88,
    ])->select();
    // ==> SELECT * FROM `tp_one` WHERE `math` = 88 AND `chinese` = 88
    $data = Db::table('tp_one')->where([
        'math'      =>  88,
        'chinese'   =>  [88,99,11],//等效於IN (88,99,11)
    ])->select();
    // ==> SELECT * FROM `tp_one` WHERE `math` = 88 AND `chinese` IN (88,99,11)
  • 索引數組查詢:批量設置查詢條件

    // Where索引數組查詢
    $data = Db::table('tp_one')->where([
          ['math','<=','88'],
          ['chinese','>','90'],
      ])->select();
    // ==>  SELECT * FROM `tp_one` WHERE `math` <= 88 AND `chinese` > 90

    若是須要事先組裝數組查詢條件,可使用:

    $map[] = ['name','like','think'];
    $map[] = ['status','=',1];

    數組的各類查詢方式其實能夠多樣應用

  • 字符串傳遞

    使用字符串條件直接查詢和操做,例如:

    Db::table('think_user')->where('type=1 AND status=1')->select();

    最後生成的SQL語句是

    SELECT * FROM think_user WHERE type=1 AND status=1

這裏的where多樣運用須要開發者按照本身的喜愛和實際的開發需求決定如何使用;若是沒法運用就直接使用原生!

table

table方法主要用於指定操做的數據表。

Db::table('think_user')->where('status>1')->select(); // 指定數據表
Db::table('db_name.think_user')->where('status>1')->select(); //指定數據庫和表

若是須要對多表進行操做,能夠這樣使用:

Db::field('user.name,role.title')
->table('think_user user,think_role role')
->limit(10)->select();

爲了儘可能避免和mysql的關鍵字衝突,能夠建議使用數組方式定義,例如:

Db::field('user.name,role.title')
->table(['think_user'=>'user','think_role'=>'role'])
->limit(10)->select();

使用數組方式定義的優點是能夠避免由於表名和關鍵字衝突而出錯的狀況。

alias

alias用於設置當前數據表的別名,便於使用其餘的連貫操做;例如join方法等。

示例:

Db::table('think_user')
->alias('a')
->join('think_dept b ','b.user_id= a.id')
->select();

最終生成的SQL語句相似於:

SELECT * FROM think_user a INNER JOIN think_dept b ON b.user_id= a.id
field

field方法主要做用是標識要返回或者操做的字段,能夠用於查詢和寫入操做。

  • 指定字段:field()能夠在查詢數據、添加數據中均可以運用到,可是在添加中不得違背SQL的規範

    $data = Db::table('tp_book')
        ->where('user_id','>','50')
        ->field('title')
        ->select();
    // ==> SELECT `title` FROM `tp_book` WHERE `user_id` > 50
  • 使用SQL函數

    $data = Db::table('tp_one')
        ->field('SUM(math)')
        ->select();
    // ==> SELECT SUM(math) FROM `tp_one`
  • field方法的參數能夠支持數組,例如:

    Db::table('think_user')->field(['id','title','content'])->select();
  • 字段排除:排除某一個或多個字段,須要在field()的第二參數設置爲True默認Falst

    // 排除某一個或多個字段,須要在field()的第二參數設置爲True  不支持跨表和join操做。
    $data = Db::table('tp_book')->field('user_id',true)->select();
    // ==> SELECT `id`,`title` FROM `tp_book`
    $data = Db::table('tp_book')->field('id,user_id',true)->select();
    // ==>   SELECT `title` FROM `tp_book`
strict

strict方法用於設置是否嚴格檢查字段名,用法以下:(建議true)

// 關閉字段嚴格檢查
Db::name('user')
    ->strict(false)
    ->insert($data);

注意,系統默認值是由數據庫配置參數fields_strict決定,所以修改數據庫配置參數能夠進行全局的嚴格檢查配置,以下:

// 關閉嚴格檢查字段是否存在
'fields_strict'  => false,

若是開啓字段嚴格檢查的話,在更新和寫入數據庫的時候,一旦存在非數據表字段的值,則會拋出異常。

limit

limit()用於限制輸入輸出的數據條數,也能夠指定輸出的行數範圍

// limit() 能夠指定輸出的條數、行數範圍、輸入的條數限制
$data = Db::table('tp_book')->field('title')->limit(3)->select(); //限制條數
// ==>  SELECT `title` FROM `tp_book` LIMIT 3
$data = Db::table('tp_book')->field('title')->limit(3,3)->select(); // 實現分頁
// ==> SELECT `title` FROM `tp_book` LIMIT 3,3 //limit(起始行,條數)

limit方法也能夠用於寫操做,例如更新知足要求的3條數據:

Db::table('think_user')
->where('score',100)
->limit(3)
->update(['level'=>'A']);
page

page()方法主要用於分頁查詢。

// page() 分頁查詢
$data = Db::table('tp_book')->field('title')->page(1,3)->select();
// =>  SELECT `title` FROM `tp_book` LIMIT 0,3
$data = Db::table('tp_book')->field('title')->page(2,3)->select();
// =>  SELECT `title` FROM `tp_book` LIMIT 3,3

page()直接是規定第一頁第二頁便可,page()方法自動實現LIMIT的分頁補充……而當LIMIT和page同時出現的話,page接受的一個參數表明頁數,而limit的參數表明輸出的每頁條數。(具體見手冊)

order

order()方法用於對操做的結果排序或者優先級限制。(參考手冊)

Db::table('think_user')
->where('status', 1)
->order('id', 'desc')
->limit(5)
->select();
 SELECT * FROM `think_user` WHERE `status` = 1 ORDER BY `id` desc LIMIT 5

若是沒有指定desc或者asc排序規則的話,默認爲asc

支持使用數組對多個字段的排序,例如:

Db::table('think_user')
->where('status', 1)
->order(['order','id'=>'desc'])
->limit(5)
->select();

最終的查詢SQL多是

SELECT * FROM `think_user` WHERE `status` = 1 ORDER BY `order`,`id` desc LIMIT 5

對於更新數據或者刪除數據的時候能夠用於優先級限制

Db::table('think_user')
->where('status', 1)
->order('id', 'desc')
->limit(5)
->delete();

生成的SQL

DELETE FROM `think_user` WHERE `status` = 1 ORDER BY `id` desc LIMIT 5

V5.1.7+版本開始,若是你須要在order方法中使用mysql函數的話,必須使用下面的方式:

Db::table('think_user')
->where('status', 1)
->orderRaw("field(name,'thinkphp','onethink','kancloud')")
->limit(5)
->select();
group

GROUP方法一般用於結合合計函數,根據一個或多個列對結果集進行分組 。(參考手冊)

group方法只有一個參數,而且只能使用字符串。

例如,咱們都查詢結果按照用戶id進行分組統計:

Db::table('think_user')
    ->field('user_id,username,max(score)')
    ->group('user_id')
    ->select();

生成的SQL語句是:

SELECT user_id,username,max(score) FROM think_score GROUP BY user_id

也支持對多個字段進行分組,例如:

Db::table('think_user')
    ->field('user_id,test_time,username,max(score)')
    ->group('user_id,test_time')
    ->select();

生成的SQL語句是:

SELECT user_id,test_time,username,max(score) FROM think_user GROUP BY user_id,test_time
having

HAVING方法用於配合group方法完成從分組的結果中篩選(一般是聚合條件)數據。

having方法只有一個參數,而且只能使用字符串,例如:

Db::table('think_user')
    ->field('username,max(score)')
    ->group('user_id')
    ->having('count(test_time)>3')
    ->select();

生成的SQL語句是:

SELECT username,max(score) FROM think_score GROUP BY user_id HAVING count(test_time)>3
相關文章
相關標籤/搜索