[置顶] 让我爱恨的ThinkPHP Relation
还记得第一次用ThinkPHP的relation,做了一个关联查询,觉得特别好用。有那么一天尝试着用关联插入,怎么插,都插不进,我插,我擦!
后来在龙哥的指点下算是成功的实践了一次,后来怎么用都不顺,后来变远离了 relation,便觉得这是TP 本身的问题,却不知是自己没有找到问题的症结,还是编程届
的那句谚语说的好,你没有了解出现问题的真正原因,就不算解决了BUG。
最近公司做接口,两张表一对多的关系, 正常查询的话(select tag.*, evaluate.* from tbl_tag as tag,tbl_evaluate as evaluate where(tag.tag_id = evaluate.tag_id))是多条记录,而需要返回如下的JSON数据:
{
    "ret": "0",
    "msg": "ok",
    "data": [
         {
            "tag_id": "1226",
            "name": "软件故障类",
            "type": "1",
            "Icon": "/style/images/sortImgs/small/",
            "created_at": "1373383665",
            "status": "1",
            "explain": "暂无",
            "changed_at": "1373383665",
            "evaluate_count": "5",
            "contents_type": "1",
            "process_id": null,
            "evaluate": [
                {
                    "evaluate_id": "4",
                    "tag_id": "1226",
                    "name": "任务创建时间",
                    "limit_time": "0",
                    "alert_time": "0",
                    "position": "1",
                    "description": null,
                    "isfixed": null,
                    "status": null,
                    "remark": null
                },
                {
                    "evaluate_id": "5",
                    "tag_id": "1226",
                    "name": "任务分配时间",
                    "limit_time": "10",
                    "alert_time": "5",
                    "position": "1",
                    "description": null,
                    "isfixed": null,
                    "status": null,
                    "remark": null
                },
                {
                    "evaluate_id": "6",
                    "tag_id": "1226",
                    "name": "任务领取时间",
                    "limit_time": "15",
                    "alert_time": "3",
                    "position": "1",
                    "description": null,
                    "isfixed": null,
                    "status": null,
                    "remark": null
                },
                {
                    "evaluate_id": "7",
                    "tag_id": "1226",
                    "name": "任务开始时间",
                    "limit_time": "60",
                    "alert_time": "20",
                    "position": "1",
                    "description": null,
                    "isfixed": null,
                    "status": null,
                    "remark": null
                },
                {
                    "evaluate_id": "8",
                    "tag_id": "1226",
                    "name": "任务结束时间",
                    "limit_time": "240",
                    "alert_time": "30",
                    "position": "1",
                    "description": null,
                    "isfixed": null,
                    "status": null,
                    "remark": null
                }
            ]
        },
        {
            "tag_id": "1229",
            "name": "改进后的任务我22",
            "type": "1",
            "Icon": "/style/images/sortImgs/small/",
            "created_at": "1373700085",
            "status": "1",
            "explain": null,
            "changed_at": "1373700979",
            "evaluate_count": "5",
            "contents_type": "1",
            "process_id": null,
            "evaluate": [
                {
                    "evaluate_id": "10",
                    "tag_id": "1229",
                    "name": "时间1",
                    "limit_time": "11",
                    "alert_time": "6",
                    "position": "1",
                    "description": null,
                    "isfixed": null,
                    "status": null,
                    "remark": null
                }
            ]
        },
        {
            "tag_id": "1230",
            "name": "维修任务修改2",
            "type": "1",
            "Icon": "/style/images/sortImgs/small/",
            "created_at": "1373714061",
            "status": "1",
            "explain": null,
            "changed_at": "1373715337",
            "evaluate_count": "2",
            "contents_type": "1",
            "process_id": null,
            "evaluate": [
                {
                    "evaluate_id": "11",
                    "tag_id": "1230",
                    "name": "执行时间1",
                    "limit_time": "4",
                    "alert_time": "3",
                    "position": "1",
                    "description": null,
                    "isfixed": "1",
                    "status": "1",
                    "remark": null
                },
                {
                    "evaluate_id": "12",
                    "tag_id": "1230",
                    "name": "执行时间1",
                    "limit_time": "5",
                    "alert_time": "4",
                    "position": "2",
                    "description": null,
                    "isfixed": "1",
                    "status": "1",
                    "remark": null
                }
            ]
        }
   ]
}
阅读别人的代码的时候,发现TP的 relation能返回这样的数据,好了,躲不掉的Relation
马上我就又凌乱了,之前的TP直接继承RelationModel,关联查询 so easy, 关键是公司继承了BaseModel,各种研究,各种陌生
/**
* 通过id查询标签
*/
public function show(){
		//自动校验
		$dr_tag=D('Tag');
		$condition=$dr_tag->create($_GET);
		if( false === $condition) exit(RS::jsonReturn($dr_tag->getError()));
		$dr_process = D('Process');
		$dr_process = $dr_process->switchModel ( 'Relation' );
		$linklist = ProcessModel::get_link ( 'this' );
		$dr_process->setProperty ( '_link', $linklist );
		$field = TagModel::getObjFields ( 'this' );
		$tags_id=$condition['tags_id'];
		$name=$condition['name'];
		$explain=$condition['explain'];
		if(empty($tags_id) && empty($name) && empty($explain)) exit(RS::jsonReturn("20001"));
		//查询条件
		if (!empty ( $tags_id)) $where ['tbl_tag.tag_id'] = array ('eq', $condition['tags_id'] );
		if (!empty ( $condition ['name'] )) $where ['tbl_tag.name'] = array ('eq', $name );
		if (!empty ( $condition ['explain'] )) $where ['tbl_tag.explain'] = array ('like','%'.$explain.'%');
		$where['tbl_tag.tag_id'][]=array('neq',999);
		$field[] = 'tbl_tag.tag_id';
		$field[] = 'tbl_tag.name';
		$field[] = 'tbl_tag.type';
		$field[] = 'tbl_tag.status';
		$field[] = 'tbl_tag.Icon';
		$field[] = 'tbl_tag.created_at';
		$field[] = 'tbl_tag.changed_at';
		$field[] = 'tbl_tag.explain';
		$field[] = 'tbl_tag.contents_type';
		$field[] = 'tbl_tag.process_id';
		$field[] = 'tbl_process.process_count';
		$data = $dr_process->field ( $field )
		->join ( 'right join tbl_tag ON tbl_tag.process_id = tbl_process.process_id' )
		->where ( $where )
		->relation ( true )
		->find();
		//返回数据
		if(empty($data)) exit(RS::jsonReturn("20000"));
		echo RS::jsonReturn("0",$data,"ok");
	}
