一、什麼是模型
爲什麼我們要在項目中使用模型,其實我們知道,我們可以直接在控制器中進行數據庫的增、刪、改、查,其實已經能基本完成我們的需求,但是,爲什麼還要有模型的存在呢?
比如說我們現在要做一個用戶註冊的操作,用戶註冊我們可能用兩個表來保存用戶的信息,一個是user表(保存用戶基本信息),一個是user_info表(保存用戶擴展信息,比如愛好等等),如果我們現在直接在我們的控制器中編寫,那麼我們需要對數據庫兩個表進行操作,我們就需要寫兩個db的方法來進行操作,我們需要將這些方法進行封裝,最後放在模型裏,只要執行這個模型裏的某一個方法,那麼就會自動完成我們所有操作的操作,也就是說,把我們數據庫完成同一件事情的操作,放在一個公共方法裏,這樣我們在控制器裏進行調用就會變得很方便。特別是代碼複用的部分,我們可以編寫這樣的方法,讓我們在任何地方可以使用用戶註冊這個方法。那麼下面就看看如何定義模型:
首先在我們的application/index/創建一個model目錄,專門放模型文件,然後在model目錄下創建一個User.php文件
模型文件的命名規範: 首先我們的模型名和我們的表名要是對應的。比如我們要寫我們數據庫中的shulv_user表,那麼我們的模型名就是去掉前綴之後使用駝峯的命名方式,也就是User.php,當數據庫中有這種包含下劃線的表名時,去掉下劃線,並將下劃線後邊的字母大寫,即時模型名,shulv_user_info 對應模型名就是UserInfo,這樣他就會自動對應到數據庫中的表。下邊寫代碼驗證一下:
namespace app\index\controller;
use think\Controller;
use app\index\model\User;//使用我們剛剛新建的那個模型
class Index extends Controller
{
public function index()
{
$res = User::get(51);//通過get()方法,取出user表中的id=51的這條數據(現在可以不用知道爲什麼使用get方法,後邊會說)
$res = $res->toArray();//將取出的數據轉換成數組
dump($res);
}
}
你會發現,我們沒有在模型中的User.php中編寫任何的代碼,但是在控制器中use進來User模型之後,就可以直接使用靜態方法,這是爲什麼呢?
因爲在我們的模型文件中的類都繼承了think\Model這個類,think\Model中其實有這樣的方法,這些方法,後邊會說到。同樣我們還可以在控制器中使用new的方式
$user = new User();
$res = $user::get(53);
$res = $res->toArray();
dump($res);
當我們,不想通過use的方式將User模型引入進來的時候,我們還可以通過下邊的方法:
namespace app\index\controller;
use think\Controller;
//use app\index\model\User;//使用我們剛剛新建的那個模型
use think\Loader;//通過引入think下的Loader類
class Index extends Controller
{
public function index()
{
$user = Loader::model("User");//通過Loader下的model這個靜態方法來引入對應模型
$res = $user::get(52);
$res = $res->toArray();
dump($res);
}
}
//說明:這種方式,是當我們的控制器下有多個模型的時候,我們使用這種方式,這樣我們就不用在使用每一個模型的時候都use一下,我們直接使用Loader::model()這種方法直接引入。另外,它還提供了一個助手函數model(),此時我們連Loader類都不用引入了
/*
$user = model("User");
$res = $user::get(52);
$res = $res->toArray();
dump($res);
*/
//在這裏建議大家使用前兩種方式,因爲助手函數式可能被覆蓋掉的,當然這種情況很少發生,但是爲了避免,或者讓我們的代碼可讀性更高,建議大家使用第一種方式,也就是將需要的模型都use進來,通過它的靜態方法來獲取數據,這樣我們的代碼看起來更清晰,我們可以在最上邊就看見我們當前的控制器使用了哪些模型類,這樣在後期維護中會變得很方便
二、通過模型進行數據查詢
namespace app\index\controller;
use think\Controller;
use app\index\model\User;//使用我們剛剛新建的那個模型
//use think\Loader;//通過引入think下的Loader類
class Index extends Controller
{
public function index()
{
//之前我們查詢一條數據的時候是通過給get()方法傳遞一個主鍵來獲取對應數據,我們還可以傳遞一個閉包函數
$res = User::get(function($query){//在這裏邊構造查詢條件
$query->where("id", "eq", 55);//這裏條件的構造和前邊的博客中說的一樣(同樣可以在後邊繼續添加鏈式方法)
});
$res = $res->toArray();
dump($res);
}
}
我們還可以通過下邊這種方法構造where條件
namespace app\index\controller;
use think\Controller;
use app\index\model\User;//使用我們剛剛新建的那個模型
//use think\Loader;//通過引入think下的Loader類
class Index extends Controller
{
public function index()
{
$res = User::where("id", 51)
->find();//同樣我們可以在後邊添加更多的鏈式方法
$res = $res->toArray();
dump($res);
}
}
/*
當我們想獲取表中的多條數據時,我們可以使用User::all();參數是主鍵名,可以使用字符串的方式,也可以使用數組的方式
$res = User::all("1,2,3");//這個時候返回的每一條記錄都是一個對象,我們就可以通過foreach進行遍歷輸出
//或$res = User::all([1,2,3]);
foreach($res as $value){
dump($value->toArray());//這個時候我們就會獲得三條數據
}
//這個all()還可以接收一個閉包函數作爲參數,來構造where條件
$res = User::all(function($query){
$query->where("id", "<", 5); //同樣可以添加更多的鏈式方法
});
*/
當我們想要獲取單獨的一個字段,我們知道Db類有一個value() 方法,模型我們也可以這樣
$res = User::where()->value("email");//直接返回的是字符串
dump($res);
//獲取某一個字段那一列時
$res = User::column("email");//返回的是一個數組
三、使用模型添加數據
在thinkphp,它的model爲我們提供了一個create()方法(靜態方法),直接向數據庫中插入數據
namespace app\index\controller;
use think\Controller;
use app\index\model\User;//使用我們剛剛新建的那個模型
//use think\Loader;//通過引入think下的Loader類
class Index extends Controller
{
public function index()
{
$res = User::create([
'username' => 'shulv',
'password' => md5('shulv'),
'email' => '[email protected]',
'num' => 100
]);//它的返回結果依然是一個對象
dump($res->id);//獲得此時的自增id
dump($res);
}
}
namespace app\index\controller;
use think\Controller;
use app\index\model\User;//使用我們剛剛新建的那個模型
//use think\Loader;//通過引入think下的Loader類
class Index extends Controller
{
public function index()
{
// $res = User::create([
// 'username' => 'shulv',
// 'password' => md5('shulv'),
// 'email' => '[email protected]',
// 'num' => 100
// 'demo' => 15245
// ]);//當我們要插入一個表中並沒有的字段時,不傳遞第二個參數時,運行時會報錯,說該字段不存在(此時數據庫也並不會插入這條數據)
/*
我們知道,當前臺傳遞數據時,往往直接傳到$_POST中,我們會將POST中所有的數據插入到表中,那麼我們就應該讓它有的就插入表中,沒有的就不插入,此時我們就需要給它傳入第二個參數"true"
*/
$res = User::create([
'username' => 'shulv1',
'password' => md5('shulv1'),
'email' => '[email protected]',
'num' => 101,
'demo' => 15245
],true);
dump($res);
}
}
當我們僅允許添加指定的字段時,我們可以將第二個參數傳遞一個數組,數組中的元素就是,你指定添加的字段
public function index()
{
$res = User::create([
'username' => 'shulv2',
'password' => md5('shulv2'),
'email' => '[email protected]',
'num' => 102,
'demo' => 145
],['username','password']);
dump($res->id);
}
模型中還爲我們提供了一個save()方法來插入數據(如果我們想使用save()就要先實例化我們的模型)
namespace app\index\controller;
use think\Controller;
use app\index\model\User;//使用我們剛剛新建的那個模型
//use think\Loader;//通過引入think下的Loader類
class Index extends Controller
{
public function index()
{
$userModel = new User;
//那麼此時,我們就可以對數據庫進行添加的操作了
$userModel->username = 'shulv3';
$userModel->password = md5('shulv3');
$userModel->email = '[email protected]';
$userModel->num = 103;
$userModel->save();
dump($userModel->id);
}
}
當然我們還可以使用一種簡單的方法,就是直接給save()傳遞一個數組,數組的元素爲插入的值,就像create()方法傳遞參數那樣。不一樣的地方是,但遇見插入的字段,表中不存在的時候,它的處理方法是調用一個allowField()方法
$userModel = new User;
$res = $userModel
->allowField(true)
->save([//allowField('true')也可以傳遞一個數組,元素爲允許插入的字段名
'username' => 'shulv4',
'password' => md5('shulv5'),
'email' => '[email protected]',
'demo' => 123
]);//返回值是插入的條數
dump($res);
那麼當我們想要添加多條記錄時,我們可以使用saveAll()方法,參數爲一個二維數組
public function index()
{
$userModel = new User;
$res = $userModel->saveAll([
['email' => '[email protected]'],
['email' => '[email protected]']
]);//我這裏只插入了email
foreach($res as $value){
dump($value->id);
//dump($value->toArray());
}
}