<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] # 介紹 Yii提供了一個[yii\\db\\Query](http://www.yiichina.com/doc/api/2.0/yii-db-query)讓我們方便地進行數據查詢 這不是模型,而是一個查詢器,基本兼容各種主流關系型數據庫 示例: ~~~php $user = (new \yii\db\Query())->select(['id', 'name'])->from('user')->one(); print_r($user); ~~~ 和db->createCommand('select id,name from user limit 1')的區別就是:createCommand是直接寫一個SQL語句來創建命令的,但Query是根據參數和數據庫類型生成不同了最終SQL語句,所以用Query會提升項目的數據庫可遷移性,而且代碼看起來也比較好閱讀 下面是一些常用的查詢方式 # all 查詢指定表的所有記錄 ~~~php $query = new \yii\db\Query(); // SELECT * FROM user $users = $query->from('user')->all(); print_r($users); ~~~ 就是實例化一個`\yii\db\Query`對象來執行查詢,`from`方法用于指定表 * * * # where 指定條件 ~~~php $query = new \yii\db\Query(); // SELECT * FROM user WHERE status = 1 $users = $query->from('user')->where(['status' => 1])->all(); print_r($users); ~~~ 其中這個where方法的條件寫法將在后面陸續擴展增強演示,各種條件都能表達,除非我寫漏 # one 查詢單條記錄 根據ID查一條記錄 ~~~php $query = new \yii\db\Query(); // SELECT * FROM user WHERE id = 1 $data = $query->from('test')->where(['id' => 1])->one(); print_r($data); ~~~ **注意one方法不會limit 1,而只是在編程語言級別獲取第1條,所以比較適合條件本身就只有唯一的情況** 提示:后面我的演示代碼都不再new了,直接以$query這個變量作為查詢構造器開始演示,以上代碼只是方便你直接復制調試 # 判斷記錄是否存在 ~~~php $query = new \yii\db\Query(); //SELECT EXISTS(SELECT * FROM user WHERE type = 2) $exists = $query->from('user')->where(['default_patient_id' => 2])->exists(); if($exists == true){ //... } ~~~ # select 指定查詢字段 ~~~php // SELECT id,name FROM user $query->select(['id', 'name'])->from('user')->all(); ~~~ # 定義字段別名 查找年齡為50的用戶的id,名字和郵箱 ~~~php // SELECT id,email AS mail FROM user $query->select(['id', 'mail' => 'email'])->from('user')->all(); ~~~ 其中注意第2個字段`'mail' => 'email'`,意思是查詢email字段,但返回值時以mail作為key # orderBy排序,limit限制篩選記錄數 查找最新注冊的一個用戶 ~~~php //SELECT * FROM user ORDER BY add_time DESC limit 1 $query->from('user')->orderBy(['add_time' => SORT_DESC])->limit(1)->one(); ~~~ `orderBy`設定排序字段,以`數組`作參數,`key是要排序的字段`,排序方式是PHP自帶常量`SORT_ASC`或`SORT_DESC` `limit`用于限制輸出幾條記錄 需要增加更多排序字段則增加更多`KEY => VALUE`的數組單元,比如`orderBy(['id' => SORT_ASC, 'age' => SORT_DESC])` **SORT\_ASC**和**SORT\_DESC**是PHP自帶的常量 # 獲取SQL語句 ~~~php $query = new \yii\db\Query(); $query->from('user')->where(['id' => 999]); //注意不要加all或one echo $query->createCommand()->sql; //獲取 參數化的 SQL原型 echo $query->createCommand()->rawSql; //最終會生成的SQL語句 ~~~ 在還沒有執行all或one之前不會進行查詢操作,此時再通過createCommand方法創建一個`yii\db\Command`對象,再訪問這個對象的rawSql就能得到SQL語句 `\yii\db\Query`只是一個查詢命令的**構造器**,底層最終其實還是由createCommand創建一個`yii\db\Command`來執行的) # 獲取執行過的語句 在獲取執行過的SQL方面,我并沒有在Yii里看到簡單快速的方式來獲取,大家平時調試比較需要,所以我繼承yii\\db\\Connection封裝了一個方法來獲取,[參考代碼](https://github.com/kk8686/xoa/blob/master/server/common/ext/db/Connection.php) 使用方法是:下載這個類的代碼放到你的項目中,按照你的需求修改命名空間,調用示例 `echo Yii::$app->db->getLastSqls();`獲取上次執行的一條SQL語句 `echo Yii::$app->db->getLastSqls(3);`獲取上次執行的三條SQL語句 `echo Yii::$app->db->getLastSqls(2, 'from`user`');`獲取上兩條包含'from`user`'關鍵字的SQL語句 # 多個and條件 查找年齡為60的女性用戶 ~~~php // SELECT * FROM user WHERE age = 50 AND sex = 2 $query->from('user')->where([ 'age' => 50, 'sex' => 2, //假設是女性的類型標識 ])->all(); ~~~ 和大多數框架一樣,`where`的參數是數組,每一對`KEY => VALUE`就是一個`AND條件`單元了 好了后面我的代碼不執行one或all了,為了讓大家方便地直接復制代碼看到生成的SQL我都用**createCommand()->rawSql**了 # in條件 查找ID為1,2,3并且年齡為30的用戶 ~~~php // SELECT * FROM user WHERE age = 30 AND id in(1, 2, 3) echo $query->from('user')->where([ 'age' => 30, 'id' => [1, 2, 3], ])->createCommand()->rawSql; ~~~ 要實現in條件語句則為這個字段的值傳入數組即可 # count 統計 統計(年齡為50)的(男性 和 人妖)的用戶數量`假設sex的1=男,2=女,3=人妖` ~~~php // SELECT count(*) FROM user WHERE type = 1 $query->from('user')->where(['type' => 1])->count(); ~~~ # 大于小于條件比較+offset分頁 以10個用戶顯示一頁的話,查找出第2頁未成年用戶 ~~~php // SELECT * FROM user WHERE age < 18 OFFSET 10 LIMIT 10 echo $query->from('user')->where(['<', 'age', 18])->offset(10)->limit(10)->createCommand()->rawSql; ~~~ 這時候你發現where的條件的每一個元素都沒有key了,第一個參數表示比較邏輯符,第二個是比較字段,第三個是比較的值 # 大于等于,小于等于條件比較 查詢所有成年人 ~~~php // SELECT * FROM user WHERE age >= 18 echo $query->from('user')->where(['>=', 'age', 18])->createCommand()->rawSql; ~~~ # like查詢 ~~~php // SELECT * FROM user WHERE name LIKE '%abc%' echo $query->from('user')->where(['like', 'name', 'abc'])->createCommand()->rawSql; // SELECT * FROM user WHERE name LIKE '%abc%' AND name LIKE '%xyz%' echo $query->from('user')->where(['like', 'name', ['abc', 'xyz']])->createCommand()->rawSql; // SELECT * FROM user WHERE name LIKE '%abc' echo $query->from('user')->where(['like', 'name', '%abc'])->createCommand()->rawSql; // SELECT * FROM user WHERE name LIKE 'abc%' echo $query->from('user')->where(['like', 'name', 'abc%'])->createCommand()->rawSql; // SELECT * FROM user WHERE name NOE LIKE '%abc%' echo $query->from('user')->where(['not like', 'name', 'abc'])->createCommand()->rawSql; ~~~ # between篩選和group by分組結果 查詢各性別的未成年用戶 ~~~php // SELECT * FROM user WHERE age BETWEEN 1 AND 18 GROUP BY sex echo $query->from('user')->where(['between', 'age', 1, 18])->groupBy(['sex']) ->createCommand()->rawSql; ~~~ 要groupBy多個字段的話就是`['sex', 'country']`這樣,繼續增加數組元素就好了 # having二級篩選 查詢某分類的文章發表數量超過100的用戶 ~~~php // SELECT count(user_id) as arc_count FROM article WHERE category = 33 HAVING arc_count > 100 $query->select(['arc_count' => 'count(user_id)'])->from('article')->where(['category' => 33])->having('arc_count > 100')->createCommand()->rawSql; ~~~ # or邏輯條件構造 查詢名字為lily或者性別為男的用戶 ~~~php // SELECT * FROM user WHERE name = 'abc' OR sex = 1 $name = 'lily'; echo $query->from('user')->where([ 'or', ['name' => 'abc'], ['sex' => 1], ])->createCommand()->rawSql; ~~~ 之前where方法傳數組是以鍵值對來表達`key1=val1 and key2 = val2`這樣的 但你要表達復雜邏輯關系時,數組的`第一個元素`必須先聲明你是`什么邏輯關系`,比如`or` 再以`第二個元素`表達or`左邊的條件`是什么,然后`第三個元素`表達or`右邊的條件`是什么 這里要注意第二和第三個參數,第一個是**字符串**,表達了邏輯關系,第二和第三個為什么是數組?很簡單的,因為邏輯關系的左邊和右邊可能會有很多條件,比如 ~~~sql (a=1 and b=2) or (右邊那一塊...) ~~~ 所以左邊和右邊都可能是多個條件,意味著如果左右邊都有多條件的話就應該這樣寫了: ~~~php where([ 'or', [ //or左邊的條件塊 'name' => 'abc', ['<', 'age', 18], //當不是 字段 = 值 的條件而是大于小于之類的比較時,請注意這里要用數組了,前面介紹過大于小于,between那些都可以這樣用 'xxx' => 6, ], [ //or右邊的條件塊 'sex' => 1, 'email' => 'abc@dd.com', ], ]) ~~~ # and、or條件嵌套 查詢用戶表**(年齡為$age)并且(性別為女 或者 2014年注冊)**的用戶 ~~~php // SELECT * FROM user WHERE age = 33 AND (sex = 2 OR add_time > '2014-01-01 00:00:00') echo $query->from('user')->where([ 'and', ['age' => 33], [ 'or', ['sex' => 2], ['>', 'add_time', '2014-01-01 00:00:00'], ], ])->createCommand()->rawSql; ~~~ 回到數組的條件傳達方式,之前說過,where條件的數組第一維度,第一元素是邏輯關鍵字,第二元素是邏輯的左邊條件,第三元素是邏輯的右邊條件 而如果右邊條件又是一個多條件表達式,那么則用數組表達,這個數組還是第一元素是邏輯關鍵字,第二元素是左邊邏輯,第三元素是你懂的邏輯 那么反過來,邏輯左邊條件是復合型條件的話又怎么寫第二元素呢? # 追加and條件 ~~~php $title = 'xx'; $query->from('user')->where(['status' => 2]); if($title){ //重點 $query->andWhere(['like', 'title', $title]); } //SELECT * FROM user WHERE status AND title LIKE '%xx%' echo $query->createCommand()->rawSql; ~~~ 這樣后面andWhere的會跟前面where的組合成and邏輯,如果要換or那就用orWhere方法也可以 # 追加or條件 和andWhere道理是一樣的 ~~~php $title = 'xx'; $query->from('user')->where(['status' => 2]); if($title){ //重點 $query->orWhere(['like', 'title', $title]); } //SELECT * FROM user WHERE status OR title LIKE '%xx%' echo $query->createCommand()->rawSql; ~~~ # 自動過濾空值條件 你曾經可能經常寫這樣的代碼: ~~~php if($location){ $where['location'] = $location; } ~~~ 這樣的判斷邏輯在很多程序里都有,yii提供了這樣的辦法: ~~~php $category = 0; $location = ''; // SELECT * FROM user WHERE (category = 0 AND size = 33) AND name LEKE '%xx%' echo $query->from('user')->filterWhere([ 'category_id' => $category, 'location' => $location, 'size' => 33, ])->andWhere(['like', 'name', 'xx'])->createCommand()->rawSql; ~~~ 由于location是**空字符串**所以該字段的條件不會生成,只會生成其它非空字符串的條件 不過如果還是很喜歡自己寫SQL的話那請一定要做好參數綁定工作防注入!(參數綁定方法可以自己抽時間另外學習yii官方的教程) # 表別名、左聯接查詢以及聯接表別名的使用 查詢所有文章的標題和發布人的名稱 ~~~php // SELECT * a.title as title, u.name as username FROM article as a LEFT JOIN user as u ON u.id = a.user_id echo $query->select([ 'title' => 'a.title', 'username' => 'u.name', ])->from(['a' => 'article'])->leftJoin(['u' => 'user'], 'u.id = a.user_id')->createCommand()->rawSql; ~~~ # 更新積分+1或-1什么的 這個要靠[yii\\db\\Expression](http://www.yiichina.com/doc/api/2.0/yii-db-exception)來實現 ~~~php $expression = new \yii\db\Expression('score + 9999'); echo $query->createCommand() ->update('user', ['score' => $expression]) ->rawSql; // UPDATE `user` SET `score` = score + 9999; ~~~ # 批量查詢 ->大數據維護處理或統計 (哈哈,說得好高大上~~~反正這數據就是大,數量多!) 有沒有過這樣的經歷,某類數據運營一年半年后產生了上千萬條記錄,且不這么說,就是上百萬條吧 然后這個數據的A字段是一個復合數據,里面保存了一些具體的信息,比如里面包含了10個別的地方的ID集 然后某天的產品需求造成程序要根據這些ID集的數量來進行查詢,那總不能count這個字段啊 因為它對于MYSQL而言就是一個字符串而已,要查詢就要where這個數據的數量是否大于指定值來查詢了 而且還要搞個索引來優化查詢速度,沒辦法,那就要在別的專用查詢表或這個表上加一個xxx\_count這樣的字段 然后將所有現存數據的A字段ID集個數統計一下存入到xxx\_count字段以便查詢。 這是一種需求,別的還有比如說簡單地就是查出所有XXX字段大于多少的用戶,坑爹了有時候就算你分表了 在前面的需求和這個需求的情況下你都能遇到一個問題:PHP內存不足,不能一下子讀出所有的記錄來處理。試過了吧? 然后你的辦法可能就是做一些分頁查詢控制,比如第一次查先查1000條,處理完再查第2000條…做完一次再刷新,做完一次再刷新…... 或者還有別的流程,反正就是要你很麻煩地去搭建代碼 Yii提供了底層的分頁查詢處理,不用你再寫這些大數據轉換的非核心邏輯代碼。下面引用官方文檔的代碼足矣: ~~~php use yii\db\Query; $query = (new Query())->from('user') ->orderBy('id'); foreach($query->batch() as $users) { //這樣會先查出100條記錄放到$users里,在第二次for循環的時候再查第二百條,第三次就查第三百條…但關于這個100條如何控制數量變成1000條等,暫時未在文檔中找到控制參數,然而這個問題不大,畢竟最終會遍歷整個表。除了數據維護,其實前端要為用戶統計一些數據的時候,也避免了先查出所有記錄一齊遍歷統計的麻煩,統計一批數據就丟棄一批,再查下一批 } foreach ($query->each() as $user) { //用each時每次for循環都會查詢下一條出來 } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看