반응형
JPA에서 다중 파라미터 처리를 진행 할 때 아래의 예제 처럼 작성하면 기능 구현이 가능하다.
Page<AdminUser> adminUsers = null;
if(adminUserApiRequest.getAccount() == null && adminUserApiRequest.getRole() == null)
{
adminUsers = adminUserRepository.findAll(pageable);
}
else if(adminUserApiRequest.getAccount() != null && adminUserApiRequest.getRole() == null)
{
adminUsers = adminUserRepository.findAllByAccount(pageable, adminUserApiRequest.getAccount());
}
else if(adminUserApiRequest.getRole() != null && adminUserApiRequest.getAccount() == null)
{
adminUsers = adminUserRepository.findAllByRole(pageable, adminUserApiRequest.getRole());
}
else
{
adminUsers = adminUserRepository.findAllByAccountAndRole(pageable, adminUserApiRequest.getAccount(), adminUserApiRequest.getRole());
}
단, 이와 같은 방식은 파라미터 변경(추가, 삭제, 수정) 이 일어날 경우 소스 수정은 불가피 하다.
따라서 파라미터의 변경에 종속되지 않게 작성하기 위해 Specification를 사용하였다.
아래의 예제를 보면,
public Header<List<AdminUserApiResponse>> search(Pageable pageable, AdminUserApiRequest adminUserApiRequest) {
// convertObjectToMap - Object를 Map형태로 형변환
Map<String, Object> searchRequest = CommonObjectUtils.convertObjectToMap(adminUserApiRequest);
Map<String, Object> searchKeys = new HashMap<>();
for (String key : searchRequest.keySet()) {
String value = String.valueOf(searchRequest.get(key));
if(value != null && !value.isEmpty() && !"null".equals(value)){
searchKeys.put(key, searchRequest.get(key));
}
}
Page<AdminUser> adminUsers = adminUserRepository.findAll(adminUserSpecification.searchWith(searchKeys), pageable);
.
.
.
생략
}
우선 첫번째로 화면에서 넘어온 adminUser객체를 Map형태로 변환시켜 세팅.
그 이후 새로 정의 한 findAll의 첫번째 매개변수에 사용된 searchWith이라는 함수의
import com.example.study.model.entity.AdminUser;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Component
public class AdminUserSpecification{
public static Specification<AdminUser> searchWith(Map<String, Object> searchKeyword) {
return (Specification<AdminUser>) ((root, query, builder) -> {
List<Predicate> predicate = getPredicateWithKeyword(searchKeyword, root, builder);
return builder.and(predicate.toArray(new Predicate[0]));
});
}
private static List<Predicate> getPredicateWithKeyword(Map<String, Object> searchKeyword, Root<AdminUser> root, CriteriaBuilder builder) {
List<Predicate> predicate = new ArrayList<>();
for (String key : searchKeyword.keySet()) {
predicate.add(builder.equal(root.get(key), searchKeyword.get(key)));
}
return predicate;
}
}
넘어온 searchKeyword 크기만큼 List<Predicate>에 담아서 그 내용을 CriteriaBuilder에 and하여 추가 하는 방식이다.
위의 내용은 넘어온 파라미터에 대해 모두 and조건으로 값이 동일할때의 케이스이며 or조건으로 Like, >, < 등의
조건은 새로 구성 해야됨.
반응형
'Back > Spring Java' 카테고리의 다른 글
CamelCase, SnakeCase Convert Function (0) | 2020.01.14 |
---|---|
Class Object Entity convert to Map (0) | 2020.01.14 |
BeanUtils.copyProperties (0) | 2019.12.23 |
Blob형태의 이미지 파일 입출력 (0) | 2019.12.19 |
Spring Security Login (2) | 2019.12.18 |