分享一个自己写的基于TP的关系模型
为了说明问题,假设现在有表test1,test1有从表test2;test1属于test3,test1和test4多对多,关联表test1_test4。
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 ]