본문 바로가기
jpa

jpa Specifications

by 뇽꾸리 2022. 5. 17.
반응형
  • JpaSpecificationExecutor 추가
public interface Repository extends JpaRepository<Test, Long>,JpaSpecificationExecutor<Test>{

}
  • spec.class 생성 
  • entity 들은 자기 entity 값들을 맞춰준다.
import java.util.List;
import javax.persistence.criteria.Predicate;
import org.springframework.data.jpa.domain.Specification;

public class TestSpecification {

    /**
     * 검색옵션 가져오기
	 * @author me
	 * @param List<SearchCriteriaDTO>
     * @return list
	 */
    public static Specification<Test> search(List<SearchCriteriaDTO> params) {
		return (Specification<Test>) ((root, query, builder) -> {
			List<Predicate> predicate = PredicateUtil.getPredicate(params, root, builder);
			return builder.and(predicate.toArray(new Predicate[0]));
		});
	}
}
  • 다른곳에서도 쓸 수 있게 util로 생성 
public class PredicateUtil {
    
    /**
     * 검색옵션 리스트 리턴
	 * @author me
	 * @param List<SearchCriteriaDTO>,root,builder
     * @return List<Predicate> 
	 */
	public static List<Predicate> getPredicate(List<SearchCriteriaDTO> params, Root<?> root, CriteriaBuilder builder) {
		List<Predicate> predicate = new ArrayList<>();
        for(SearchCriteriaDTO dto : params){
            switch (dto.getOperator()) {
                case "like":
                    predicate.add(builder.like(root.get(dto.getKey()), "%" + dto.getValue() + "%"));
                    break;
                case "equal":
                    predicate.add(builder.equal(root.get(dto.getKey()), dto.getValue()));
                    break;
                
                default :
                    break;
            }
        }
		return predicate;
	}
}
  • service 단에서는 이렇게 호출해주게 변경했다. 
/**
     * 검색옵션 리스트 
	 * @author me
	 * @param TestDTO,Pageable
	 */
	@Transactional(readOnly = true)
	public Page<Test> list(TestDTO reqDTO, Pageable pageable){

		/* 검색옵션 배열이 없으면 페이징만 해서 return */
		if(reqDTO.getSearchCriterias() == null|| reqDTO.getSearchCriterias().size() == 0){
			return repository.findAll(pageable);
		}

		/* 검색옵션 추가 */
		Specification<Test> specs = TestSpecification.search(reqDTO.getSearchCriterias());
	 	return	repository.findAll(specs,pageable);
	}

 

 

최근 코드들중 가장 맘에든다. 뿌듯 

리팩토링전에는 이렇게 작업했고 이게 더 보기 좋긴한데 여러 조건들을 많이 넣으려고 하다보니 List<Predicate>로 변경

public class TestSpecification {
    /**
     * like 검색옵션 
	 * @author me
	 * @param key,value
	 */
    public static Specification<Test> like(String key, String value){
        return (root, query, criteriaBuilder) 
            -> criteriaBuilder.like(root.get(key), "%"+value+"%");
    }
    

    /**
     * equal 검색옵션 
	 * @author me
	 * @param key,value  
	 */
    public static Specification<Test> equal(String key, String value){
        return (root, query, criteriaBuilder) 
            -> criteriaBuilder.equal(root.get(key), value);
    }
}
반응형

'jpa' 카테고리의 다른 글

jpa paging , sort  (0) 2022.05.10

댓글