首页 > 解决方案 > Laravel Query Builder Join vs With Function,哪个更好?

问题描述

我想问一下 Laravel Query 使用Join还是With哪个更好。

在这种情况下,我尝试了一个简短的查询。但是有一些事情让我想知道。

就我而言,我正在尝试使用 API 创建用户列表。问题在于对数据进行排序

问题分为几个。

  1. 如果我使用With。使用 with 的好处是我可以调用模型中的属性,而无需重写我要使用的属性。但是当我调用与其他表相关的数据进行排序时,我感到很困惑。示例查询:
     /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $sortBy = $request->query('sortBy');
        $sortDesc = (is_null($request->query('sortDesc'))) ? $request->query('sortDesc') : ($request->query('sortDesc') == 'true' ? 'desc' : 'asc');
        $page = $request->query('page');
        $itemsPerPage = $request->query('itemsPerPage');
        $search = $request->query('search');
        $starDate = $request->query('start');
        $endDate = $request->query('end');

        $start = ($page - 1) * $itemsPerPage;

        $query = MemberRegular::query();
        $query->with(['users' => function ($subQuery) {
            $subQuery->select('id', 'name', 'email', 'phone');
        }]);
        $query->select(
            'id',
            'code'
        );

        if ($search) {
            $query->where(function ($subQuery) use ($search) {
                $subQuery->where('code', 'like', '%' . $search . '%');
                $subQuery->orWhere(function ($q) use ($search) {
                    $q->whereHas('users', function ($j) use ($search) {
                        $j->where('name', 'like', '%' . $search . '%');
                        $j->orWhere('email', 'like', '%' . $search . '%');
                    })
                });
            });
        }

        if ($sortBy && $sortDesc) {
            $query->orderBy($sortBy, $sortDesc)->orderBy('id', 'desc');
        } else {
            $query->orderBy('created_at', 'desc')->orderBy('id', 'desc');
        }

        if ($starDate && $endDate) {
            $query->whereBetween('created_at', [$starDate, $endDate]);
        }
        $data['totalItems'] = $query->count();
        $data['items'] = $query->skip($start)->take($itemsPerPage)->get();
        return HResource::collection($data['items'])->additional(['totalItems' => (int) $data['totalItems']], true);
    }
  1. 如果我使用Join。使用Join的好处是,如果数据与其他表相关,我可以轻松地对数据进行排序。但是我必须在集合中重新创建一个新属性。示例查询:
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $sortBy = $request->query('sortBy');
        $sortDesc = (is_null($request->query('sortDesc'))) ? $request->query('sortDesc') : ($request->query('sortDesc') == 'true' ? 'desc' : 'asc');
        $page = $request->query('page');
        $itemsPerPage = $request->query('itemsPerPage');
        $search = $request->query('search');
        $starDate = $request->query('start');
        $endDate = $request->query('end');

        $start = ($page - 1) * $itemsPerPage;

        $query = MemberRegular::query();
        $query->join('users', 'users.id', '=', 'member_regulars.user_id');
        $query->select(
            'member_regulars.id',
            'member_regulars.code',
            'users.name',
            'users.email',
            'users.phone'
        );

        if ($search) {
            $query->where(function ($subQuery) use ($search) {
                $subQuery->where('member_regulars.code', 'like', '%' . $search . '%');
                $subQuery->orWhere('users.name', 'ilike', '%' . $search . '%');
                $subQuery->orWhere('users.email', 'ilike', '%' . $search . '%');
                $subQuery->orWhere('users.phone', 'ilike', '%' . $search . '%');
            });
        }

        if ($sortBy && $sortDesc) {
            $query->orderBy($sortBy, $sortDesc)->orderBy('member_regulars.id', 'desc');
        } else {
            $query->orderBy('member_regulars.created_at', 'desc')->orderBy('member_regulars.id', 'desc');
        }

        if ($starDate && $endDate) {
            $query->whereBetween('member_regulars.created_at', [$starDate, $endDate]);
        }
        $data['totalItems'] = $query->count();
        $data['items'] = $query->skip($start)->take($itemsPerPage)->get();
        return HResource::collection($data['items'])->additional(['totalItems' => (int) $data['totalItems']], true);
    }
  1. 如果使用Query With问题在于发送如下users.name这样的sortBy参数会报错,因为我做的查询中没有找到表,但是我可以立即调用可以直接使用的属性而无需创建一个新的自定义属性。

  2. 如果使用 Query Join,问题是我必须重新创建要在数据集合中使用的自定义属性,但我不需要担心对数据进行排序

两者对我来说同样重要。但是,如果有人愿意就这种情况下我必须使用JoinWith的最佳方式提供建议。

谢谢你。

标签: phplaravelpostgresql

解决方案


最后,我找到了解决我所面临问题的最佳方法。我希望这可以帮助其他人。

这里我选择使用Join为什么?因为事实证明我可以在我创建的模型中调用函数关系users()以便我仍然可以在用户模型中检索自定义属性。我真的不知道这是否是正确的方法。我希望这对其他人有帮助。

谢谢你。


推荐阅读