## 概述
模型類Think\Model配合數據庫中間層Think\Db實現了完整的ORM功能,包括CURD和ActiveRecord實現。
基礎模型類Model的設計非常靈活,無需進行任何模型定義,就可以進行相關數據表的ORM和CURD操作,只有在需要封裝單獨的業務邏輯的時候,模型類才是必須被定義的。
新版采用了PHP的Trait特性實現了模型的動態組裝,可以更加靈活的實現模型的擴展。
## 模型定義
如果你僅僅需要實現對數據表的CURD操作的話,實際上根本不需要定義模型類,直接實例化基礎模型類即可。(參考模型實例化)
只有當你需要額外定義模型的屬性或者方法邏輯的時候,才需要額外定義模型類。模型類一般位于模塊的model 目錄下面,例如:
~~~
namespace app\index\model;
use think\Model;
class New extends Model{
public function getNews(){
//添加自己的業務邏輯
// ...
}
}
~~~
實例化代碼如下:
~~~
$model = \think\Loader::model('index/New');
// 快捷方法
$model = D('index/New');
~~~
如果你的模型沒有定義模型類的話,可以直接使用
~~~
$model = \think\Loader::table('New');
// 快捷方法
$model = M('New');
~~~
并且支持傳入模型參數:
~~~
$config = [
'prefix' => 'think_',
'connection'=> $connection,
...
];
// 或者使用
$model = \think\Loader::table('New',$config);
~~~
支持的配置參數包括:
| 參數名|含義 |
|---|---|
| prefix | 數據表前綴 |
| connection | 數據庫連接信息 |
|table_name|實際的數據表(不含前綴)|
|true_table_name|實際的數據表(含前綴 支持指定數據庫名)|
|db_name|數據庫名稱|
支持多層的模型類定義,例如:
~~~
namespace app\index\model\one;
use think\Model;
class New extends Model{
public function getNews(){
//添加自己的業務邏輯
// ...
}
}
~~~
實例化代碼如下:
~~~
$model = \think\Loader::model('index/one/New');
// 快捷方法
$model = D('index/one/New');
~~~
注意如果類名是駝峰方式的話,例如:
~~~
namespace app\index\model;
use think\Model;
class UserType extends Model{
}
~~~
對應的模型文件名應該是:
~~~
application\index\model\UserType.php
~~~
默認情況下,模型類和數據表的默認對應關系如下:
| 模型名(類名)|約定對應數據表(假設數據庫的前綴定義是?think_) |
|---|---|
| User | think_user |
| UserType | think_user_type |
如果你的規則和上面的系統約定不符合,那么需要設置Model類的數據表名稱屬性。
在ThinkPHP的模型里面,有幾個關于數據表名稱的屬性定義:
| 屬性 | 說明 |
|---|---|
| tableName | 不包含表前綴的數據表名稱,一般情況下默認和模型名稱相同,只有當你的表名和當前的模型類的名稱不同的時候才需要定義。 |
| trueTableName | 包含前綴的數據表名稱,也就是數據庫中的實際表名,該名稱無需設置,只有當上面的規則都不適用的情況或者特殊情況下才需要設置。 |
| dbName | 定義模型當前對應的數據庫名稱,只有當你當前的模型類對應的數據庫名稱和配置文件不同的時候才需要定義。 |
下面舉個例子來加深理解,例如,在數據庫里面有一個think_categories表,而我們定義的模型類名稱是CategoryModel,按照系統的約定,這個模型的名稱是Category,對應的數據表名稱應該是think_category(全部小寫),但是現在的數據表名稱是think_categories,因此我們就需要設置tableName屬性來改變默認的規則(假設我們定義的數據表前綴`database.db_prefix` 為 think_)。
~~~
protected $tableName = 'categories';
~~~
注意這個屬性的定義不需要加表的前綴think_
而對于另外一種特殊情況,數據庫中有一個表(top_depts)的前綴和其它表前綴不同,不是think_ 而是 top_,這個時候我們就需要定義 trueTableName 屬性了
~~~
protected $trueTableName = 'top_depts';
~~~
注意trueTableName需要完整的表名定義
除了數據表的定義外,還可以對數據庫進行定義,例如:
~~~
protected $dbName = 'top';
~~~
## 查詢語言
ThinkPHP5.0的查詢語言基本和3.2版本保持一致,核心\Think\Model除了基本的CURD和AR查詢之外,還提供了一些統計函數、getField方法,及動態查詢方法,使用如下:
~~~
$User = D('User');
$User->count();
$User->getField('name');
$User->getByName('thinkphp');
$User->getFieldByName('thinkphp','name');
~~~
> 查詢語言基本和3.2版本沒有任何變化,請先參考3.2的完全開發手冊。
## 自動驗證和自動完成
要使用模型的自動驗證和自動完成功能,需要引入traits,例如:
~~~
namespace app\index\model;
T('model/Auto');
class User extends \think\Model{
use \traits\model\Auto;
// 下面是模型類的方法和屬性定義
}
~~~
如果你的PHP版本是5.5的話,可以省略下面這行代碼:
~~~
T('model/Auto');
~~~
## 視圖模型
視圖模型的用法也是需要首先繼承視圖模型擴展,例如:
~~~
namespace app\index\model;
use think\model\View;
class UserType extends View{
}
~~~
其它用法和之前的視圖模型用法一致。
## 關聯模型
~~~
namespace app\index\model;
use think\model\Relation;
class User extends Relation{
}
~~~