一、关联模型 ( RelationMondel )

1.数据查询

① HAS_ONE 查询

创建两张数据表评论表和文章表: tpk_comment , tpk_article 。评论和文章的对应关系为,一条评论 id 对应一篇文章,为 ONE_TO_ONE 关系 ( 一对一 )。评论表的结构为:

其中 aid 字段与文章表的 id 字段对应。打开自定义模型 ArticleModel,让模型继承于 RelationModel,然后定义成员属性 $_link,代码:

ArticleModel.class.php:

<?php
class ArticleModel extends RelationModel{ protected $_link = array( //关联模型(表)1
'comment'=>array(
//元素(属性)定义
'mapping_type'=>HAS_ONE,
'class_name'=>"comment",
"mapping_name"=>"comment",
"foreign_key"=>"aid",
"mapping_fields"=>array("id","comment","comment_time"),
"as_fields"=>"id:comment_id,comment,comment_time",
), }

foreign_key 为必须的。

控制器:IndexAction.class.php:

<?php
class IndexAction extends Action { public function relation(){ $obj=D("Article");
$rows=$obj->field('id,title')->relation(true)->select();
dump($rows);
}
}

浏览器输出:

array(6) {
[0] => array(5) {
["id"] => string(1) "1"
["title"] => string(4) "test"
["comment_id"] => string(1) "1"
["comment"] => string(15) "第一条评论"
["comment_time"] => string(19) "2014-11-22 22:40:01"
}
[1] => array(5) {
["id"] => string(1) "2"
["title"] => string(12) "吼吼吼吼"
["comment_id"] => string(1) "2"
["comment"] => string(15) "第二条评论"
["comment_time"] => string(19) "2014-11-22 22:40:06"
}
[2] => array(5) {
["id"] => string(1) "4"
["title"] => string(7) "test2_m"
["comment_id"] => NULL
["comment"] => NULL
["comment_time"] => NULL
}
[3] => array(5) {
["id"] => string(1) "5"
["title"] => string(2) "22"
["comment_id"] => NULL
["comment"] => NULL
["comment_time"] => NULL
}
[4] => array(5) {
["id"] => string(1) "6"
["title"] => string(1) "1"
["comment_id"] => NULL
["comment"] => NULL
["comment_time"] => NULL
}
[5] => array(5) {
["id"] => string(1) "7"
["title"] => string(6) "lalala"
["comment_id"] => NULL
["comment"] => NULL
["comment_time"] => NULL
}
}

http://127.0.0.26/index.php/index/relation

此时文章表和评论表的数据为:

评论表:

文章表:

② BELONGS_TO 查询

一条评论数据对应一个用户 id,评论表和用户表之间的关系是 BELONGS_TO

创建自定义模型 CommentModel,继承于RelationModel:

CommentModel.class.php:

<?php
class CommentModel extends RelationModel{ protected $_link = array( 'user'=>array( "mapping_type"=>BELONGS_TO,
"foreign_key"=>"comment_user",
"mapping_fields"=>array("id","username"),
"as_fields"=>"id:user_id,username", ), );
}

tpk_user 表结构

数据:

控制器 ArticleModel.class.php:

<?php
class IndexAction extends Action { //BELONGS_TO
public function relation2(){ $obj=D("Comment");
$rows=$obj->relation(true)->select();
dump($rows);
} }

访问 http://127.0.0.26/index.php/index/relation2

显示:

array(2) {
[0] => array(7) {
["id"] => string(1) "1"
["aid"] => string(1) "1"
["comment"] => string(15) "第一条评论"
["comment_time"] => string(19) "2014-11-22 22:40:01"
["comment_user"] => string(1) "1"
["user_id"] => string(1) "1"
["username"] => string(3) "dee"
}
[1] => array(7) {
["id"] => string(1) "2"
["aid"] => string(1) "2"
["comment"] => string(15) "第二条评论"
["comment_time"] => string(19) "2014-11-22 22:40:06"
["comment_user"] => string(1) "2"
["user_id"] => string(1) "2"
["username"] => string(4) "yoko"
}
}

③ HAS_MANY

一篇文章可以对应多条评论,评论表和文章表之间的关系为 HAS_MANY

此时评论表的数据为:

模型:CommentModel.class.php:

<?php
class CommentModel extends RelationModel{ //关联模型2 HAS_MANY
'comment'=>array( 'mapping_type'=>HAS_MANY,
'foreign_key'=>"aid",
), }

控制器 ArticleModel.class.php:

<?php
class IndexAction extends Action { //HAS_MANY
public function relation3(){ $obj=D("Article");
$rows=$obj->relation(true)->select();
dump($rows);
}
}

访问 http://127.0.0.26/index.php/index/relation3

显示:

array(6) {
[0] => array(8) {
["id"] => string(1) "1"
["title"] => string(4) "test"
["content"] => string(12) "test_content"
["category"] => string(13) "test_category"
["area"] => string(6) "北京"
["add_user"] => string(5) "admin"
["add_time"] => string(19) "2014-11-20 23:03:44"
["comment"] => array(2) {
[0] => array(5) {
["id"] => string(1) "1"
["aid"] => string(1) "1"
["comment"] => string(15) "第一条评论"
["comment_time"] => string(19) "2014-11-22 22:40:01"
["comment_user"] => string(1) "1"
}
[1] => array(5) {
["id"] => string(1) "2"
["aid"] => string(1) "1"
["comment"] => string(15) "第二条评论"
["comment_time"] => string(19) "2014-11-22 22:40:06"
["comment_user"] => string(1) "2"
}
}
}
[1] => array(8) {
["id"] => string(1) "2"
["title"] => string(12) "吼吼吼吼"
["content"] => string(18) "任溶溶柔然人"
["category"] => string(14) "test_category2"
["area"] => string(6) "河北"
["add_user"] => string(5) "admin"
["add_time"] => string(19) "2014-11-22 15:16:12"
["comment"] => NULL
}
[2] => array(8) {
["id"] => string(1) "4"
["title"] => string(7) "test2_m"
["content"] => string(4) "haha"
["category"] => string(0) ""
["area"] => string(6) "福建"
["add_user"] => NULL
["add_time"] => string(19) "2014-11-22 11:44:26"
["comment"] => NULL
}
[3] => array(8) {
["id"] => string(1) "5"
["title"] => string(2) "22"
["content"] => NULL
["category"] => string(0) ""
["area"] => string(6) "福建"
["add_user"] => NULL
["add_time"] => string(19) "2014-11-22 12:40:58"
["comment"] => NULL
}
[4] => array(8) {
["id"] => string(1) "6"
["title"] => string(1) "1"
["content"] => string(1) "2"
["category"] => string(0) ""
["area"] => string(6) "福建"
["add_user"] => NULL
["add_time"] => NULL
["comment"] => NULL
}
[5] => array(8) {
["id"] => string(1) "7"
["title"] => string(6) "lalala"
["content"] => string(6) "hohoho"
["category"] => string(0) ""
["area"] => string(6) "北京"
["add_user"] => NULL
["add_time"] => NULL
["comment"] => NULL
}
}

2.数据操作

以 HAS_MANY 为例,在tpk_article中添加一篇文章,同时 tpk_comment 中添加两条评论。代码:

控制器 ArticleModel.class.php:

