溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ThinkPHP中數據查詢的基本原則是什么

發布時間:2021-01-16 10:10:36 來源:億速云 閱讀:202 作者:小新 欄目:編程語言

小編給大家分享一下ThinkPHP中數據查詢的基本原則是什么,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

盡量不要使用數組條件查詢

大部分混亂的查詢語法都是使用了數組查詢導致的,而5.1的數組條件查詢用法又和5.0是完全不同的,如果你習慣了5.0的數組查詢方式,建議你閱讀下這篇文章:「 教你使用5.1的數組對象查詢 」。

下面可能是很多新手比較容易犯的一個查詢錯誤。

$where['id'] = ['in', '1,2,3'];
User::where($where)->select();

顯然,這個查詢思維深受老版本的影響。5.1版本的查詢語法相比較5.0來說,更加對象化,下面的這種才是正確的用法。

$where['id'] = [1,2,3];
User::where($where)->select();

也許是因為PHP的數組太好用的緣故,很多人對數組查詢條件樂此不疲(或者是對象焦慮?)。但如果你正確的使用查詢構造器以及配合模型的相關特性,可以讓你的查詢邏輯變得更清晰,也更加易于維護。

而且,在一些較為復雜的查詢條件下,你無法使用數組完成查詢,例如下面的查詢用法。

User::where('id', '>', 100)
    ->whereOr('id', '<', 10)
    ->where('name', 'like', 'think%')
    ->whereColumn('name', 'nickname')
    ->when('80'== $condition, function ($query) {
        $query->where('score', '>', 80)->limit(10);
    })->select();

所以,除非你很清楚5.1的數組查詢用法,否則請盡量不要用數組條件查詢了。

安全使用字符串查詢條件

在使用字符串查詢條件的時候,如果存在外部變量,請務必使用參數綁定,并最好使用whereRaw方法,該方法可以和其它的查詢構造器方法混合使用。

User::whereRaw("id = :id AND name = :name", [
        'id' => [$id, \PDO::PARAM_INT] , 
        'name' => $name
    ])->where('status', 1)
    ->order('id', 'desc')
    ->select();

對于一些比較在意性能的查詢,你也可以直接使用query或者execute方法,但同樣也要注意參數的安全以及考慮不同數據庫的移植問題。

Db::query("select * from think_user where id=? AND status=?", [8, 1]);
Db::execute("update think_user set name=:name where status=:status", ['name' => 'thinkphp', 'status' => 1]);

對使用了SQL函數的查詢采用Raw機制

如果你的查詢里面包含了SQL函數,那么請使用whereRaw(或者whereExp)、orderRaw或者fieldRaw方法。

User::whereExp('nickname', "= CONCAT(name, '-', id)")
    ->orderRaw("field(name,'thinkphp', 'kancloud')")
    ->fieldRaw('id,SUM(score)')
    ->select();

合理運用閉包,但不要濫用

閉包查詢在查詢構造器中有一些特殊用途,但如非必要,也無需濫用。

閉包查詢的典型使用場景包括下面幾個。

條件查詢中通常都用閉包來表示一組條件查詢。

User::when($condition, function ($query) {
    // 滿足條件后執行
    $query->where('score', '>', 80)->limit(10);
}, function ($query) {
    // 不滿足條件執行
    $query->where('score', '>', 60);
})->select();

在一些子查詢中經常會用到閉包。

User::whereIn('id', function ($query) {
    $query->table('profile')
        ->where('name', 'like', 'think%')
        ->field('id');
})->select();

生成一組閉合的查詢條件

User::where('id', '>', 100)
    ->whereOr(function($query) {
        $query->where('name', 'like', 'think%')
        ->whereColumn('name', 'nickname');
    })->select();

在這個查詢用法中,閉包里面的查詢條件會在兩邊加上括號而成為一個閉合的查詢條件。

在很多的關聯預載入查詢中可以通過閉包來進行關聯數據的篩選。

User::with(['profile' => function($query) {
$query->field('user_id,email,phone');
}])->select([1,2,3]);

盡量復用你的查詢條件

所有的查詢條件應該做到一處定義多處復用,例如封裝到模型的方法里面,尤其不要直接把一堆復雜的查詢條件寫到你的控制器代碼,否則一旦業務調整,滿世界的搜索代碼改變你的查詢條件將會是一場噩夢。

你也許在官方的手冊或者一些教程中看到很多在控制器里面直接封裝查詢條件的寫法,但那僅僅是出于方便展示用法的需要,并不可取。

在一些中大型的應用架構設計中,通常會把模型分成數據層、邏輯層和服務層,控制器只會調用服務層方法。而查詢邏輯則基本上被封裝到邏輯層里面,數據層僅僅是做模型的各種定義。

而在簡單的應用里面,也可以采用PHP的Trait機制來實現代碼的復用機制。

用查詢范圍或搜索器簡化查詢

如果你使用模型查詢的話,把你的查詢條件盡量封裝到查詢范圍或者搜索器方法里面,查詢范圍和搜索器的區別主要在于查詢范圍比較適合定義一組(多個字段)查詢條件,如果要調用多個查詢范圍需要多次調用,而搜索器比較適合定義一個字段(其實并非絕對)的查詢條件,只需要調用一次withSearch方法。

使用查詢范圍和搜索器的例子。

<?php
namespace app\index\model;
use think\Model;
class User extends Model
{
    public function scopeVip($query)
    {
        $query->where('user_type', 'vip')
            ->where('status', 1)
            ->field('id,name');
    }
    
    public function searchAgeAttr($query, $age)
    {
        $query->where('age','>',$age);
    }    
    
    public function searchScoreAttr($query, $score)
    {
        $query->where('score','<=',$score)->where('score', '>' ,0);
    }    
}

控制器代碼

<?php
namespace app\index\controller;
use think\Controller;
use think\Request;
class index extends Controller
{
    public function index(Request $request)
    {
        // 查詢VIP會員
        User::vip()->select();
        // 查詢年齡和分數
        User::withSearch(['age,'score''], $request->param())->select();
    }
}

在控制器代碼中,我們只關注業務邏輯本身,而不需要關注這個邏輯內部的查詢條件是什么。更詳細的關于搜索器和查詢范圍的內容可以參考官方手冊。

看完了這篇文章,相信你對“ThinkPHP中數據查詢的基本原則是什么”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女