在thinkphp中,ORM指的是“對(duì)象關(guān)系映射”,是為方便開發(fā)者使用數(shù)據(jù)庫(kù)開發(fā)的一個(gè)存儲(chǔ)訪問層;ORM的主要用途是把對(duì)象模型表示的對(duì)象映射到基于sql的關(guān)系模型數(shù)據(jù)庫(kù)結(jié)構(gòu)中去。
本教程操作環(huán)境:Windows7系統(tǒng)、thinkphp v5.1版、Dell G3電腦。
thinkphp中的orm
ORM的全稱是Object Relational Mapping,即對(duì)象關(guān)系映射
-
O(Object) 對(duì)象,在項(xiàng)目中就是實(shí)體,更加精確的來說就是數(shù)據(jù)Model,也可以說持久化類。
立即學(xué)習(xí)“PHP免費(fèi)學(xué)習(xí)筆記(深入)”;
-
R(Relation) 關(guān)系數(shù)據(jù)
-
M (Mapping)映射,將對(duì)象映射到關(guān)系數(shù)據(jù),將關(guān)系數(shù)據(jù)映射到對(duì)象的過程。
更加直觀理解就是,ORM 就是以O(shè)OP思想,產(chǎn)生增刪改查SQL語句。
ThinkPHP的ORM是為方便開發(fā)者使用數(shù)據(jù)庫(kù)開發(fā)的一個(gè)存儲(chǔ)訪問層,框架設(shè)計(jì)圖片如下:
主要用途是:把對(duì)象模型表示的對(duì)象映射到基于sql的關(guān)系模型數(shù)據(jù)庫(kù)結(jié)構(gòu)中去。
當(dāng)改變這個(gè)對(duì)象自身的屬性或者調(diào)用該對(duì)象的方法時(shí),相對(duì)應(yīng)的是執(zhí)行某些sql語句。
這樣子編寫代碼的人員就可以更好地編寫業(yè)務(wù)邏輯,而非重復(fù)地編寫增刪改查sql語句。
thinkphp中的運(yùn)用示例
TP框架中關(guān)于數(shù)據(jù)庫(kù)操作有兩個(gè)模塊:
-
數(shù)據(jù)庫(kù)
-
模型
tp中的數(shù)據(jù)庫(kù)模塊
引用一句文檔的特性描述
拆分為Connection(連接器)/Query(查詢器)/Builder(SQL生成器)
-
Connection連接器主要是用來連接數(shù)據(jù)庫(kù)的,可以使用不同的驅(qū)動(dòng)連接不同類型的數(shù)據(jù)庫(kù)。
-
Query查詢器則是用來運(yùn)行sql語句,處理結(jié)果,映射到數(shù)據(jù)集中。
-
Builder生成器則是用來把我們傳遞進(jìn)去的條件、排序等轉(zhuǎn)換成sql語句。
在這3個(gè)步驟中,我們可以知道,如果有運(yùn)用到ORM思想抽象映射的,那就只可能是Query查詢器模塊,但是我們可以細(xì)查TP文檔中關(guān)于數(shù)據(jù)集的描述。
它更多的是封裝提供對(duì)于數(shù)據(jù)的處理方法,比如:
(以下是從文檔復(fù)制過來的 ?一小部分)
toArray?????將數(shù)據(jù)集的數(shù)據(jù)轉(zhuǎn)為數(shù)組 merge???合并其它數(shù)據(jù) diff????比較數(shù)組,返回差集 flip????交換數(shù)據(jù)中的鍵和值 intersect???比較數(shù)組,返回交集 keys????返回?cái)?shù)據(jù)中的所有鍵名 pop?刪除數(shù)據(jù)中的最后一個(gè)元素 shift???刪除數(shù)據(jù)中的第一個(gè)元素 unshift?在數(shù)據(jù)開頭插入一個(gè)元素 reduce??通過使用用戶自定義函數(shù),以字符串返回?cái)?shù)組
但是卻沒有提供反向映射的關(guān)系操作,比如我們操作數(shù)據(jù)集,自動(dòng)更新數(shù)據(jù)庫(kù)中的數(shù)據(jù)。
所以在我的理解中,數(shù)據(jù)庫(kù)模塊中的ORM思想并不多,重點(diǎn)還是要了解和運(yùn)用模型
tp中的模型
定義模型文件
namespace?appindexmodel; use?thinkModel; //?設(shè)置類名?需要遵循轉(zhuǎn)換規(guī)則,蛇形轉(zhuǎn)為大駝峰 class?User?extends?Model { ????//?設(shè)置主鍵字段名 ????protected?$pk?=?'u_id'; ????//?開啟自動(dòng)維護(hù)時(shí)間戳字段?(什么時(shí)間插入?什么時(shí)間更新) ????protected?$autoWriteTimestamp?=?true; ????//?軟刪除?開啟之后?刪除數(shù)據(jù)只是用一個(gè)字段來標(biāo)識(shí)為刪除狀態(tài)?方便查詢、備份等 ????use?SoftDelete; ????protected?$deleteTime?=?'delete_time'; }
以上代碼比文檔中第一章節(jié)模型初始化要多了一些內(nèi)容,這是為了突出 模型可以完成很多功能
這也是ORM出現(xiàn)的原因:將sql的執(zhí)行,抽象映射為面向?qū)ο缶幊讨械膶?duì)象。
我們可以理解為:表中的一行數(shù)據(jù),代表我們代碼中new一個(gè)對(duì)象,改變對(duì)象,則自動(dòng)更新表中對(duì)應(yīng)的行。
使用模型
演示的代碼是比較簡(jiǎn)單的,實(shí)際是可以很靈活的
比如查詢用非主鍵的條件來查詢、查詢多行記錄等等
<?php // *******快速查詢、更新******* // 查詢主鍵=1的數(shù)據(jù) $user = User::get(1); // 然后更改它的name字段為新的值 $user->name?=?'thinkphp'; //?保存,自己去數(shù)據(jù)庫(kù)給我更新吧~ $user->save(); //?*******插入新的一行數(shù)據(jù)******* //?新建一個(gè)對(duì)象(相對(duì)應(yīng)的操作就是新創(chuàng)建一行) $user?=?new?User; //?設(shè)置字段的值??有多個(gè)字段就多個(gè)設(shè)置 $user->name=?'thinkphp'; //?保存,自己去插入吧~ $user->save();
誤區(qū)
看了使用之后,很多初學(xué)者就開始寫代碼了,然而卻使用了不太正確的方式。
① model只當(dāng)為Db類用
雖然model可以看成db類的超集,但是如果只是把它當(dāng)成簡(jiǎn)單的DB類使用,而不是使用ORM思想去編寫。那么就沒什么必要使用它了。。
如果使用不對(duì),不僅不能提高效率,反而會(huì)影響自己。(比如代碼規(guī)范不統(tǒng)一、新增表還要新增對(duì)應(yīng)的模型文件等等)
代碼演示:
<?php $userModel = new User(); // 這里就相當(dāng)于初始化Db類 $userOneInfo = $userModel->where(['u_id'?=>?1])->find(); $userTwoInfo?=?$userModel->where(['u_id'?=>?2])->find(); //?...?執(zhí)行其他邏輯?比如判斷上下級(jí)?操作權(quán)限等等 //?業(yè)務(wù)需求不只是讀取用戶的數(shù)據(jù)這么簡(jiǎn)單 //?還要扣除余額(就是更新數(shù)據(jù)庫(kù)) $userOneRes?=?$userModel->where(['u_id'?=>?1])->update(['u_balance'?=>?'xxxx']); //?...?執(zhí)行其他邏輯
看到這里,先停下來思考一下。。你的代碼有出現(xiàn)過這樣子的嗎?
我相信還是有些人會(huì)這樣子用的吧!因?yàn)槲乙郧耙彩沁@樣子用的。
那么我們看看正確的使用方法(我認(rèn)為的,如果覺得不對(duì)或者有更好的,歡迎評(píng)論交流)
<?php $userOneInfo = User::get(1); // 這里演示使用非主鍵條件查詢的情況!! // 查詢一個(gè)1用戶的下級(jí)出來 $userTwoInfo = User::get(function($query){ $query->where(['p_uid'?=>?1]); }); //?...?執(zhí)行其他邏輯?比如判斷上下級(jí)?操作權(quán)限等等 //?業(yè)務(wù)需求不只是讀取用戶的數(shù)據(jù)這么簡(jiǎn)單 //?還要扣除余額(就是更新數(shù)據(jù)庫(kù)) $userOneInfo->u_balance?=?0; $userOneRes?=?$userOneInfo->save(); $userTwoInfo->u_balance?=?0; $userTwoRes?=??$userTwoInfo->save(); //?...?執(zhí)行其他邏輯
因?yàn)橐粋€(gè)對(duì)象映射一條數(shù)據(jù),所以我們?cè)诓僮魍瑯觲here條件的數(shù)據(jù),直接操作對(duì)象就可以了, 就不用反復(fù)編寫where u_id =1更新, u_id = 1 要?jiǎng)h除
使用模型,還有很多用處,(得益于開源團(tuán)隊(duì)的奉獻(xiàn),為我們封裝了大量的功能)
比如:?
?– 用戶表新增一條數(shù)據(jù),另一個(gè)附屬表也要用該用戶id初始化一行。
?– 自動(dòng)轉(zhuǎn)換數(shù)據(jù)格式(儲(chǔ)存時(shí)間戳,查詢出來為2019-7-13 19:53:04格式)。
?– 自動(dòng)校驗(yàn)數(shù)據(jù),自動(dòng)完成數(shù)據(jù)(操作的時(shí)候默認(rèn)取操作人ip 權(quán)限等儲(chǔ)存)。
?– 關(guān)聯(lián)查詢(TP中非常強(qiáng)大的功能,在模型中定義好與另一個(gè)模型的關(guān)系,比如店鋪表中的u_id 可以用來查詢出店鋪所屬用戶的信息? 相當(dāng)于店鋪模型和用戶模型的關(guān)聯(lián)? 自動(dòng)join數(shù)據(jù) 合并 返回給我們使用)
?– 等等
總結(jié)
ORM是一種思想,概念,代表 對(duì)象-關(guān)系映射(數(shù)據(jù)庫(kù)-對(duì)象 映射)ORM使得對(duì)數(shù)據(jù)的操作抽象為對(duì)對(duì)象的操作。要學(xué)會(huì)思想的改變,利用好框架提供的特性,編寫更好地代碼。TP中的模型非常強(qiáng)大,封裝了大量的邏輯。
【相關(guān)教程推薦:thinkphp框架】