Laravel查询父模型时如何预加载关联?Address与Kontokorrent表应用
如何在查询Address模型时预加载关联的Kontokorrent模型
嘿,我来帮你搞定这个问题!在Laravel里,要避免N+1查询并预加载关联模型,用with()方法就可以轻松实现,下面给你详细说怎么修改你的代码:
基础预加载实现
你只需要在初始化Address查询链的时候,加上with('kontokorrent'),就能一次性把关联的Kontokorrent数据和Address数据一起拉取回来。这样后续遍历Address并访问kontokorrent属性时,就不会触发额外的SQL查询了。
修改后的完整代码示例:
// 初始化查询,同时预加载kontokorrent关联 $addresses = Address::with('kontokorrent') ->whereHas('kontokorrent', function($query) { $query->ktoArt('D')->mandant(1)->aktiv(); }); // 条件判断 if(Auth::user()->activeAddress) { $addresses->where('Aktiv', '<>', 0); } $addressesFormated = $addresses->get()->map(function($item, $key) { return [ 'addresse' => $item->Adresse, 'kto' => $item->kontokorrent->KtoNr, // 补全你需要的具体字段,比如KtoNr // 其他需要返回的字段 ]; });
进阶:给预加载的关联加筛选条件
如果你的Address模型可能关联多个Kontokorrent记录,而你只想预加载和whereHas里条件一致的那一条,还可以给with()传一个闭包,对预加载的关联数据也做筛选:
$addresses = Address::with(['kontokorrent' => function($query) { // 和whereHas里相同的筛选条件,确保预加载的是符合要求的关联数据 $query->ktoArt('D')->mandant(1)->aktiv(); }]) ->whereHas('kontokorrent', function($query) { $query->ktoArt('D')->mandant(1)->aktiv(); });
这样预加载的kontokorrent就只会是符合你指定条件的那条数据,避免加载无关的关联记录。
为什么要这么做?
预加载能有效解决N+1查询问题:如果不预加载,当你遍历每个Address并访问kontokorrent时,Laravel会为每一条Address单独执行一次查询去拉取关联数据,数据量越大性能越差;而预加载只需要两次查询(一次查Address,一次查对应的Kontokorrent),性能提升非常明显。
内容的提问来源于stack exchange,提问作者Greg Ostry
相关产品推荐
相关产品推荐

