Laravel拆分Object表后,如何获取指定分类的全部对象?
解决方案
要实现指定分类下所有对象的查询,核心思路是合并不同Object派生类对应的关联查询结果,下面提供两种高效实现方式:
方式一:查询构建器层面合并(推荐,性能最优)
通过unionAll将多个belongsToMany关联的SQL查询合并为单次查询,适合所有Object派生类表结构一致的场景:
public function getAllObjects() { // 获取所有启用的Object派生类类名 $objectTypes = $this->getEnabledObjectTypes(); $combinedQuery = null; foreach ($objectTypes as $type) { // 为当前对象类型创建关联 $relation = $this->belongsToMany( $type, $type::TABLE_CATEGORIES, $type::COL_CATID, $type::COL_OBJID ); $currentQuery = $relation->getQuery(); // 合并查询:首次直接赋值,后续用unionAll拼接 if (is_null($combinedQuery)) { $combinedQuery = $currentQuery; } else { // 确保所有表的字段数量、类型一致,否则unionAll会报错 $combinedQuery->unionAll($currentQuery); } } return $combinedQuery ? $combinedQuery->get() : collect(); }
注意事项
- 所有
Object派生类必须保证表结构完全一致(字段名、类型、数量匹配),否则unionAll会触发SQL错误。 - 如需添加筛选条件(如
where('status', 1)),可在$currentQuery上直接追加:$currentQuery->where('status', 1);。 - 支持直接调用
paginate()实现分页:return $combinedQuery ? $combinedQuery->paginate(15) : collect();。
方式二:集合层面合并(灵活,适配表结构差异)
如果不同Object派生类的表结构存在差异,可先分别查询每个类型的对象,再合并为一个集合:
public function getAllObjects() { $objectTypes = $this->getEnabledObjectTypes(); $allObjects = collect(); foreach ($objectTypes as $type) { $objects = $this->belongsToMany( $type, $type::TABLE_CATEGORIES, $type::COL_CATID, $type::COL_OBJID )->get(); $allObjects = $allObjects->merge($objects); } return $allObjects; }
优缺点
- 优点:无需严格统一表结构,适配更多场景。
- 缺点:会触发多次SQL查询,数据量较大时性能不如方式一;分页需自行处理集合切片逻辑。
内容的提问来源于stack exchange,提问作者badluck
相关产品推荐
相关产品推荐

