[Laravel] where와 orWhere를 사용함에 주의해야 할 점

 

Laravel Queries

 

 

환경


Laravel v9.5.1 (PHP v8.1.3)

 

목표


SQL로 “조건A”이고 “조건B이거나 조건C”의 정보를 가지고 온다.

(부서ID가 1이고 권한이 소유권한이거나 관리권한의 정보를 가지고 온다.)

 

올바른 취득 방법


User::where('role', UserRole::Owner->value)
    ->orWhere('role', UserRole::Admin->value)
    ->where('department_id', 1)->get();

=> Illuminate\Database\Eloquent\Collection {#4690
     all: [
       App\Models\User {#4689
         id: 1,
         name: "장원영",
         email: "jangwonyoung123@gmail.com",
         department_id: 1,
         role: 1,
       },
     ],
   }

소유권한이거나 관리자권한이고 부서ID가 1의 데이터를 올바르게 가져오는 예시이다.

검색의 where보다 OR검색의 orWhere먼저 있기 때문에 우선된다.

따라서 “Role이 1이거나 2”이고 “부서ID가 1”의 유저를 가지고 올 수 있다.

select * from `users` where (`role` = ? or `role` = ?) and `department_id` = ?

 

잘못된 취득 방법


User::where('department_id', 1)
    ->where('role', UserRole::Owner->value)
    ->orWhere('role', UserRole::Admin->value)->get();

=> Illuminate\Database\Eloquent\Collection {
     all: [
       App\Models\User {
         id: 1,
         name: "장원영",
         email: "jangwonyoung123@gmail.com",
         department_id: 1,
         role: 1,
       },
       App\Models\User {
         id: 2,
         name: "김민정",
         email: "kimminjung123@gmail.com",
         department_id: 2,
         role: 2,
       },
     ],
   }

다른부서의 관리자권한을 가진 유저도 취득하게 된다. (김민정은 부서2의 유저)

 

OR보다AND쪽이 우선 되기 때문에 “부서가 1이고 Role이 1” 또는 “Role이 2” 인 유저를 가져오게 된다.

Where검색의 순서가 바뀌는것뿐 검색 결과가 전혀 달라지게 된다.

select * from `users` where `department_id` = ? and `role` = ? or `role` = ?

 

한국어 매뉴얼


https://laravel.kr/docs/9.x/queries

 

더 좋은 코딩 방법으로는


User::where('department_id', 1)->where(function ($query) {
    $query->where('role', UserRole::Owner->value)
        ->orWhere('role', UserRole::Admin->value);
})->get();

이렇게 사용하면 조금 길어질 수 있지만 한눈에 어디가 그룹화 되어 있는지 알기가 쉽게 쓸 수 있다.

select * from `users` where `department_id` = ? and (`role` = ? or `role` = ?)

SQL을 보더라도 OR를 괄호로 그룹화 시켜 “부서가 1” 이고 “Role이 1 이거나 2” 인 유저의 결과를 가지고 올 수 있다.

보다 간결하게 사용하려면…

// 방법1
User::whereIn('role', [UserRole::Owner->value, UserRole::Admin->value])
    ->where('department_id', 1)->get();

// 방법2
User::where('department_id', 1)->where(function ($query) {
    $query->whereIn('role', [UserRole::Owner->value, UserRole::Admin->value]);
})->get()

그룹화하지 않고도 whereIn을 사용해 보다 간결하게 쓸 수 있다.

 

마무리


검색해 가져오는 결과가 같더라도 다른 사람이 코드를 봤을 때

한눈에 이해되기 쉽게 되도록 쓸 수 있는 코딩하는 것은

본인의 실력 향상에도 중요한 것이기 때문에

입문때 부터 습관들이는 것이 중요하다.

 

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