照猫画虎,自己来一个,尽管搞不明白:
$linklist = ProcessModel::get_link ( 'this' );
$dr_process->setProperty ( '_link', $linklist );
//关联,显示所有任务类型和指标详情
protected function tagsShow_link(){
return array(
'evaluate'=>array(
'mapping_type' => HAS_MANY,
'class_name'=>'Evaluate',
'foreign_key'=>'tag_id',
//'mapping_name' =>'indexs',
'mapping_fields_name' =>'this'
),
); } /* 返回字段 */
public static function tagsShowObjFields(){
$ObjFields = self::$allObjFields;
foreach ($ObjFields as $key=>$val){
if('notifications_enabled' === $val) unset($ObjFields[$key]);
}
return $ObjFields;
}
结果就是出不来结果,Relation不出来,出来的就是关联的是false
源于不明白这个get_link和 setProperty总是以为是这里出了批漏,各种查,各种对比,各种纠结,一个人,在周六
$linklist = ProcessModel::get_link ( 'this' );
$dr_process->setProperty ( '_link', $linklist );
找到了一条靠谱的解决方法,是改RelationModel下面的M 方法为D ( http://lhdeyx.blog.163.com/blog/static/318196972010112351516763/),我打开一看,晕死了,就是D;
之前都是在物理上实现外键约束的,现在是在逻辑上实现,以为Relation关联不上错在这里,实际上是无关的
无奈了,最后,想SQL语句,一开始就想到了,下面的,觉得可行,就是效率太低,PASS
$tag = D('Tag');
		$evaluate = D('Evaluate');
		$tag_ids = $tag->getField('tag_id,name');
		if(isset($_GET['since_at']) && !empty($_GET['since_at'])){
			$since_at = $_GET['since_at'];
			$condition['changed_at'] = array('gt',$since_at);
		}
		//echo $tag->getLastSQl();die();
		foreach($tag_ids as $key=>$val){
			$map['tag_id'] = array('eq',$key);
			$condition['tag_id'] = array('eq',$key);
			$result = $tag->where($condition)->find();
			$res = $evaluate->where($map)->select();
			$result['indexs'] = $res;
			$data[] = $result;
		}
		//返回数据
		if(empty($data)) exit(RS::jsonReturn("20000"));
		echo RS::jsonReturn("0",$data,"ok");
后来就google大神,论坛,以至于差点用起了行列转换
--行列转换模型
select name 姓名,
max(case subject when '语文' then result else 0 end) 语文,
max(case subject when '数学' then result else 0 end) 数学,
max(case subject when '物理' then result else 0 end) 物理
from tb
group by name
纠结在继续,
在sql搞不定之后,回到了Relation,还是搞不定,夜很静了,我只能简单粗暴了,一开始的sql.
…………
方姐,来了,观察了一下情况,该有的都有了,于是
$data = $dr_tag->relation(true)->select();
$evaluate = D('Evaluate');
echo $evaluate->getLastSql();die('dd');
我一下就反映过来了,告诉TA是limit_time,后来改了Model中的字段
sudo rm -rf *,TA迷人的样子让我折服,轻轻的在我耳边说,该了Model要删缓存,Ta 说的那么轻描淡写,我觉永远记住了
我之前也
echo $dr_tag->getLastSql();die('dd');提示的错误让人更纠结。回想Ta 解决BUG缜密思路,我…………
提示你false, 我永远都不知道用被关联的表evaluate实例化后输出,直到Ta 展示给我
爱上了Relation, 爱上……
[置顶] 让我爱恨的ThinkPHP Relation的更多相关文章
- 爱pia戏推出PC客户端,为您自动置顶窗口,方便查找
		
爱pia戏推出PC客户端, 可以在无法使用插件的时候,使用PC客户端, 将为您自动置顶窗口,方便查看剧本. 百度网盘下载地址: 链接: http://pan.baidu.com/s/1pLpvn5p ...
 - Menu与ActionBar的爱恨情仇
		
最近在开发一款音乐播放器,在开发过程中遇到了一点小麻烦,通过android API搞清楚了Menu与ActionBar的爱恨情仇,写了个小Demo祭奠一下那些年我们陷进去的坑,有不对的地方请大神们批评 ...
 - 在UWP中页面滑动导航栏置顶
		
最近在研究掌上英雄联盟,主要是用来给自己看新闻,顺便copy个界面改一下段位装装逼,可是在我copy的时候发现这个东西 当你滑动到一定距离的时候导航栏会置顶不动,这个特性在微博和淘宝都有,我看了@ms ...
 - WinFrom窗体始终置顶
		
调用WindowsAPI使窗体始终保持置顶效果,不被其他窗体遮盖: [DllImport("user32.dll", CharSet = CharSet.Auto)] privat ...
 - web移动端fixed布局和input等表单的爱恨情仇 - 终极BUG,完美解决
		
[问题]移动端开发,ios下当fixed属性和输入框input(这里不限于input,只要可以调用移动端输入法的都包括,如:textarea.HTML5中contenteditable等),同时存在的 ...
 - winform窗体置顶
		
winform窗体置顶 金刚 winform 置顶 今天做了一个winform小工具.需要设置置顶功能. 网上找了下,发现百度真的很垃圾... 还是必应靠谱些. 找到一个可以链接. https://s ...
 - 自定义置顶TOP按钮
		
简述一下,分为三个步骤: 1. 添加Html代码 2. 调整Css样式 3. 添加Jquery代码 具体代码如下: <style type="text/css"> #G ...
 - ahk之路:利用ahk在window7下实现窗口置顶
		
操作系统:win7 64位 ahk版本:autohotkey_L1.1.24.03 今天安装了AutoHotkey_1.1.24.03.SciTE.PuloversMacroCreator,重新开始我 ...
 - Qt中让Qwidget置顶的方法
		
一般来是说窗体置顶和取消只要 setWindowFlags(Qt::WindowStaysOnTopHint); setWindowFlags(Qt::Widget); 要 ...
 
随机推荐
- 吞吐量(Throughput)、QPS、并发数、响应时间(RT)对系统性能的影响
			
首先对吞吐量().QPS.并发数.响应时间(RT)几个概念一直比较模糊,也不知道哪些指标可以较好的衡量系统的性能.今天特意查了些资料做一些记录:首先看一些概念(来自百度百科) 1. 响应时间(RT) ...
 - ActionScript GifPlayer的修改
			
ActionScript不能播放gif格式的图片,在做as项目的时候如果需要用到加载gif动画图片时,就需要引入第三方包. 常用的第三方包是GifPlayer,在github上可以找到该项目的源代码C ...
 - PCIe固态存储和HDD常见的硬盘性能对比测试
			
2周测试后,导致以下结果 MySQL-OLTP测试结果:(50表.每个表1000广域网数据,1000个线程) TPS:MySQL在PCIe固态存储上执行是在HDD上执行的5.63倍 writes:My ...
 - Visual Studio 2015环境
			
Visual Studio 2015环境搭建 2014年11月13日,微软发布了Visual Studio 2015 Preview,跟随者Visual Studio 2015 而来的是,.net 开 ...
 - SQL Server中生成测试数据
			
原文:SQL Server中生成测试数据 简介 在实际的开发过程中.很多情况下我们都需要在数据库中插入大量测试数据来对程序的功能进行测试.而生成的测试数据往往需要符合特定规则.虽然可以自己写 ...
 - Scala从零开始:使用Intellij IDEA写hello world
			
Scala从零开始:使用Intellij IDEA写hello world 分类: Scala |2014-05-23 00:39 |860人阅读 引言 在之前的文章中,我们介绍了如何使用Scal ...
 - Cocos2d-x在Android在竖屏切换
			
在Cocos2d-x在,屏幕类型的默认设置是横屏,当我们需要切换到肖像,能够在项目目录打开proj.android目录.找到AndroidManifest.xml文件,直接打开,然后就可以看到里面:s ...
 - 九度OJ 1035:找出直系亲属(二叉树)
			
题目1035:找出直系亲属 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1309 解决:521 题目描述: 如果A,B是C的父母亲,则A,B是C的parent,C是A,B的child,如 ...
 - 【值得收藏】数据分析和可视化软件IDL的学习资料汇编【可免费下载】
			
IDL学习教程 IDL 是一种数据分析和图像化应用程序及编程语言,最初在七十年代后期用于帮助科学家分析火星探险卫星发回的数据.此后,IDL得到广泛运用,使用者日众.IDL能使用户可以迅速且方便地运用此 ...
 - nutch solr 配置
			
http://blog.csdn.net/panjunbiao/article/details/12171147 后半部分实践通过