1. 程式人生 > 其它 >ThinkPhP $map用法

ThinkPhP $map用法

ThinkPHP內建了非常靈活的查詢方法,可以快速的進行資料查詢操作,查詢條件可以用於CURD等任何操作,作為where方法的引數傳入即可,下面來一一講解查詢語言的內涵。查詢方式ThinkPHP可以支援直接使用字串作為查詢條件,但是大多數情況推薦使用索引陣列或者物件來作為查詢條件,因為會更加安全。

一、使用字串作為查詢條件

這是最傳統的方式,但是安全性不高

例如:
$User = M("User"); // 例項化User物件

$User->where('type=1 AND status=1')->select(); 最後生成的SQL語句是
SELECT * FROM think_user WHERE type=1 AND status=1 

二、使用陣列作為查詢條件

$User = M("User"); // 例項化User物件

$condition['name'] = 'thinkphp';

$condition['status'] = 1;

// 把查詢條件傳入查詢方法

$User->where($condition)->select(); 最後生成的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(); 最後生成的SQL語句是
SELECT * FROM think_user WHERE `name`='thinkphp' OR `account`='thinkphp' 

三、使用物件方式來查詢 (這裡以stdClass內建物件為例)

$User = M("User"); // 例項化User物件

// 定義查詢條件

$condition = new stdClass();

$condition->name = 'thinkphp';

$condition->status= 1;

$User->where($condition)->select(); 最後生成的SQL語句和上面一樣
SELECT * FROM think_user WHERE `name`='thinkphp' AND status=1

使用物件方式查詢和使用陣列查詢的效果是相同的,並且是可以互換的,大多數情況下,我們建議採用陣列方式更加高效,後面我們會以陣列方式為例來講解具體的查詢語言用法。

表示式查詢上面的查詢條件僅僅是一個簡單的相等判斷,可以使用查詢表示式支援更多的SQL查詢語法,並且可以用於陣列或者物件方式的查詢(下面僅以陣列方式為例說明),

查詢表示式的使用格式:

$map['欄位名'] = array('表示式','查詢條件');

表示式不分大小寫,支援的查詢表示式有下面幾種,分別表示的含義是:

  • EQ 等於(=)
  • NEQ 不等於(<>)
  • GT 大於(>)
  • EGT 大於等於(>=)
  • LT 小於(<)
  • ELT 小於等於(<=)
  • LIKE 模糊查詢
  • [NOT] BETWEEN (不在)區間查詢
  • [NOT] IN (不在)IN 查詢
  • EXP 表示式查詢,支援SQL語法
表示式	含義
示例如下:
EQ :等於(=)
例如:
$map['id'] = array('eq',100); 和下面的查詢等效

$map['id'] = 100; 表示的查詢條件就是 id = 100

NEQ: 不等於(<>)
例如:

$map['id'] = array('neq',100); 表示的查詢條件就是 id <> 100

GT:大於(>)
例如:

$map['id'] = array('gt',100); 表示的查詢條件就是 id > 100

EGT:大於等於(>=)
例如:

$map['id'] = array('egt',100); 表示的查詢條件就是 id >= 100

LT:小於(<)
例如:

$map['id'] = array('lt',100); 表示的查詢條件就是 id < 100

ELT: 小於等於(<=)
例如:

$map['id'] = array('elt',100); 表示的查詢條件就是 id <= 100

[NOT] LIKE: 同sql的LIKE
例如:

$map['name'] = array('like','thinkphp%'); 查詢條件就變成 name like 'thinkphp%'
如果配置了DB_LIKE_FIELDS引數的話,某些欄位也會自動進行模糊查詢。例如設定了:

'DB_LIKE_FIELDS'=>'title|content' 的話,使用

$map['title'] = 'thinkphp'; 查詢條件就會變成 name like '%thinkphp%'
支援陣列方式,例如

$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, 查詢條件支援字串或者陣列,例如:

$map['id'] = array('between','1,8'); 和下面的等效:

$map['id'] = array('between',array('1','8')); 查詢條件就變成 id BETWEEN 1 AND 8

