CASE 표현식을 사용하여 검색 항목이 비어 있는 경우 조건을 무시합니다.

if 문을 사용하지 않고 SQL의 CASE 식에서 null을 무시한 검색 수행



이하와 같은 형태로 검색에 사용하는 입력 항목이 몇개도 있었을 경우에, 컨트롤러측에서 if문을 사용해 공란시와 그렇지 않은 경우의 경우 나누기를 하면 if/else가 쭉 늘어서서, 비슷한 메서드를 여러 개 사용하여 코드가 더러워지기 때문에 SQL에서 어떻게 할 수 없는지 여러가지 조사해 보았는데 SQL의 CASE 식을 사용하면 if 문을 사용하지 않고 더 스마트하게 코드를 걸는 것을 알았다. 그래서 비망록으로 남깁니다.


repository.java
    @Query(value = "SELECT * FROM mst_asset" 
                 + " WHERE id = CASE WHEN :id = 0 THEN id ELSE :id END" 
                 + " AND category_id = CASE WHEN :categoryId = 0 THEN category_id ELSE :categoryId END" 
                 + " AND admin_name LIKE concat('%', CASE WHEN :adminName = '' THEN admin_name ELSE :adminName END, '%')"
                 + " AND asset_name LIKE concat('%', CASE WHEN :assetName = '' THEN asset_name ELSE :assetName END, '%')" 
                 + " AND delete_flag = false ORDER BY id ASC"
                 +  , nativeQuery = true)
    List<Asset> findByIdAndCategoryIdAndAdminNameAndAssetName(
        @Param("id") Integer id,
        @Param("categoryId")Integer categoryId,
        @Param("adminName") String adminName,
        @Param("assetName") String assetName);

분명히 WHERE 절의 [컬럼 이름] = [컬럼 이름]의 경우에는 조건으로 카운트하지 않는다는 성질이있는 것 같고 그것을 CASE 식에 응용하여 화면에서 검색 키워드가 입력되지 않은 파라미터를 무시합니다. SQL을 실행할 수 있는 것 같다.
상기의 코드에서는, Integer형의 입력란의 파라미터에 관해서는 공란의대로라고 null로서 받아 버리므로, 그 경우는 서비스중에서 if문을 사용해 0에 세트 합니다. String 형의 파라미터에 대해서는, 입력되었을 때에는 그것을 서비스 안에서 트리밍해 concat 를 사용해 부분 일치 검색으로 합니다.

좋은 웹페이지 즐겨찾기