传统的 mvc框架 下,都需要从 controller 层分配数据,在 view 层中渲染。在列表视图页中,我们时常会遇到如下的场景:
分案时间 | 分案对象 | 分案金额 | 分案笔数 |
2019-10-10 13:02:20 | 委外机构1 | 772.20 | 10 |
2019-10-10 10:12:32 | 委外机构2 | 1092.22 | 21 |
... | ... | ... | ... |
注意上面的“分案对象”这一栏,这一栏在视图中读取的数据是对象id,在页面中需要渲染对象名称,这种情况下,就需要我们封装一个函数 getObjName(),将对象id转化为对象名称。
在Laravel5框架中,我一般会自己封装一个常用的函数,比如 /bootstrap/helper.php,用来封装一些常用的自定义函数。
如果我们按照正常思路来封装这个转化函数,大概实现方式是这样的:
function getObjName($id){
$obj = \App\Models\ObjModel::find(id);
return $obj->name;
}
这种方式虽然能实现将对象id转化为对象名称的需求,但是效率特别低。主要问题在于,加入页面有20条数据,就要调用20次 getObjName($id) ,进而要进行20次find查询。
想要优化这个问题,关键在于减少数据库查询次数,优化的方法有多种,比如说将查询内容做缓存,就是一种处理方案,实现方案也比较简单,在这里我就不过多赘述了。
除了缓存方法,我还想给大家介绍另一种比较巧妙的方法:使用静态变量,缓存单次请求的重复调用问题。
function getObjName($id){
static $objArr = [];
if(!isset($objArr[$id])){
$obj = \App\Models\ObjModel::find(id);
$objArr[$id] = $obj->name;
}
return $objArr[$id];
}
这样,就可以避免同一个id,多次重复查询的情况。
当然如果列表中id的分布广、重复少,这种优化方案效果不大,依然会有很多次查库操作,这种情况下,我们可以对以上方案做一个简单的修改:
function getObjName($id){
static $objArr = [];
if(!$objArr){
$objArr = \App\Models\ObjModel::pluck('name','id')->toArray();
}
return isset($objArr[$id])?$objArr[$id]:'--';
}
这样我们只需要将obj表中的数据,一次全部查询出来做缓存,一次请求的多次调用就不会重发查表了。当然这种方案也只适合obj表中数据量较少的情况。
具体情况应该如何处理,大家合理评估,这里只是给大家提供另一种思路,做抛砖引玉。
本文为 陈华 原创,欢迎转载,但请注明出处:http://edu.ichenhua.cn/read/16