[NOT] IN: 同sql的[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); // 根據條件儲存修改的資料 1

快捷查詢新版增加了快捷查詢方式,可以進一步簡化查詢條件的寫法,例如:

一、實現不同欄位相同的查詢條件

$User = 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` < 10)

$map['id'] = array(array('gt',3),array('lt',10), 'or') ; 得到的查詢條件是: (`id` > 3) OR (`id` < 10)

$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';

$User->where($map)->select(); 最後得到的查詢條件就成了:
( `id` != 1 ) AND ( `name` = 'ok' ) AND ( status=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','%thinkphp%');

$where['_logic'] = 'or';

$map['_complex'] = $where;

$map['id'] = array('gt',1); 查詢條件是
( id > 1) AND ( ( name like '%thinkphp%') OR ( title like '%thinkphp%') )
複合查詢使用了_complex作為子查詢條件來定義,配合之前的查詢方式,可以非常靈活的制定更加複雜的查詢條件。
很多查詢方式可以相互轉換,例如上面的查詢條件可以改成:

$where['id'] = array('gt',1);

$where['_string'] = ' (name like "%thinkphp%") OR ( title like "%thinkphp") '; 最後生成的SQL語句是一致的。 

統計查詢在應用中我們經常會用到一些統計資料,例如當前所有(或者滿足某些條件)的使用者數、所有使用者的最大積分、使用者的平均成績等等,ThinkPHP為這些統計操作提供了一系列的內建方法,包括:

  • Count 統計數量,引數是要統計的欄位名(可選)
  • Max 獲取最大值,引數是要統計的欄位名(必須)
  • Min 獲取最小值,引數是要統計的欄位名(必須)
  • Avg 獲取平均值,引數是要統計的欄位名(必須)
  • Sum 獲取總分,引數是要統計的欄位名(必須)
方法	說明
用法示例:
$User = M("User"); // 例項化User物件 獲取使用者數:

$userCount = $User->count(); 或者根據欄位統計:

$userCount = $User->count("id"); 獲取使用者的最大積分:

$maxScore = $User->max('score'); 獲取積分大於0的使用者的最小積分:

$minScore = $User->where('score>0')->min('score'); 獲取使用者的平均積分:

$avgScore = $User->avg('score'); 統計使用者的總成績:

$sumScore = $User->sum('score'); 並且所有的統計查詢均支援連貫操作的使用。

定位查詢ThinkPHP支援定位查詢,但是要求當前模型必須繼承高階模型類才能使用,可以使用getN方法直接返回查詢結果中的某個位置的記錄。

例如:
獲取符合條件的第3條記錄:
$User->where('score>0')->order('score desc')->getN(2); 獲取符合條件的最後第二條記錄:

$User-> where('score>80')->order('score desc')->getN(-2); 獲取第一條記錄:

$User->where('score>80')->order('score desc')->first(); 獲取最後一條記錄:

$User->where('score>80')->order('score desc')->last();

SQL查詢ThinkPHP內建的ORM和ActiveRecord模式實現了方便的資料存取操作,而且新版增加的連貫操作功能更是讓這個資料操作更加清晰,但是ThinkPHP仍然保留了原生的SQL查詢和執行操作支援,為了滿足複雜查詢的需要和一些特殊的資料操作,SQL查詢的返回值因為是直接返回的Db類的查詢結果,沒有做任何的處理。主要包括下面兩個方法:

1、query方法 用法 query($sql,$parse=false)

引數
query(必須):要查詢的SQL語句
parse(可選):是否需要解析SQL 返回值
如果資料非法或者查詢錯誤則返回false
否則返回查詢結果資料集(同select方法)
query 執行SQL查詢操作

使用示例:
$Model = new Model() // 例項化一個model物件 沒有對應任何資料表

$Model->query("select * from think_user where status=1"); 
如果你當前採用了分散式資料庫,並且設定了讀寫分離的話,
query方法始終是在讀伺服器執行,因此query方法對應的都是讀操作,而不管你的SQL語句是什麼。 

2、execute方法 用法 execute($sql,$parse=false)

引數
query(必須):要執行的SQL語句
parse(可選):是否需要解析SQL 返回值 如果資料非法或者查詢錯誤則返回false
否則返回影響的記錄數
execute用於更新和寫入資料的sql操作

使用示例:
$Model = new Model() // 例項化一個model物件 沒有對應任何資料表

$Model->execute("update think_user set name='thinkPHP' where status=1"); 
如果你當前採用了分散式資料庫,並且設定了讀寫分離的話,
execute方法始終是在寫伺服器執行,因此execute方法對應的都是寫操作,而不管你的SQL語句是什麼。 

3、其他技巧

自動獲取當前表名
通常使用原生SQL需要手動加上當前要查詢的表名,如果你的表名以後會變化的話,那麼就需要修改每個原生SQL查詢的sql語句了,針對這個情況,系統還提供了一個小的技巧來幫助解決這個問題。

例如:

$model = M("User");

$model->query('select * from __TABLE__ where status>1'); 
我們這裡使用了__TABLE__ 這樣一個字串,系統在解析的時候會自動替換成當前模型對應的表名,
這樣就可以做到即使模型對應的表名有所變化,仍然不用修改原生的sql語句。

4.支援連貫操作和SQL解析

新版對query和execute兩個原生SQL操作方法增加第二個引數支援,
表示是否需要解析SQL (預設為false 表示直接執行sql ),
如果設為true 則會解析SQL中的特殊字串 (需要配合連貫操作)。

例如,支援 如下寫法:

$model->table("think_user")

->where(array("name"=>"thinkphp"))

->field("id,name,email")

->query('select %FIELD% from %TABLE% %WHERE%',true); 
其中query方法中的%FIELD%、%TABLE%和%WHERE%字串會自動替換為同名的連貫操作方法的解析結果SQL,支援的替換字串包括:
%FIELD% field %TABLE% table %DISTINCT% distinct %WHERE% where %JOIN% join %GROUP% group %HAVING% having %ORDER% order %LIMIT% limit %UNION% union
替換字串	對應連貫操作方法

5.動態查詢藉助PHP5語言的特性,

ThinkPHP實現了動態查詢,包括下面幾種: getBy 根據某個欄位的值查詢資料 例如,getByName,getByEmail getFieldBy 根據某個欄位查詢並返回某個欄位的值 例如,getFieldByName top 獲取前多少條記錄(需要高階模型支援)

一、getBy動態查詢

該查詢方式針對資料表的欄位進行查詢。

例如,User物件擁有id,name,email,address 等屬性,那麼我們就可以使用下面的查詢方法來直接根據某個屬性來查詢符合條件的記錄。
$user = $User->getByName('liu21st');

$user = $User->getByEmail('[email protected]');

$user = $User->getByAddress('中國深圳'); 暫時不支援多資料欄位的動態查詢方法,請使用find方法和select方法進行查詢。

二、getFieldBy動態查詢

針對某個欄位查詢並返回某個欄位的值,

例如
$user = $User->getFieldByName('liu21st','id'); 表示根據使用者的name獲取使用者的id值。 

三、top動態查詢

ThinkPHP還提供了另外一種動態查詢方式,就是獲取符合條件的前N條記錄(和定位查詢一樣,也要求當前模型類必須繼承高階模型類後才能使用)。

例如,我們需要獲取當前使用者中積分大於0,積分最高的前5位使用者 :

$User-> where('score>80')->order('score desc')->top5(); 要獲取積分的前8位可以改成:

$User-> where('score>80')->order('score desc')->top8(); 5

子查詢新版新增了子查詢支援,有兩種使用方式:

1、使用select方法

當select方法的引數為false的時候,表示不進行查詢只是返回構建SQL,

例如:
// 首先構造子查詢SQL

$subQuery = $model->field('id,name')->table('tablename')->group('field')->where($where)->order('status')->select(false); 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() 構造的子查詢SQL可用於TP的連貫操作方法,例如table where等。

原作者路徑

第二路徑

鄭重宣告:本文版權歸原作者所有,轉載文章僅為傳播更多資訊之目的,如作者資訊標記有誤,請第一時間聯絡我修改或刪除,多謝。