    //HAS_MANY 操作,tpk_article中添加一篇文章,同时tpk_comment中添加两条评论
public function reladd(){ $obj=D("Article");
$data['title']="新闻标题";
$data['content']='这是一条体育新闻';
$data['add_time']=date("Y-m-d H:i:s",time());
//关联的模型
$data['comment']=array(
array("aid"=>20,"comment"=>"体育新闻评论1","comment_time"=>date("Y-m-d H:i:s",time()),"comment_user"=>1),
array("aid"=>20,"comment"=>"体育新闻评论2","comment_time"=>date("Y-m-d H:i:s",time()),"comment_user"=>1),
);
$obj->relation(true)->add($data);
}

另一个例子,删除文章的同时也删除了评论:

控制器 IndexAction.class.php:

<?php
class IndexAction extends Action { //HAS_MANY 删除
public function reldel(){ $obj=D("Article");
$obj->relation(true)->delete(20);
echo $obj->getLastSql();
} }

二、高级模型 ( AdvModel )

高级模型除了可以实现普通模型所有功能之外,还能够实现数据过滤、操作限制、延迟操作等功能。

例子:

定位查询 getN() , first , last

getN(2) :获取结果集正序第 3 条记录

Model 代码:

<?php
class ArticleModel extends AdvModel{ //....
}

控制器代码:

<?php

class IndexAction extends Action {

        //使用高级模型定位查询
// $obj=D("Article");
// $rows=$obj->getN(2);
// dump($rows);
// echo $obj->getLastSql(); //使用高级模型动态查询
// $obj=D("Article");
// $rows=$obj->getByArea("北京");
// dump($rows);
// echo $obj->getLastSql(); //使用高级模型动态查询2
// $obj=D("Article");
// $rows=$obj->getFieldByArea("北京","id");
// dump($rows);
// echo $obj->getLastSql(); //使用高级模型动态查询3
// $obj=D("Article");
// $rows=$obj->top5();
// dump($rows);
// echo $obj->getLastSql();
}
}

参考资料:《PHP MVC 开发实战》

