## 概述
模型类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{
}
~~~