기본 골격

This commit is contained in:
현성필
2023-05-08 10:16:00 +09:00
parent 169ba6448c
commit 2412d289c3
606 changed files with 214162 additions and 114780 deletions
@@ -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;
}
}