在之前的
项目配置中我们已经知道了如何
定义项目入口
文件和进行项目配置,相当于是策划项目的过程。定义数据模型其实就是设计数据结构的过程,把设计好的数据字典转换成对应的数据对象(VO对象)就行了。
VO是指Value Object(数据对象),更加精确的说是业务对象,因为VO对象是存活在业务层的,供业务逻辑使用的。VO对象和数据表存在一种映射关系,VO对象的每个属性对应数据表(或者视图)的一个
字段,你完全可以添加其他非数据表字段的VO对象属性,以用于业务逻辑操作,例如关联字段。VO对象有个特殊的保留属性_info,是一个数组
变量,用来保存该VO对象的一些特殊信息。和VO对象对应的概念还有PO(持久数据对象),VO和PO的概念都来自于O/R Mapping (Object Relational Mapping,对象关系映射),PO只能用在数据层(也就是说PO对象的属性必须和数据表一一对应),VO用在业务逻辑层和表示层(可以有自己的额外属性)。各层操作属于该层自己的数据对象,这样就可以降低各层之间的耦合,便于以后
系统的维护和扩展。如果将PO用在各个层中就相当于我们使用全局变量,我们知道在OO设计非常不赞成使用全局变量。
ThinkPHP框架采用了简单的OO-RDBMS Mapping,没有使用PO对象。
Vo对象的定义基于数据表的字段,但是不完全等同于数据表,有如下几点需要注意:
1、在有些环境下面对数据表中的字段是不区分大小写的,但是Vo对象的属性定义是严格区分大小写的,忠于数据表的字段名称是一个好的建议,这样便于移植;
2、Vo对象除了可以包含数据表中对应的字段还可以包括扩展的业务逻辑属性;
3、Vo对象可以包含对视图的定义;
4、为了让数据定义尽量简单化,没有在Vo对象中加入对数据类型、长度和自动增长等设置的定义,但是Vo对象保留了一个特殊属性_info来支持以后的扩展定义。
创建Vo类
我们来根据数据表来创建Vo对象类,假设有个用户表为:
- CREATE TABLE `user` (
- `
id` int(10) NOT NULL auto_increment,- `
name` varchar(30) NOT NULL,- `
password` varchar(32) NOT NULL,- `
nickname` varchar(30) NOT NULL,- `
status` tinyint(1) NOT NULL,- `
remark` varchar(255) default NULL,-
PRIMARY KEY (`id`),-
UNIQUE KEY `name` (`name`)- )
那么我们把user表转换为Vo对象应该写成:
- class UserVo extends Vo
-
{ //类定义开始-
var $id; //用户编号-
var $name; //用户名-
var $password; //密码-
var $nickname; //昵称-
var $status; //用户状态-
var $remark; //备注信息-
}//类定义结束
Vo类的文件名和类名同名,例如上面的类文件名应该是 UserVo.class.php,通常放置在项目
应用类库目录下面的Vo子目录下面。
注意:上面的写法是兼容PHP4的写法,如果你采用PHP5开发,并且不考虑兼容性的话,可以使用public/protected/private 访问控制符号来定义字段属性。严格来说,Vo对象属性并不一定限制为数据表字段,我们可以理解为视图对象,这样Vo的字段就更加灵活了。
这里定义的Vo对象的属性应该就是
数据库查询的返回字段名,如果进行关联查询的话,属性名可能和真实表字段名有所区别。如果你的数据库支持视图,那么这么这里可以定义为视图中字段名。
数据表中字段是不区分大小写的,但是在Vo对象中定义的属性是区分大小写的,这点尤其要注意。
要初始化一个Vo对象可以使用数组或者Map对象,也可以创建空对象,然后进行属性设置。
你不需要为每个对象属性添加存取方法,要获取或者设置Vo对象的属性请使用get和set方法,这两个方法调用了Base基类的__get和__set方法。
Vo对象有三个转换方法可以转换成其他类型
- toArray 转换成数组
- toMap 转换成Map对象
- toJson 转换成Json字串
可以使用isEmpty方法判断一个Vo对象是否为空。
在ThinkPHP开发模型中默认的数据表主键命名统一使用id,并且使用自动增长类型,如果和你的数据库设计不符,在使用Dao类的时候需要设置参数。
另外一个高级技巧是可以为多个Vo对象定义父类,那么通过相关设置,你可以做到更新子对象的同时可以更新父对象。
例如,为网站的所有类型的用户定义一个UserVo对象,其中包括了所有类型用户所公共的属性,各类型的私有属性可以定义在自己的Vo对象中,如下面的会员Vo对象继承了UserVo对象
- class MemberVo extends UserVo
-
{ //类定义开始- //父类中的属性无需再定义了
- //这里添加会员才有的一些属性
-
var $email; //邮箱-
var $tel; //电话-
var $birthday; //生日-
var $nickname; //昵称-
}//类定义结束
如果Member数据表和User数据表在你的数据库设计中都存在,那么,你可以设置项目配置文件中的SAVE_PARENT_VO 和UPDATE_PARENT_VO参数来实现保存和更新子表的同时操作父表。