一. 模型简介
关联模型,一共有三种模式。一对一:ONE_TO_ONE,包括 HAS_ONE 和 BELONGS_TO;
一对多:ONE_TO_MANY,包括 HAS_MANY 和 BELONGS_TO;多对多:MANY_TO_MANY。
用表关系来理解这三种模式:
一对一:用户表和身份证表,一个用户只能对应一个身份证,而一个身份证只能对应一
个用户。这就是一对一。
一对多:用户表和留言表:一个用户可以发表 N 条留言,而每条留言只能由某一个用户
发表。这就是一对多。就算有多个用户发表了相同的留言内容,但 ID 却不一样,所以,不
能理解为多对多。
多对多:用户表和角色表:一个用户可以是认证专员,同时也是审核专员。那么角色表
中的审核专员也可以是蜡笔小新的角色,也可以是路飞的角色。这就是多对多。
二. 关联操作
用户表和身份证表关联,HAS_ONE(一对一),表示一个用户只有一个身份证。
先创建两个数据表:
think_card
think_user
WeiBo/Home/Controller/UserController.class.php 中插入代码:
1 <?php 2 3 namespace HomeController; 4 use ThinkController; 5 use HomeModelUserModel; 6 7 class UserController extends Controller { 8 public function index() { 9 $user = D('User'); 10 $arr = $user->relation(true)->select(); 11 var_dump($arr); 12 } 13 }
然后在 WeiBo/Home/User/Model/UserModel.class.php 中插入代码:
1 <?php 2 namespace HomeModel; 3 use ThinkModel; 4 use ThinkModelRelationModel; 5 6 class UserModel extends RelationModel { 7 protected $_link = array( 8 'Card'=>array( 9 'mapping_type'=>self::HAS_ONE, 10 'class_name'=>'Card', 11 'mapping_name'=>'Card', 12 'foreign_key' =>'uid', 13 'mapping_fields'=>'code', 14 'as_fields'=>'code', 15 'condition'=>'id=1', 16 ), 17 ); 18 }
HAS_ONE 支持以下属性
class_name | 关联的模型类名,如果不写,会自动定位相关数据表。 |
mapping_name | 关联映射名称,用于获取数据的数组名。 |
mapping_type | 设置关联模式,比如一对一 self::HAS_ONE。 |
foreign_key | 关联外键的名称,会自动对应当前数据表的 id。 |
mapping_fields | 关联要查询的字段,默认是查询所有。 |
as_fields | 关联的字段映射成同级的字段。 |
condition | 关联条件,额外查询使用。 |
在 WeiBo/Home/User/Model/UserModel.class.php 中测试各行代码的效果:
1 protected $_link = array( 2 'Card'=>array( 3 'mapping_type'=>self::HAS_ONE, 4 'class_name'=>'Card', 5 'mapping_name'=>'Carder', 6 ), 7 );
效果为:
'class_name'=>'Card', 这行可以不写,因为不写的的时候默认会自动定位相关数据表,
但写了就不能写错了,必须和数据表的名字是一样的。
'mapping_name'=>'Carder', 则这时把定位的数据表的名字改为 Carder ,这时什么都没显示,
是因为没有设置关联的外键,加上 'foreign_key' =>'uid', 后,得到效果如图:
这时就可以得到think_card和think_user的数据表关联在一起了。
加上 'mapping_fields'=>'code', 后,只获取think_card中的code数据;
再加上 'as_fields'=>'code', 后,则将think_card中的code数据呈现形式和think_user中的数据呈现形式一样:
加上 'condition'=>'id=1', 后,获取 think_card 中只获取 id=1 的数据,只是SQL查询的方式有些变化
没加之前是:
加了之后:
这时读取数据中只有id=1的数据中有code,其它的code的数据都是NULL,
下面是BELONGS_TO关联模型:
Belongs_to 关联表示当前模型从属于另外一个父对象,例如每个用户都属于一个部门
新建 WeiBo/Home/Controller/CardController.class.php ,代码为:
1 <?php 2 namespace HomeCOntroller; 3 use ThinkController; 4 5 class CardController extends Controller { 6 public function index() { 7 $card = D('Card'); 8 $arr=$card->relation(true)->select(); 9 var_dump($arr); 10 } 11 }
新建 WeiBo/Home/User/Model/CardModel.class.php ,插入代码:
1 <?php 2 namespace HomeModel; 3 use ThinkModel; 4 use ThinkModelRelationModel; 5 6 class CardModel extends RelationModel { 7 protected $_link = array( 8 'User'=>array( 9 'mapping_type'=>self::BELONGS_TO, 10 'foreign_key'=>'uid', 11 'mapping_fields'=>'user', 12 'as_fields'=>'user', 13 ), 14 ); 15 16 }
'foreign_key'=>'uid', 中关联的uid是card表中的结构,而不是user表中的结构。card中的uid的数据为:1,2,4,则得到的结果是:
红色标出的是需要注意的部分,如果这里写id,在card表中的数据为1,2,3则出现的结果为:
此时得到的数据是user里面的第3个用户的名字。