기본 골격
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
package com.eactive.httpmockserver.common.search;
|
||||
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Overview:
|
||||
*
|
||||
* BaseSearch 클래스는 Spring Data JPA 프레임워크를 사용하여 복잡한 검색 쿼리를 편리하게 작성할 수 있는 방법을 제공하는 추상 클래스입니다.
|
||||
* 이 클래스를 사용하면 SearchModel 객체 목록을 사용하여 검색 쿼리를 생성할 수 있으며, 이를 결합하여 보다 복잡하고 구체적인 검색 조건을 만들 수 있습니다.
|
||||
*
|
||||
* How to Use:
|
||||
*
|
||||
* BaseSearch 클래스를 사용하려면 검색하려는 엔티티에 특정한 BaseSearch의 하위 클래스를 만들어야 합니다.
|
||||
* 예를 들어 User 개체를 검색하려는 경우 BaseSearch<User>를 확장하는 UserSearch라는 클래스를 만들 수 있습니다.
|
||||
*
|
||||
* 하위 클래스에서 buildSearchCondition() 메서드를 구현해야 합니다.
|
||||
* 이 메서드는 사용하려는 검색 조건을 나타내는 SearchModel 객체 목록을 반환해야 합니다.
|
||||
*
|
||||
* 예를 들어, 다음은 이름에 특정 문자열이 포함된 사용자를 검색하기 위해 buildSearchCondition() 메서드를 구현하는 방법입니다:
|
||||
*
|
||||
* public List<SearchModel> buildSearchCondition() {
|
||||
* List<SearchModel> models = new ArrayList<>();
|
||||
* models.add(new ColumnSearchModel("firstName", SearchCondition.LIKE, "John"));
|
||||
* models.add(new ColumnSearchModel("lastName", SearchCondition.LIKE, "Doe"));
|
||||
* return models;
|
||||
* }
|
||||
*
|
||||
* 이 예제에서는 이름과 성에 각각 문자열 "John"과 "Doe"가 포함된 사용자를 검색하는 두 개의 ColumnSearchModel 객체를 만들고 있습니다.
|
||||
*
|
||||
* 검색 쿼리를 빌드하려면 UserSearch 클래스의 인스턴스를 생성하고 그 인스턴스에서 buildSpecification() 메서드를 호출하면 됩니다.
|
||||
* 이 메서드는 Spring 데이터 JPA를 사용하여 데이터베이스를 쿼리하는 데 사용할 수 있는 Specification 객체를 반환합니다.
|
||||
*
|
||||
* UserSearch search = new UserSearch();
|
||||
* Specification<User> spec = search.buildSpecification();
|
||||
* List<User> users = userRepository.findAll(spec);
|
||||
*
|
||||
* 이 예제에서는 UserSearch 인스턴스를 만들고 buildSpecification() 메서드를 호출하여 사양 객체를 빌드한 다음 이 사양 객체를 사용하여 데이터베이스에서 검색 조건과 일치하는 모든 사용자 객체를 쿼리합니다.
|
||||
* 결과는 User 객체 목록으로 반환됩니다.
|
||||
*
|
||||
* 추가 활용 방법
|
||||
*
|
||||
* BaseSearch 클래스는 유연하고 확장 가능하도록 설계되어 필요에 따라 더 복잡한 검색 쿼리를 사용할 수 있습니다.
|
||||
* getSpecification() 메서드를 구현하는 SearchModel의 새로운 서브클래스를 생성하여 검색 조건을 추가할 수 있습니다.
|
||||
* 필요에 따라 추가 검색 조건을 포함하도록 SpecificationUtil 클래스를 수정할 수도 있습니다.
|
||||
*
|
||||
* 또한 BaseSearch 클래스를 확장하여 정렬 및 페이징과 같은 추가 기능을 제공할 수 있습니다.
|
||||
* 하위 클래스에 메서드와 속성을 추가하여 애플리케이션의 특정 요구 사항을 충족하는 검색 쿼리를 만들 수 있습니다.
|
||||
*
|
||||
* ColumnSearchModel은 검색조건이 컬럼명과 비교 연산자, 값으로 구성된다. SearchCondition 참조
|
||||
* SpecificationSearchModel은 검색조건이 Specification을 리턴하는 형태로 구성된다. 검색조건을 복잡하게 구성해야 할 때 사용한다.
|
||||
*
|
||||
* public static Specification current(String user, ApproverStatus approverStatus) {
|
||||
* return (root, criteriaQuery, criteriaBuilder) -> {
|
||||
* ListJoin join = root.joinList("approvers");
|
||||
* return criteriaBuilder.and(
|
||||
* criteriaBuilder.equal(join.get("user"), user),
|
||||
* criteriaBuilder.equal(join.get("status"), approverStatus));
|
||||
* };
|
||||
* }
|
||||
*/
|
||||
public interface BaseSearch<T> {
|
||||
|
||||
List<SearchModel> buildSearchCondition();
|
||||
|
||||
default Specification<T> buildSpecification() {
|
||||
|
||||
List<SearchModel> models = buildSearchCondition();
|
||||
Specification<T> specifications = null;
|
||||
|
||||
for (SearchModel model : models) {
|
||||
Specification spec = getSpecification(model);
|
||||
|
||||
if (spec != null) {
|
||||
if (specifications == null) {
|
||||
specifications = Specification.where(spec);
|
||||
} else {
|
||||
specifications = specifications.and(spec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return specifications;
|
||||
}
|
||||
|
||||
default Specification<T> getSpecification(SearchModel model) {
|
||||
return model.getSpecification();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.eactive.httpmockserver.common.search;
|
||||
|
||||
import com.eactive.httpmockserver.common.util.SpecificationUtil;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class ColumnSearchModel implements SearchModel {
|
||||
|
||||
private String column;
|
||||
|
||||
private Object value; //값의 형태는 String, Collection, Object 등이 될 수 있다.
|
||||
|
||||
private SearchCondition condition;
|
||||
|
||||
public ColumnSearchModel(String column, SearchCondition condition, Object value) {
|
||||
this.column = column;
|
||||
this.condition = condition;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getColumn() {
|
||||
return column;
|
||||
}
|
||||
|
||||
public void setColumn(String column) {
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
public SearchCondition getCondition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
public void setCondition(SearchCondition condition) {
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Specification getSpecification() {
|
||||
|
||||
if (condition == null) return null;
|
||||
if (column == null) return null;
|
||||
if (ObjectUtils.isEmpty(value)) return null;
|
||||
|
||||
if (condition.equals(SearchCondition.EQUAL)) {
|
||||
return SpecificationUtil.equalTo(column, value);
|
||||
} else if (condition.equals(SearchCondition.LIKE)) {
|
||||
return SpecificationUtil.like(column, value.toString());
|
||||
} else if (condition.equals(SearchCondition.IN)) {
|
||||
return SpecificationUtil.in(column, (Collection) value);
|
||||
} else if (condition.equals(SearchCondition.NOT_EQUAL)) {
|
||||
return SpecificationUtil.notEqualTo(column, value);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.eactive.httpmockserver.common.search;
|
||||
|
||||
public enum SearchCondition {
|
||||
EQUAL,
|
||||
LIKE,
|
||||
IN,
|
||||
NOT_EQUAL
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.eactive.httpmockserver.common.search;
|
||||
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface SearchModel extends Serializable {
|
||||
|
||||
Specification getSpecification();
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.eactive.httpmockserver.common.search;
|
||||
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
public class SpecificationSearchModel implements SearchModel {
|
||||
|
||||
private final Specification specification;
|
||||
|
||||
public SpecificationSearchModel(Specification specification) {
|
||||
this.specification = specification;
|
||||
}
|
||||
|
||||
public Specification getSpecification() {
|
||||
|
||||
return specification;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user