ThinkPHP 学习笔记 ( 四 ) 数据库操作之关联模型 ( RelationMondel ) 和高级模型 ( AdvModel )的更多相关文章

  1. ThinkPHP 学习笔记 ( 三 ) 数据库操作之数据表模型和基础模型 ( Model )

    //TP 恶补ing... 一.定义数据表模型 1.模型映射 要测试数据库是否正常连接,最直接的办法就是在当前控制器中实例化数据表,然后使用 dump 函数输出,查看数据库的链接状态.代码: publ ...

  2. Symfony2学习笔记之数据库操作

    数据库和Doctrine让我们来面对这个对于任何应用程序来说最为普遍最具挑战性的任务,从数据库中读取和持久化数据信息.幸运的是,Symfony和Doctrine进行了集成,Doctrine类库全部目标 ...

  3. Laravel 学习笔记之数据库操作——Eloquent ORM

    1. 时间戳 默认情况下在使用ORM操作数据库进行添加.修改数据时, created_at 和 updated_at列会自动存在于数据表中,并显示的是 ‘2017’格式,如果想以 Unix时间戳格式存 ...

  4. python学习笔记(四)-文件操作

    文件读写"""一.文件打开有3种方式 1.读 r #如果打开的文件的时候没有指定模式,那么默认是读 读写模式 r+,只要沾上r,文件不存在的时候,打开都会报错 2.写 w ...

  5. openresty 学习笔记四:连接mysql和进行相关操作

    openresty 学习笔记四:连接mysql和进行相关操作 毕竟redis是作为缓存,供程序的快速读写,虽然reidis也可以做持久化保存,但还是需要一个做数据存储的数据库.比如首次查询数据在red ...

  6. thinkphp学习笔记4—眼花缭乱的配置

    原文:thinkphp学习笔记4-眼花缭乱的配置 1.配置类别 ThinkPHP提供了灵活的全局配置功能,ThinkPHP会依次加载管理配置>项目配置>调试配置>分组配置>扩展 ...

  7. MySql学习笔记四

    MySql学习笔记四 5.3.数据类型 数值型 整型 小数 定点数 浮点数 字符型 较短的文本:char, varchar 较长的文本:text, blob(较长的二进制数据) 日期型 原则:所选择类 ...

  8. thinkphp学习笔记10—看不懂的路由规则

    原文:thinkphp学习笔记10-看不懂的路由规则 路由这部分貌似在实际工作中没有怎么设计过,只是在用默认的设置,在手册里面看到部分,艰涩难懂. 1.路由定义 要使用路由功能需要支持PATH_INF ...

  9. thinkphp学习笔记6—url模式

    原文:thinkphp学习笔记6-url模式 入口文件是应用的唯一入口,因为可以多入口,每个应用可以对应一个入口文件,系统会从rul参数中解析当前请求的模块,控制器,操作.ThinkPHP是区分大小写 ...

随机推荐

  1. H.264 基础及 RTP 封包详解

    转自:http://my.oschina.net/u/1431835/blog/393315 一. h264基础概念 1.NAL.Slice与frame意思及相互关系 1 frame的数据可以分为多个 ...

  2. CC2540开发板学习笔记(七)—— 睡眠唤醒

    (一)中断唤醒 一.实验内容 通过中断唤醒在睡眠模式下的CC2540 二.实验原理 1.系统电源管理(工作方式) (1)全功能模式: 高频晶振(16M或者32M)和低频晶振(32.768K RCOSC ...

  3. Spring的国际化资源messageSource

    Spring中可以使用两个类加载资源文件:ReloadableResourceBundleMessageSource和ResourceBundleMessageSource. 可配置如下message ...

  4. HTML-Canvas01

    画直线: var c = document.getElementById("myCanvas"); //不要忘写document var ctx = c.getContext(&q ...

  5. LCIS HDOJ 4512 吉哥系列故事——完美队形I

    题目传送门 题意:中文题面 分析:LCIS应用:设置b[]为a[]的反转,然后LCIS,若相等的是自己本身,则+1, 否则+2 代码: #include <cstdio> #include ...

  6. LMT 装机记录

    老毛桃是一个存在很久的文物了,当年在大学的时候,学习委员还专门做了一个PPT来讲老毛桃,现在想想,有点后悔那是不去试一下. 但万幸的是,最近终于彻底理解了工作流程: 1)安装一个LMT的软件,从其官网 ...

  7. POJ2396 Budget(有源汇流量有上下界网络的可行流)

    题目大概给一个有n×m个单元的矩阵,各单元是一个非负整数,已知其每行每列所有单元的和,还有几个约束条件描述一些单元是大于小于还是等于某个数,问矩阵可以是怎样的. 经典的流量有上下界网络流问题. 把行. ...

  8. okhttp3 get post 简单封装

    最近打算在新项目中使用 okhttp3, 简单封装了一下异步 get post 因为 CallBack 也是在子线程中执行,所以用到了 Handler public class MyOkHttpCli ...

  9. 三角形[HDU2039]

    三角形 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  10. 洛谷 P1313 计算系数 Label:杨辉三角形 多项式计算

    题目描述 给定一个多项式(by+ax)^k,请求出多项式展开后x^n*y^m 项的系数. 输入输出格式 输入格式: 输入文件名为factor.in. 共一行,包含5 个整数,分别为 a ,b ,k , ...