要定义视图对象,需要设置模型的viewModel属性为true,然后设置viewFields属性即可。例如下面的例子,我们定义了一个BlogView模型对象,其中包括了Blog模型的id、name、title和User模型的name,以及Category模型的title字段,我们通过创建BlogView模型来快速读取一个包含了User名称和类别名称的Blog记录(集)。
class BlogViewModel extends Model
{
protected $viewModel = true;
protected $viewFields = array(
‘Category’=>array(’title’=>’categoryName’),
‘User’=>array(’name’=>’userName’),
‘Blog’=>array(’id’,'name’,'title’),
);
protected $viewCondition = array(
‘Blog.categoryId’=>array(’eqf’,'Category.id’),
‘Blog.userId’=>array(’eqf’,'User.id’),
);
}
我们来解释一下定义的格式代表了什么。
$viewFields 属性表示视图模型包含的字段,每个元素定义了某个数据表或者模型的字段。
例如:
‘Blog’=>array(’id’,'name’,'title’)
表示BlogView视图模型要包含Blog模型中的id、name和title字段属性,这个其实很容易理解,就和数据库的视图要包含某个数据表的字段一样。而Blog相当于是给Blog模型对应的数据表定义了一个别名。
BlogView视图模式除了包含Blog模型之外,还包含了Category和User模型,下面的定义:
‘Category’=>array(’title’=>’categoryName’)
和上面类似,表示BlogView视图模型还要包含Category模型的title字段,因为视图模型里面已经存在了一个title字段,所以我们通过’title’=>’categoryName’ 把Category模型的title字段映射为categoryName字段,如果有多个字段,可以使用同样的方式添加。最后的User模型的定义方式同样也就很容易理解了。
$viewCondition 属性表示了视图的基础关联条件
例如:
‘Blog.categoryId’=>array(’eqf’,'Category.id’),
‘Blog.userId’=>array(’eqf’,'User.id’),
注意eqf指的是后面的条件不是字符串,而是SQL字段操作,这样定义后,在进行其它查询的时候,会自动带上这个基础条件。最终的解析结果其实是:
Blog.categoryId = Category.id AND Blog.userId = User.id
最后,我们把视图模型的定义翻译成SQL语句就更加容易理解视图模型的原理了。假设我们不带任何其他条件查询全部的字段,那么查询的SQL语句就是
Select
Blog.id as id,
Blog.name as name,
Blog.title as title,
Category.title as categoryName,
User.name as UserName
from think_blog Blog JOIN think_category Category JOIN think_user User
where Blog.categoryId=Category.id AND Blog.userId=User.id
视图模型的定义一般需要先单独定义其中的模型类,但是这并不是必须的,如果没有定义其中的模型类,系统会默认按照系统的规则进行数据表的定位。如果Blog模型并没有定义,那么系统会自动根据当前模型的表前缀和后缀来自动获取对应的数据表。也就是说,如果我们并没有定义Blog模型类,那么上面的定义后,系统在进行视图模型的操作的时候会根据Blog这个名称和当前的表前缀设置(假设为Think_ )获取到对应的数据表可能是think_blog。不过系统建议为了操作方便,最好还是单独定义Blog模型,这样单表和视图都可以操作。
1.5版本以上,ThinkPHP还可以支持视图模型的ON定义和JOIN类型定义,我们可以把上面的视图定义改成:
protected $viewFields = array(
‘Blog’=>array(’id’,'name’,'title’),
‘Category’=>array(’title’=>’categoryName’,'_on’=>’Category.id=Blog.categoryId’,'_type’=>’LEFT’),
‘User’=>array(’name’=>’userName’,'_on’=>’User.id=Blog.userId’,'_type’=>’RIGHT’),
);
视图模型的viewFields和viewCondition属性就合并到新的viewFields定义了。通过上面的定义,我们在查询的时候最终生成的SQL语句就变成:
Select
Blog.id as id,
Blog.name as name,
Blog.title as title,
Category.title as categoryName,
User.name as UserName
from think_blog Blog LEFT JOIN think_category Category ON Blog.categoryId=Category.id RIGHT JOIN think_user User ON Blog.userId=User.id
燕之庐