在app
目錄下建立Model
目錄,便可建立模型文件php
定義一個和數據庫表相匹配的模型react
use think\Model; class User extends Model { }
User
會自動匹配對於數據庫中的數據表tp_user
sql
模型命名後綴,是爲了防止關鍵字衝突,能夠開啓應用類後綴:建立
Class UserModel
thinkphpuse think\Model; class UserModel extends Model { //指向數據表 protected $name = 'user'; protected $table = 'tp_user'; }
模型類的定義須要去除表前綴,採用駝峯式命名首字母大寫數據庫
tp_user ==> User tp_user_type ==> UserType
建立於數據表相匹配的模型類後,能夠在使用User::*
方法來調用數據庫進行操做json
namespace app\controller; use think\facade\Db; use app\model; class DataTest { public function index() { $user = model\User::select(); return json($user); } }
模型中默認的主鍵爲id
,也能夠在模型類中設置主鍵字段名$pk
數組
protected $pk = 'uid';
在控制器中調用模型操做,發生重名能夠設置別名app
use app\model\User as UserModel;
模型類中能夠定義指向數據庫表函數
protected $table = 'tp_user'; //包含前綴 protected $name = 'user'; //不含前綴
模型類初始化操做(控制器也有),可是必須設置static
靜態方法性能
protected static funtion init() { echo "初始化"; }
模型設置屬性:
屬性 | 描述 |
---|---|
name | 指向數據表名(無前綴),默認爲當前模型名 |
table | 數據表 |
suffix | 數據表後綴(默認爲空) |
pd | 設置數據表主鍵字段名(默認爲id ) |
connection | 數據庫鏈接(默認加載數據庫配置database.php ) |
query | 模型使用的查詢類名稱 |
field | 指定容許操做的字段(支持數組) |
schema | 模型對應數據表字段和類型 |
type | 模型須要自動轉換的字段和類型 |
strict | 是否嚴重區分字段大小(默認true) |
disuse | 數據表廢棄字段 |
模型的數據字段和對應的數據表字段是對應的,默認會自動獲取(以及類型),自動獲取的過程會加一次查詢操做(浪費資源),thinkphp支持自定義字段信息。
$schema = [ '[字段名]' => '[字段類型]'; ]
schema
須要定義整個數據表字段,對單個字段定義須要自動轉換的類型可使用type
若是須要廢棄(忽略)數據表中的字段,可使用$disuse
來定義
protected $disuse = [‘type’,'status'];
獲取數據
$user = User::find(1); echo $user->create_time; echo $user->name;
因爲模型類實現了ArrayAccess
接口,因此能夠當成數組使用。
$user = User::find(1); echo $user['create_time']; echo $user['name'];
若是你是在模型內部獲取數據的話,須要改爲:
$user = $this->find(1); echo $user->getAttr('create_time'); echo $user->getAttr('name');
模型賦值、 實例化
給模型對象賦值
$user = new User() ; $user->table = 'tp_user'; $user->score = 100 ;
上述代碼會將模型對象打包賦值給$user
,能夠對其封裝的模型對象進行操做「修改器」
同時也可使用
$data['name'] = 'thinkphp'; $data['score'] = 100; $user = new User($data);
或者使用
$user = new User(); $data['name'] = 'thinkphp'; $data['score'] = 100; $user->data($data);
data
方法支持使用修改器
$user = new User(); $data['name'] = 'thinkphp'; $data['score'] = 100; $user->data($data, true);
若是須要對數據進行過濾,可使用
$user = new User(); $data['name'] = 'thinkphp'; $data['score'] = 100; $user->data($data, true, ['name','score']);
表示只設置data
數組的name
和score
數據。
新增數據的最佳實踐原則:使用create
靜態方法新增數據,使用saveAll
批量新增數。
刪除的最佳實踐原則是:若是刪除當前模型數據,用delete
方法,若是須要直接刪除數,使用destroy
靜態方法。
更新的最佳實踐原則是:若是須要使用模型事件,那麼就先查詢後更新,若是不須要使用事件或者不查詢直接更新,直接使用靜態的Update
方法進行條件更新,如非必要,儘可能不要使用批量更新。
save()
模型數據的新增和數據庫的新增數據有所區別,數據庫的新增只是單純的寫入給定的數據,而模型的數據寫入會包含修改器、自動完成以及模型事件等環節,數據庫的數據寫入參考數據庫章節。
第一步:實例化模型對象
$user = new UserModel(); $user = new \app\model\UserModel();
第二步:新增數據
public function index() { $user = new model\UserModel(); $user->username = '諸葛大力'; $user->password = 'gouzaizai'; $user->gender = '女'; $user->email = 'chengguo@gmail.com'; $user->price = 100 ; $user->uid = 0000; $user->details = '000'; $user->save(); }
上述的只是一個普通方法,除此還有傳遞數據數組的方式
public function index() { $user = new model\UserModel(); $data = [ 'username' => '諸葛大力', 'password' => 'gouzaizai', 'gender' => '女', 'email' => 'chengguo@gmail.com', 'price' => 100 , 'uid' => 0000, 'details' => '000', ]; $user->save($data); }
allowField()
限制寫入容許字段$user // 限制只容許寫入‘username、password’字段 ->allowField(['username','password']) ->save($data);
replace()
新增實現REPLACE into
新增(修改新增)
$user->replace()->save($data);
若是$data
數據表已存在會更新;
REPLACE INTO `tp_user` SET `id` = 301 , `username` = '諸葛大力' , `password` = 'gouzaizai' , `gender` = '女' , `email` = 'chengguo@gmail.com' , `price` = 100 , `uid` = 0 , `details` = '000' , `create_time` = '2020-04-10 11:40:20.660840' , `update_time` = '2020-04-10 11:40:20.660840'
$user->id; $user->uid; ……
saveAll()
*能夠批量添數據,返回新增數組
$user = new User; $list = [ ['name'=>'thinkphp','email'=>'thinkphp@qq.com'], ['name'=>'onethink','email'=>'onethink@qq.com'] ]; $user->saveAll($list);
saveAll方法新增數據返回的是包含新增模型(帶自增ID)的數據集對象。
saveAll
方法新增數據默認會自動識別數據是須要新增仍是更新操做,當數據中存在主鍵的時候認爲是更新操做。
create()
*$user = UserModel::create([ 'username' => '李白', 'password' => '123', 'gender' => '男', 'email' => 'libai@163.com', 'price' => 100, 'details' => '123', 'uid' => 1011 ], ['username', 'password', 'details'], false);
參數 1 是新增數據數組,必選
參數 2 是容許寫入的字段,可選
參數 3 爲是否 replace 寫入,默認 false 爲 Insert 寫入
新增數據的最佳實踐原則:使用create
方法新增數據,使用saveAll
批量新增數據。
delete()
$user = new User(); $user->delete();
User::destroy(1); User::destroy([1,2,3]);
User::where('id',10)->delete();
User::destroy(function($query){ $query->where('id',10); });
刪除的最佳實踐原則是:若是刪除當前模型數據,用delete
方法,若是須要直接刪除數據,使用destroy
靜態方法。
使用find()
方法獲取數據,經過save()
方法提交修改
$user = new model\UserModel(); $data = [ 'username' => '諸葛大力', 'gender' => '女' ]; $user->find(305)->save($data);
使用where()
方法結合find()
方法設置查詢條件並獲取數據
$user = new model\UserModel(); $data = [ 'username' => '齊天大聖' ]; $user->where('username','孫悟空') ->find()->save($data);
save()
只會更新數據有區別的地方;強制使用save()
更新數據須要使用force()
Db::raw()
執行SQL函數方法一樣能夠實現更新
$user = model\UserModel::find(305); $user->price = Db::raw('price+10'); $user->save();
使用allowField()
方法,容許要更新的字段
$user = model\UserModel::find(305); $data = [ 'username' => '李白', 'password' => '123', 'gender' => '男', 'email' => 'libai@163.com', 'price' => 100, 'details' => '123', 'uid' => 1011 ]; $user->allowField(['username'])->save($data);
使用saveAll()
方法能夠批量修改數據,返回被修改數據集;批量saveAll()
更新只能夠經過主鍵來進行
靜態方法::update()
更新
$data = [ 'username=> '李白', 'password' => '123', 'gender' => '男', 'email' => 'libai@163.com', 'price' => 100, 'details' => '123', 'uid' => 1011 ]; model\UserModel::update($data,['id'=> 304],['username']);
參數 1 是數據數組,必選
參數 2 更新條件,可選
參數 3 是容許寫入的字段,可選
save()
模型的新增、更新都須要
save()
進行執行,具備自動識別;實例化模型後調用
save()
表示新增,查詢數據後調用save()
表示修改
更新的最佳實踐原則是:若是須要使用模型事件,那麼就先查詢後更新,若是不須要使用事件或者不查詢直接更新,直接使用靜態的Update
方法進行條件更新,如非必要,儘可能不要使用批量更新。
使用find()
經過主鍵查詢想要的數據(能夠在模型類中設置主鍵字段)
調用find()
方法是,若是數據不存在返回Null,使用findOrEmpty()
方法,數據不存返回空模型
使用isEmpty()
方法判斷是否爲空模型
使用where()
進行條件篩選查詢
使用select()
方法,查詢多條指定主鍵的字段,不指定就是所有字段
$user = model\UserModel::select([304,305]); foreach ($user as $key=>$value) { echo $value->username; }
支持查詢構造器的各類方法
getBy[字段名]
:能夠獲取對應字段的value(駝峯命名,字段首字母大寫)
$user = model\UserModel::getByUsername('李白');
支持max
min
sum
count
avg
等方法
UserModel::max('price');
支持使用chunk()
進行分批處理數據
User::chunk(100, function ($users) { foreach($users as $user){ // 處理user模型對象 } });
支持使用cursor()
方法進行遊標查詢,返回生成器對象
foreach(User::where('status', 1)->cursor() as $user){ echo $user->name; }
user
變量是一個模型對象實例。
模型查詢的最佳實踐原則是:在模型外部使用靜態方法進行查詢,內部使用動態方法查詢,包括使用數據庫的查詢構造器。
獲取器的做用是對模型實例的數據作出自動處理
每個獲取器對應模型的一個特殊方法,方法要求public
get[FieldName]Attr()
,FieldName爲數據表字段的駝峯轉換,定義了獲取器自動觸發
$model->field_name
$model->toArray()
getAttr
方法 $this->getAttr('field_name')
// 狀態值的轉換輸出 // 模型類 public function getStatusAttr($value) { $status = [-1=>'刪除' , 0=>'禁用' , 1=>'正常' , 2=>"待審覈"]; return $status[$value]; } // 控制端 $user = model\UserModel::find(19); return $user->status;
通俗理解:
在控制端正常的查看字段值,模型類定義一個獲取器(一個字段能夠對應一個模型類中的特殊方法獲取器方法)),獲取器就會對控制端的字段查詢進行獲取並進行自定義的處理方法。
獲取器還能夠定義數據表不存在的字段,在控制端用戶能夠正常的按照字段名讀取的方式來訪問
<?php namespace app\model; use think\Model; class User extends Model { public function getStatusTextAttr($value,$data) { $status = [-1=>'刪除',0=>'禁用',1=>'正常',2=>'待審覈']; return $status[$data['status']]; } }
獲取器方法的第二個參數傳入的是當前的全部數據數組。
咱們就能夠直接使用status_text字段的值了,例如:
$user = User::find(1); echo $user->status_text; // 例如輸出「正常」
這裏也就是爲了解決多種處理方法並規避衝突的寫法;由於若是獲取器定義之後就沒法在控制端獲原始的字段值,不過也還有另一種getData()
方法得到原始字段值:
$user = User::find(1); // 經過獲取器獲取字段 echo $user->status; // 獲取原始字段數據 echo $user->getData('status'); // 獲取所有原始數據 dump($user->getData());
能夠支持對模型使用動態獲取器,無需在模型類中定義獲取器方法,在控制端使用動態獲取器:
$user = model\UserModel::find(19) ->withAttr('status',function($value,$data){ $status = [ -1=>'刪除',0=>'禁用', 1=>'正常',2=>'待審覈' ]; return $status[$value]; }); echo $user->status;
withAttr
方法支持屢次調用,定義多個字段的獲取器。另外注意,withAttr
方法以後不能再使用模型的查詢方法,必須使用Db類的查詢方法。
模型修改器的左右:對模型設置對象的值進行處理
在新增數據的時候,能夠利用修改器對數據進行格式化、轉換等處理;處理數據新增,還有數據更新也可能觸發修改器
setFieldNameAttr()
ps:修改器只對模型方法有效
public function setEmailAttr($value) { return strtolower($value); }
$user = model\UserModel::create([ 'username' => '李白', 'password' => '123', 'gender' => '男', 'email' => 'LIBai@163.com', 'price' => 100, 'details' => '123', 'uid' => 1011 ], ['username', 'password', 'details','email'], false); echo $user->save();
在模型類建立一個封裝的查詢和寫入方法,有便於控制端調用
scope()
前綴scope
,後綴自定義,在調用時吧後綴當作參數便可。
public function scopeMale($query) { $query->where('gender','男') ->field('id,username,gender,email') ->limit(5); }
$user = model\UserModel::scope('male')->select(); return "<hr>".Db::getLastSql()."<hr>".$user;
public function scopeEmail($query, $value) { $query->where('email','like','%'.$value.'%'); }
$user = UserModel::scope('email','xiao')->select(); return "<hr>".Db::getLastSql()."<hr>".$user;
scope()
的第一個參數是調用的封裝方法,第二個參數是封裝方法能夠接收的數據
支持多個查詢封裝方法連綴調用
$user = UserModel::scope('email','xiao') ->scope('price',80) ->select(); return "<hr>".Db::getLastSql()."<hr>".$user;
在使用查找範圍
scope()
後,指定使用find()
select()
查詢;在模型類中的查詢封裝方法中可使用包括修改器、獲取器等在內的模型操做方法。
public function getGenderAttr($value,$data) { $gender = ['男'=>'純爺們','女'=>'小姑娘']; return $gender[$value]; } public function scopeMale($query) { $query->where('gender','男') ->field('id,username,gender,email') ->limit(5); }
支持在模型中設置globaScope
屬性,定義全局查找範圍
class User extends Model { // 定義全局的查詢範圍 protected $globalScope = ['status']; public function scopeStatus($query) { $query->where('status',1); } }
而後,執行下面的代碼:
$user = User::find(1);
最終的查詢條件會是
status = 1 AND id = 1
若是須要動態關閉全部的全局查詢範圍,可使用:
// 關閉全局查詢範圍 User::withoutGlobalScope()->select();
可使用withoutGlobalScope
方法動態關閉部分全局查詢範圍。
User::withoutGlobalScope(['status'])->select();
搜索器用於封裝字段或搜索標識的表達式,相似查找範圍
一個搜索器對應模型的一個特殊方法
search[FieldName]Attr()
User模型定義name
字段和時間字段的搜索器,可使用:
class User extends Model { public function searchNameAttr($query, $value, $data) { $query->where('name','like', $value . '%'); } public function searchCreateTimeAttr($query, $value, $data) { $query->whereBetweenTime('create_time', $value[0], $value[1]); } }
而後,咱們可使用下面的查詢
User::withSearch(['name','create_time'], [ 'name' => 'think', 'create_time' => ['2018-8-1','2018-8-5'], 'status' => 1 ])->select();
最終生成的SQL語句相似於
SELECT * FROM `think_user` WHERE `name` LIKE 'think%' AND create_time` BETWEEN '2018-08-01 00:00:00' AND '2018-08-05 00:00:00'
能夠看到查詢條件中並無status
字段的數據,所以能夠很好的避免表單的非法查詢條件傳入,在這個示例中僅能使用name
和create_time
條件進行查詢。
事實上,除了在搜索器中使用查詢表達式外,還可使用其它的任何查詢構造器以及鏈式操做。
例如,你須要經過表單定義的排序字段進行搜索結果的排序,可使用
class User extends Model { public function searchNameAttr($query, $value, $data) { $query->where('name','like', $value . '%'); if (isset($data['sort'])) { $query->order($data['sort']); } } public function searchCreateTimeAttr($query, $value, $data) { $query->whereBetweenTime('create_time', $value[0], $value[1]); } }
而後,咱們可使用下面的查詢
User::withSearch(['name','create_time', 'status'], [ 'name' => 'think', 'create_time' => ['2018-8-1','2018-8-5'], 'status' => 1, 'sort' => ['status'=>'desc'], ]) ->select();
最終查詢的SQL多是
SELECT * FROM `think_user` WHERE `name` LIKE 'think%' AND `create_time` BETWEEN '2018-08-01 00:00:00' AND '2018-08-05 00:00:00' ORDER BY `status` DESC
你能夠給搜索器定義字段別名,例如:
User::withSearch(['name'=>'nickname','create_time', 'status'], [ 'nickname' => 'think', 'create_time' => ['2018-8-1','2018-8-5'], 'status' => 1, 'sort' => ['status'=>'desc'], ]) ->select();
搜索器一般會和查詢範圍進行比較,搜索器不管定義了多少,只須要一次調用,查詢範圍若是須要組合查詢的時候就須要屢次調用
數據集直接繼承collection
類,和數據的數據集方式同樣、操做同樣。
參照官方技術文檔
系統支持自動寫入建立和更新的時間戳字段(默認會關閉),具體配置方法:
全局開啓:在database.php
文件中修改auto_timestamp
爲truely
在模型類中單獨開啓自動時間戳:$autoWriteTimestamp
class User extends Model { protected $autoWriteTimestamp = true; }
也或者單獨關閉自動時間戳
class User extends Model { protected $autoWriteTimestamp = false; }
配置開啓後會自動添加自動時間戳寫入create_time
和update_time
兩個
端,默認的類型是int,若是是時間類型,能夠設置以下
protected $autoWriteTimestamp = [自動時間戳字段]
同時也能夠自定義兩個自動時間戳:
protected $createTime = '[字段]'; protected $updateTime = '[字段]';
在模型類中定義readonly
屬性:靜態
protected $readonly = ['字段1','字段2',……]
動態設置制度字段:
$user->readonly(['字段1',……])->save();
系統能夠經過模型端設置寫入或讀取時對字段類型進行轉換type
php rotected $type = [ 'price' => 'integer', 'status' => 'boolean', ;
設置廢棄字段 $disuse
數據庫寫入JSON字段,直接經過數組方式便可完成:
data = [ 'username' => '李白', 'password' => '123', 'gender' => '男', 'email' => 'LIBai@163.com', 'price' => 100, 'details' => '123', 'list' => ['username'=>李白,'gender'=>'女'] ]; Db::table('tp_user') ->json(['list']) // 定義list字段爲json類型字段 ->insert($data)
查詢數據,須要轉換JSON數據格式:
Db::table('tp_user')->json(['list'])->find(288);
將JSON字段裏的數據做爲查詢條件
$user = Db::table('tp_user')->json(['list'])->where('list-username','李白')->find();
修改JSON字段數據
$data['list'] = ['username'=>'李白','gender'=>'男']; Db::table('tp_user')->json(['list'])->where('id',220)->update($data);
設置寫入JSON字段的字符字段:
protetced $json = ['list'];
使用模型方法新增JSON數據的字段
$user = new User; $user->name = 'thinkphp'; $user->info = [ 'email' => 'thinkphp@qq.com', 'nickname '=> '流年', ]; $user->save();
具體的請參考官方文檔JSON部分
在實際項目中,對數據頻繁使用刪除操做會致使性能問題,軟刪除的做用就是把數據加上刪除標,而不是真正的刪除,同時也便於須要的時候進行數據的恢復。
要使用軟刪除功能,須要引入SoftDelete
trait,例如User模型按照下面的定義就可使用軟刪除功能:
use SoftDelete ; rotected $deleteTime = 'delete_time';
delete_time
默認爲Null,類型爲時間戳類型,用於記錄數據的刪除時間。
肯定開啓軟刪除和字段後
// 軟刪除 User::destroy(1); // 真實刪除 User::destroy(1,true); $user = User::find(1); // 軟刪除 $user->delete(); // 真實刪除 $user->force()->delete();
軟刪除後系統會忽略該條數據,模型會自動屏蔽數據
使用withTrashed()
取消屏蔽軟刪除的數據
使用onlyTrashend()
能夠查詢被軟刪除的數據
使用restore()
能夠恢復被軟刪除的數據
若是須要強制刪除,須要使用force()
強制安排
執行增刪改查操做的時候,能夠同時出發一些事件來執行額外的操做;額外的操做事件能夠部署在構造方法中等待激活後執行;數據庫事件方法是Db::event('事件名','執行函數')
事件名 | 描述 |
---|---|
before_select | select 查詢前回調 |
before_find | find 查詢前回調 |
after_insert | insert 操做後回調 |
after_update | update 操做後回調 |
after_delete | delete 操做後回調 |
通常狀況下,數據庫事件卸載控制器端的初始化方法裏,有利於統一管理
public function initialize() { Db::event('before_select', function($query){ echo "執行了批量的查詢操做" }); }
事件 描述 事件方法名
after_read 查詢後 onAfterRead
before_insert 新增前 onBeforeInsert
after_insert 新增後 onAfterInsert
before_update 更新前 onBeforeUpdate
after_update 更新後 onAfterUpdate
before_write 寫入前 onBeforeWrite
after_write 寫入後 onAfterWrite
before_delete 刪除前 onBeforeDelete
after_delete 刪除後 onAfterDelete
before_restore 恢復前 onBeforeRestore
after_restore 恢復後 onAfterRestore
在模型類中使用靜態方法調用便可完`成事件觸發
關聯模型:將數據表與表之間進行關聯和對象化;
關聯方式 | 描述 |
---|---|
hasOne |
一對一關聯 |
belongsTo |
一對一關聯-反向 |
hasMany |
一對多關聯 |
hasOneThrough |
遠程一對一 |
hasManyThrough |
遠程一對多 |
belongsToMany |
多對多關聯 |
morphMany |
多態一對多 |
morphOne |
多態一對一 |
morphTo |
多態關聯 |
實例:
主表:tp_user
主鍵:id
附屬表:tp_profile
字段:user_id
hobby
外鍵user_id
主表的主鍵與附屬表的外鍵進行關聯
hasOne
關聯定義:
hasOne('關聯模型類名','外鍵','主鍵')
關聯模型:
外鍵:默認的外鍵規則是當前的模型名+
_id
主鍵:當前模型的主鍵,自動獲取也能夠指定
class UserModel extends Model { protected $table = 'tp_user'; public function profile() { return $this->hasOne(ProfileModel::class , 'user_id' , 'id'); } }
class ProfileModel extends Model { protected $table = 'tp_profile'; }
$user = model\UserModel::find(19); //return json($user->profile); return $user->profile->hobby;
使用save()
設置關聯修改,經過主表修改附表字段的值
$user = UserModel::find(19); $user->profile->save(['hobby'=>'美女']);
->profile()
方法新增數據
$user->profile()->save(['hobby'=>'靚女']);
相對關聯(反向)
belongsTo('關聯模型','外鍵','關聯主鍵')
belonsTo
模式適合於附屬表關聯主表
class ProfileModel extends Model { protected $table = 'tp_profile'; public function user() { return $this->belongsTo(UserModel::class , 'user_id' , id'); } }
$profile = ProfileModel::find(1); return $profile->user;
使用hasOne()
模擬belongsTo()
$user = UserModel::hasWhere('profile',['id'=>19])->find(); // 這裏的profile是user模型勒種的方法而不是profile模型類
$user = UserModel::hasWhere('profile',function($query){ $query->where('profile.id',19); })-select();
hasMany
hasMany
模式適合主表關聯附表,實現一對多查詢;與一對一查詢的主要區別就是,hasMany
能夠實現查詢返回多條。
hasMany('關聯模型',['外鍵','主鍵']);
使用->profile()
方法模式,能夠對數據進行篩選
$user->profile()->where('id','>',19)->select()
調用屬性方式會直接返回結果,調用方法方式能夠進行中間處理
使用has()
方法查詢關聯附表的主表內容
$user = UserModel::has('profile','>=',2)->select(); return $user;
這裏的查詢是在附表中判斷數據與主表的關聯內容
上述代碼的主要功能:在附表中查找與主表有兩次以上關聯的數據,例如id=19在附表中兩兩條關聯數據
使用haswhere
查詢關聯附表的處理內容(反向關聯)
$user = UserModel::hasWhere('profile',['status'=>1])->select(); return $user;
$user = UserModel::hasWhere('profile',function($query){ $query->where('status','>=',1); })->select();
使用save()/saveAll()
新增數據
$user = UserModel::find(20); // 新增單條數據 $user->profile()->save(['hobby'=>'計算機','status'=>'1']); // 新增批量數據 $user->profile()->saveAll([ ['hobby'=>'計算機','status'=>'1'], ['hobby'=>'遊戲機','status'=>'1'] ]);
使用together()
刪除主表內容時,附表關聯的內容所有刪除
$user = UserModel::with('profile')->find(20); $user->together(['profile'])->delete();
with
普通的關聯查詢,會循環執行屢次SQL查詢;
$list = UserModel::select([19,20,21]); foreach($list as $user) { dump($user->profile); }
採用關聯預載入的方式 ,能夠減小屢次查詢的耗時;
with(['關聯數據表1','關聯數據表2']);
延遲預載入:先執行
select()
再執行load()
使用withCount()
能夠統計主表關聯附表的個數,使用profile_count
$list = UserModel::withCount(['profile'])->select([19,20,21]); foreacth($list as $user) { echo $user->profile_count; }
關聯統計的輸出採用"[關聯方法名]_count"的結構
同時支持withMax``withMin``withSum``withAvg
……
使用hidden()
方法,隱藏主表字段或附表字段
$list = Usermodel::with('profile')->select(); return json($list->hidden(['profile.status']));
使用visible()
方法,只顯示指定字段
使用append()
方法,添加額外的字段
三張表:
access表包含了user和role表的關聯ID
belongsToMany('關聯模型','中間表',['外鍵','關聯鍵'])
關聯模型:模型名或類名
中間表:{須要繼承Pivot}
外鍵:
關聯鍵:中間表的當前模型關聯鍵名
參考官方文檔