分享一个自己写的基于TP的关系模型
2015-06-19 16:53
826 查看
为了说明问题,假设现在有表test1,test1有从表test2;test1属于test3,test1和test4多对多,关联表test1_test4。
1.定义关系
关系方法:hasOne,hasMany,belongsTo
参数一:模型名或则表明
参数二 : 关联字段
2.预加载
基本用法:
预加载并加入查询条件
如果需要同时加载多个关系模型可如下调用:
3.延时加载
基本用法:
带过滤条件:
4.其他扩展和优化
需要特别注意的是,在我们使用field等类似方法过滤字段的时候,记得一定要查询关联字段,否则关联查询会出错,其次在关联字段上进行查询过滤的时候,不要使用数组的形式,原因是TP在where时会使用array_merge合并条件,而我在处理关联查询时会使用关联字段进行in查询,并在这里我是用数组的形式写的,如果有需要可以将此处改为字符串形式,则可以解决该问题
下面说说查询的思路:
所有查询都是在主表先完成查询,之后获取主键,再去关联表做in查询,然后在PHP中合并结果,所以使用关联查询也有它的局限性,当我们需要关联表做条件过滤主表数据的时候,关联查询便不太适用.
下载
1.定义关系
class Test1Model extends WdModel { public function test2(){ return $this->hasOne('Test2','test1_id'); } public function test3(){ return $this->hasMany('Test3','test1_id'); } }
class Test2Model extends WdModel { public function test1(){ return $this->belongsTo('Test1','test1_id'); } }
关系方法:hasOne,hasMany,belongsTo
参数一:模型名或则表明
参数二 : 关联字段
2.预加载
基本用法:
$test1 = D('Test1'); $rs = $test1->with('test2')->select();
预加载并加入查询条件
$rs = $test2->with(array('test1',function($query){ $query->field('id,name')->where('id=2'); }))->select();
如果需要同时加载多个关系模型可如下调用:
$this->with('business','category','bag','admin',array('log',function($query){ $query->where(array('gl_code'=>43)); }),array('sku',function($query){ $query->field("min(ss_cprice) as ss_cprice,ss_sa_id")->where("ss_number > 0")->group('ss_sa_id'); }));
3.延时加载
基本用法:
$test1 = D("Test1"); $test1->where(array('id'=>1))->find(); print_r($test1->test2);
带过滤条件:
$test1 = D("Test1"); $test1->where(array('id'=>1))->find(); $rs = $test1->has('test3',function($query){ $query->where('id >= 2'); });
4.其他扩展和优化
方法名 | 参数 | 参数说明 |
whereIn | $field,$vales | 简化in查询,$filed:查询字段,$valus:数组 |
mapWhere | $conditions | 在原有where方法的基础上加入了别名识别,即原模型的$_map属性的识别 |
map | $field | 将别名映射为对应的数据库字段 |
isDirty | 检查模型的属性是否修改,只对使用了find方法的单条数据有效 | |
getDirty | 获取修改过的字段,只对使用了find方法的单条数据有效 | |
save | 优化原有的保存方法,在原有基础上加入脏检查 | |
except | $filed | 排除那些字段不查询,可接收多个参数 |
$test1 = D("Test1"); $test1->where(array('id'=>1))->find(); $test1->name = "222222"; var_dump($test1->isDirty('name')); print_r($test1->getDirty()); $test1->save();
需要特别注意的是,在我们使用field等类似方法过滤字段的时候,记得一定要查询关联字段,否则关联查询会出错,其次在关联字段上进行查询过滤的时候,不要使用数组的形式,原因是TP在where时会使用array_merge合并条件,而我在处理关联查询时会使用关联字段进行in查询,并在这里我是用数组的形式写的,如果有需要可以将此处改为字符串形式,则可以解决该问题
下面说说查询的思路:
所有查询都是在主表先完成查询,之后获取主键,再去关联表做in查询,然后在PHP中合并结果,所以使用关联查询也有它的局限性,当我们需要关联表做条件过滤主表数据的时候,关联查询便不太适用.
SQL: SHOW COLUMNS FROM `test1` [ RunTime:0.002687s ] SQL: SELECT * FROM `test1` WHERE ( `id` = 1 ) LIMIT 1 [ RunTime:0.000425s ] SQL: SHOW COLUMNS FROM `test3` [ RunTime:0.002623s ] SQL: SELECT * FROM `test3` WHERE ( id > 2 ) AND ( `test1_id` IN ('1') ) [ RunTime:0.000405s ]
SQL: SHOW COLUMNS FROM `test1` [ RunTime:0.001573s ] SQL: SELECT * FROM `test1` [ RunTime:0.000262s ] SQL: SHOW COLUMNS FROM `test2` [ RunTime:0.001488s ] SQL: SELECT * FROM `test2` WHERE ( `test1_id` IN ('1','2','3','4','5') ) [ RunTime:0.000313s ]
下载
相关文章推荐
- php简单统计字符串单词数量的方法
- PHP对文件夹递归执行chmod命令的方法
- php强制用户转向www域名的方法
- php自动更新版权信息显示的方法
- php衣食父母之3-php利用HHVM实现高性能
- Yii2 学习日志------view form标签
- PHP实现同服务器多个二级域名共享 SESSION
- PHP CI框架学习笔记-分页实现程序
- php中Snoopy类用法实例
- PHP正则把"2010-12-20"替换成"12/20/2010"
- lftp命令使用
- php计算整个目录大小的方法
- php简单计算页面加载时间的方法
- PHP通过session id 实现session共享和登录验证的代码
- Yii2 学习日志------多语言
- php实现随机生成易于记忆的密码
- php数组中删除元素,再重新索引
- 【php】利用新浪api接口与php获取远程数据的方法,获取IP地址,并获取相应的IP归属地
- php根据一个给定范围和步进生成数组的方法
- php分割合并两个字符串的函数实例