上一篇我們掌握了基本的數據CURD方法,但更多的情況下面,由於業務邏輯的差異,CURD操作往往不是那麼簡單,尤其是複雜的業務邏輯下面,這也是ActiveRecord模式的不足之處。 ThinkPHP的查詢語言配合連貫操作可以很好解決複雜的業務邏輯需求,本篇我們首先來深入了解下框架的查詢語言。
介紹
ThinkPHP內建了非常靈活的查詢方法,可以快速的進行資料查詢操作,查詢條件可以用於讀取、更新和刪除等操作,主要涉及到where方法等連貫操作即可,無論是採用什麼資料庫,你幾乎採用一樣的查詢方法(個別資料庫例如Mongo在表達式查詢方面會有所差異),系統幫你解決了不同資料庫的差異性,因此我們把框架的這個查詢方式稱之為查詢語言。查詢語言也是ThinkPHP框架的ORM亮點,讓查詢操作更簡單易懂。下面來一一講解查詢語言的內涵。
查詢方式
ThinkPHP可以支援直接使用字串作為查詢條件,但是大多數情況建議使用索引數組或物件作為查詢條件,因為會更加安全。一、使用字串作為查詢條件這是最傳統的方式,但是安全性不高,例如:
$User = M("User"); // 實例化User物件
$User->where(' type=1 AND status=1')->select();
最後產生的SQL語句是
SELECT * FROM think_user WHERE type=1 AND * FROM think_user WHERE type=1 AND status=1
字串使用與使用新版提供的字串條件的安全預處理機制,暫且不再細說。二、使用陣列作為查詢條件這種方式是最常用的查詢方式,例如:$User = M("User"); // 實例化User物件$condition['name'] = 'thinkphp' ;$condition['status'] = 1;// 把查詢條件傳入查詢方法$User->where($condition)->select(); 最後產生的SQL語句是最後產生的SQL語句是最後產生的SQL語句SELECT * FROM think_user WHERE `name`='thinkphp' AND status=1
如果進行多字段查詢,那麼字段之間的默認邏輯關係是邏輯與AND,但是用下面的規則可以更改默認的邏輯判斷,透過使用_logic 定義查詢邏輯:
$User = M("User"); // 實例化User物件
$condition['name'] = 'thinkphp =
$condition['account'] 'thinkphp';$condition['_logic'] = 'OR';// 把查詢條件傳入查詢方式$User->where($condition)->select();$User->where($condition)->select();
最後生成的SQL語句是
SELECT * FROM think_user WHERE `name`='thinkphp' OR `account`='thinkphp'
=使用物件方式來查詢內建"User"); // 實例化User物件
// 定義查詢條件
$condition = new stdClass();
$condition->name = 'thinkphp';
$condition->name = 'thinkphp';
$condition->name = 'thinkphp';
$User->where($condition)->select();
最後產生的SQL語句和上面一樣
SELECT * FROM think_user WHERE`name`='thcom)使用物件使用方式查詢和使用陣列查詢的效果是相同的,而且是可以互換的,大多數情況下,我們建議採用陣列方式更有效率。
表達式查詢
上面的查詢條件只是一個簡單的相等判斷,可以使用查詢表達式支援更多的SQL查詢語法,也是ThinkPHP查詢語言的精髓,查詢表達式的使用格式:$map ['字段名'] = array('表達式','查詢條件');表達式不分大小寫,支援的查詢表達式有下面幾種,分別表示的含義是:
表達式
意義
EQ 等於(=)
NEQ 不等於()
LT 小於(ELT 小於等於(
LIKE 模糊查詢
[NOT] BETWEEN ( 表達式查詢,支援SQL語法
範例如下: EQ :等於(=)
例如:$map['id'] = array('eq',100);
和下面的查詢等效
$map['id'] = 100;表示的查詢條件為id = 100NEQ: 不等於()
例如:$map['id'] = array('neq',100);所表示的查詢條件就是比(>)例如:
例如:
如果配置了DB_LIKE_FIELDS參數的話,某些欄位也會自動進行模糊查詢。例如設定了:
$map['title'] = 'thinkphp';
查詢條件就會變成title'] = 'thinkphp';
查詢條件就會變成title like '%title like'
支援陣列方式,例如$map['a'] =array('like',array('%thinkphp%','%tp'),'OR');
$map['b'] =array('notlike',array('%thinkphp%','%tp'),'AND');
產生的查詢條件是:
(a like '%thinkphp%' OR a like '%tp ') AND (b not like '%thinkphp%' AND b not like '%tp')
[NOT] BETWEEN :同sql的 [not] between,查詢條件支援或數組,例如:$com ['id'] = array('between','1,8');
與下列的等價:
$map['id'] = array('between',array('1',' 8'));
查詢條件就變成id BETWEEN 1 AND 8[NOT] IN: 同註的[not] in ,查詢條件支援字串或數組,例如:
$map['id'] = array('not in','1,5,8');
和下面的等價:
$map['id'] = array('not in',array('1','5' ,'8'));
查詢條件就變成id NOT IN (1,5, 8)EXP:表達式,支援更複雜的查詢情況
例如:$map['id'] = array( 'in','1,3,8');可以改成:
$map['id'] = array('exp',' IN (1,3,8) ');
exp查詢的條件不會被當成字串,所以後面的查詢條件可以使用任何SQL支援的語法,包括使用函數和欄位名稱。查詢運算式不僅可用於查詢條件,也可用於資料更新,例如:
$User = M("User"); // 實例化User物件
// 要修改的資料物件屬性賦值
$ data['name'] = 'ThinkPHP';
$data['score'] = array('exp','score+1');// 使用者的點數加1
$User->where(' id=5')->save($data); // 依照條件保存修改的資料
快速查詢
從3.0版本開始,增加了捷徑查詢方式,可以進一步簡化查詢條件的寫法,例如:一、實作不同欄位相同的查詢條件
$User = M("User"); // 實例化User物件
$map = M("User"); // 實例化User物件
$map['name|title'] = 'thinkphp';
// 把條件傳入查詢方法
$User->where($map)->select();
查詢條件變成
name= 'thinkphp' OR title = 'thinkphp'
二、實作不同的不同欄位查詢條件
$User = M("User"); // 實例化User物件
$map['status&title'] =array('1','thinkphp','_multi'=>true);
// 把查詢條件傳入查詢方法
$User->where($map)->select();
'_multi'=>true必須加在數組的最後,表示當前是多條件匹配,這樣查詢條件就變成
status= 1 AND title = 'thinkphp'
,查詢字段支援更多的,例如:
$map['status&score&title'] =array('1',array('gt','0'),'thinkphp','_multi'=>true);
查詢條件變成
status= 1 AND score >0 AND title = 'thinkphp'
注意:快速查詢方式「|」及「&」不能同時使用。
區間查詢
ThinkPHP支援某個欄位的區間查詢,例如:
$map['id'] = array(array('gt',1),array('lt',10)) ;
得到的查詢條件是:
(`id` > 1) AND (`id`
$map['id'] = array(array('gt',3),array(' lt',10), 'or') ;
得到的查詢條件是: (`id` > 3) OR (`id`
$map['id'] = array(array('neq ',6),array('gt',3),'and');
得到的查詢條件是:(`id` != 6) AND (`id` > 3)
最後一個可以是AND、 OR或XOR運算符,如果不寫,預設是AND運算。
區間查詢的條件可以支援普通查詢的所有表達式,也就是說類似LIKE、GT和EXP這樣的表達式都可以支援。另外區間查詢還可以支援更多的條件,只要是針對一個欄位的條件都可以寫在一起,例如:
$map['name'] = array(array('like','%a%') , array('like','%b%'), array('like','%c%'), 'ThinkPHP','or');
最後的查詢條件是:
(`name` LIKE '%a%') OR (`name` LIKE '%b%') OR (`name` LIKE '%c%') OR (`name` = 'ThinkPHP')
查詢的主體還是採用數組方式查詢,只是加入了一些特殊的查詢支持,包括字符串模式查詢(_string)、複合查詢(_complex)、請求字符串查詢(_query),混合查詢中的特殊查詢每次查詢只能定義一個,由於採用數組的索引方式,索引相同的特殊查詢會被覆蓋。一、字串模式查詢(採用_string 作為查詢條件)
數組條件還可以和字串條件混合使用,例如:$User = M("User"); // 實例化User物件
$map ['id'] = array('neq',1);
$map['name'] = 'ok';
$map['_string'] = 'status=1 AND score>10';string'] = 'status=1 AND score>10';
$User->where($map)->select();
最後得到的查詢條件就成了:
( `id` != 1 ) AND ( `name`= 'ok' =1 AND score>10 )
二、請求字串查詢方式請求字串查詢是一種類似URL傳參的方式,可以支援簡單的條件相等判斷。
$map['id'] = array('gt','100');
$map['_query'] = 'status=1&score=100&_logic=or';
得到的查詢條件是:
`id`>100 AND (`status` = '1' OR `score` = '100')
三、複合查詢複合查詢相當於封裝了一個新的查詢條件,然後併入原來的查詢條件之中,所以可以完成比較複雜的查詢條件組裝。
例如:$where['name'] = array('like', '%thinkphp%');
$where['title'] = array('like','%thphp%);
很多查詢方式可以互相轉換,例如上面的查詢條件可以改成:
$where['id'] = array('gt',1);
在應用中我們經常會用到一些統計數據,例如當前所有(或滿足某些條件)的用戶數、所有用戶的最大積分、用戶的平均成績等等,ThinkPHP為這些統計操作提供了一系列的內建方法,包括:
方法
說明
Count 統計數量,參數是要統計的欄位名稱(選用)
的統計數字Min 取得最小值,參數是要統計的欄位名稱(必須)
Avg 取得平均值,參數是統計的欄位名稱(必須)
Sum
用法範例:
$User = M("User"); // 實例化User物件
取得使用者數:
$userCount = $User
();$userCount = $User);
$userCount = $User->count("id");取得使用者最大的積分:$maxScore = $User->max('score');取得積分大於0的使用者的最小積分:$minScore = $User->where('score>0')->min('score');取得使用者的平均分數:$avgScore = $User->avg('score') ;統計使用者的總分:$sumScore = $User->sum('score');且所有的統計查詢都支援連貫運算的使用。 SQL查詢ThinkPHP內建的ORM和ActiveRecord模式實現了方便的資料存取操作,而且新版增加的連貫操作功能更是讓這個資料操作更加清晰,但是ThinkPHP仍然保留了原生的SQL和查詢執行操作支持,為了滿足複雜查詢的需要和一些特殊的資料操作,SQL查詢的回傳值因為是直接傳回的Db類的查詢結果,沒有做任何的處理。主要包括以下兩種方法:1、query方法 query 執行SQL查詢作業 用法 query($
parse(選用):是否需要解析SQL
否則回傳影響的記錄數
Mode對應任何資料表$Model->execute("update think_user set name='thinkPHP' where status=1");如果你目前採用了分散式資料庫,並且設定了讀寫分離的話,execute方法始終的話是在寫伺服器執行,所以execute方法對應的都是寫入操作,而不管你的SQL語句是什麼。 動態查詢
借助PHP5語言的特性,ThinkPHP實現了動態查詢,核心模型的動態查詢方法包括以下幾種:
舉例查詢資料 例如,getByName,getByEmail
getFieldBy 根據欄位查詢並傳回某個欄位的值 例如,getFieldByName
一、getBy針對資料表的查詢該方式進行查詢。例如,User物件擁有id,name,email,address 等屬性,那麼我們就可以使用下面的查詢方法來直接根據某個屬性來查詢符合條件的記錄。
$user = $User->getByName('liu21st');
$user = $User->getByEmail('liu21st@gmail.com');
$ ');
暫時不支援多重資料欄位的動態查詢方法,請使用find方法和select方法進行查詢。二、getFieldBy動態查詢針對某個欄位查詢並傳回某個欄位的值,例如
$userId = $User->getFieldByName('liu21st','id');
表示根據使用者的name取得使用者的id值。
子查詢
從3.0版本開始新增了子查詢支持,有兩種使用方式:1、使用select方法當select方法的參數為false的時候,表示不進行查詢只是返回構建SQL,例如:
// 先建構子查詢SQL
$subQuery = $model->field('id,name')->table('tablename')->group('field')->where($where) ->order('status')->select(false);
當select方法傳入false參數的時候,表示不執行目前查詢,而只是產生查詢SQL。 2.使用buildSql方法
$subQuery = $model->field('id,name')->table('tablename')->group('field')->where($where)->order(' status')->buildSql();
呼叫buildSql方法後不會進行實際的查詢操作,而只是產生該次查詢的SQL語句(為了避免混淆,會在SQL兩邊加上括號),然後我們直接在後續的查詢中直接調用。
// 利用子查詢查詢
$model->table($subQuery.' a')->where()->order()->select()
構造的子查詢可用於ThinkPHPSQL的連貫操作方法,例如table where等。
總結
本篇主要幫助我們了解如何進行資料的查詢,包括簡單查詢、表達式查詢、快速查詢、區間查詢、統計查詢,以及如何進行子查詢操作。後面我們也會詳細了解如何使用連貫操作進行更複雜的CURD操作。
以上是ThinkPHP3.1快速入門(3)查詢語言的內容,更多相關內容請關注PHP中文網(m.sbmmt.com)