[SPRING] 스프링 데이터 - 다중 열 검색
SPRING스프링 데이터 - 다중 열 검색
나는 페이징과 정렬을 위해 Spring Data를 사용하고있다. 그러나 다중 열 검색을 수행하고 싶습니다.
자, 이제 저장소 인터페이스에서 @Query라는 어노테이션을 사용하고있다.
public interface MyRepository extends PagingAndSortingRepository<Item,Long> {
@Query(value="select mt from MY_TABLE mt where mt.field1 = %searchtext% or mt.field2 = %searchtext% or mt.field3 = %searchtext%")
Page<Item> findByAllColumns(@Param("searchtext") String searchtext, Pageable pageable);
}
편집 :이 솔루션의 문제는 @Query 어노테이션의 where 절에 있습니다. 왜냐하면 우리가 검색하고자하는 모든 열에 대해 동일한 검색 텍스트 매개 변수를 반복해야하기 때문입니다 (Brandon Oakley의 코멘트 이후에 질문의 설명이 나옵니다)
테이블의 열 수가 높을 수 있기 때문에 할 수있는 다른 방법이 있는지 알고 싶습니다.
당신의 도움을 주셔서 감사합니다.
해결법
-
==============================
1.사양을 사용할 수 있습니다. 또한 유연성이 향상됩니다. 한 가지 방법을 사용할 수 있지만 쿼리에 대해 여러 가지 사양을 사용할 수 있습니다.
사양을 사용할 수 있습니다. 또한 유연성이 향상됩니다. 한 가지 방법을 사용할 수 있지만 쿼리에 대해 여러 가지 사양을 사용할 수 있습니다.
Page<Item> findAll(Specification<T> spec, Pageable pageable); myRepository.findAll(textInAllColumns(searchText), pageable);
-
==============================
2.다음은 사용자 사양과 같은 샘플입니다.
다음은 사용자 사양과 같은 샘플입니다.
public static Specification<User> containsTextInName(String text) { if (!text.contains("%")) { text = "%" + text + "%"; } String finalText = text; return (root, query, builder) -> builder.or( builder.like(root.get("lastname"), finalText), builder.like(root.get("firstname"), finalText) ); }
또는 사용자 정의가 가능한 구현 :
public static Specification<User> containsTextInAttributes(String text, List<String> attributes) { if (!text.contains("%")) { text = "%" + text + "%"; } String finalText = text; return (root, query, builder) -> builder.or(root.getModel().getDeclaredSingularAttributes().stream() .filter(a -> attributes.contains(a.getName())) .map(a -> builder.like(root.get(a.getName()), finalText)) .toArray(Predicate[]::new) ); } public static Specification<User> containsTextInName(String text) { return containsTextInAttributes(text, Arrays.asList("lastname", "firstname")); }
용법:
userRepository.findAll(Specifications.where(UserSpecifications.containsTextInName("irs")))
-
==============================
3.이전 두 가지 답변을 결합하십시오 : API와 데이터베이스 스키마를 결합하고 싶지 않거나 사용자가 문자열 열 이름을 제공하지 않게하려면 문자열이 아닌 속성을 필터링하여 적용 할 수 있습니다 있는 모든 사람들에게. 다음 예제에서는 name, field1, field2 및 field3과 같은 열 값으로 텍스트 검색을 시도합니다.
이전 두 가지 답변을 결합하십시오 : API와 데이터베이스 스키마를 결합하고 싶지 않거나 사용자가 문자열 열 이름을 제공하지 않게하려면 문자열이 아닌 속성을 필터링하여 적용 할 수 있습니다 있는 모든 사람들에게. 다음 예제에서는 name, field1, field2 및 field3과 같은 열 값으로 텍스트 검색을 시도합니다.
엔티티 예 :
@Entity public class MyEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public int id; public String name; public String field2; public String field3; public String field4; }
사양 예 :
public class EntitySpecification { public static Specification<MyEntity> textInAllColumns(String text) { if (!text.contains("%")) { text = "%"+text+"%"; } final String finalText = text; return new Specification<MyEntity>() { @Override public Predicate toPredicate(Root<MyEntity> root, CriteriaQuery<?> cq, CriteriaBuilder builder) { return builder.or(root.getModel().getDeclaredSingularAttributes().stream().filter(a-> { if (a.getJavaType().getSimpleName().equalsIgnoreCase("string")) { return true; } else { return false; }}).map(a -> builder.like(root.get(a.getName()), finalText) ).toArray(Predicate[]::new) ); } }; } }
저장소 예 :
public interface MyEntityRepository extends PagingAndSortingRepository<MyEntity, Integer> { List<MyEntity> findAll(Specification<MyEntity> spec); }
사용 예 :
List<MyEntity> res = failureRepository.findAll(Specifications.where(FailureSpecification.textInAllColumns(text)));
다른 업데이트 (lambdas가있는 필드의 흰색 목록이있는 모든 유형의 열에서 검색 - 코드가 확인되지 않음)
public class EmployeeSpecification { public static Specification<Employee> textInAllColumns(String text, Set<String> fields) { if (!text.contains("%")) { text = "%" + text + "%"; } final String finalText = text; return (Specification<Employee>) (root, query, builder) -> builder.or(root.getModel().getDeclaredSingularAttributes().stream().filter(a -> { return fields.contains(a.getName()); }).map(a -> builder.like(root.get(a.getName()), finalText)).toArray(Predicate[]::new)); } }
from https://stackoverflow.com/questions/25872637/spring-data-multi-column-searches by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 사양을 사용하는 다중 열 검색 관련된 엔티티 내의 스프링 데이터 Jpa? (0) | 2019.07.24 |
---|---|
[SPRING] 봄 부팅 - BeanDefinitionOverrideException : 잘못된 Bean 정의 (0) | 2019.07.23 |
[SPRING] 인증 전에 Spring Security에서 X509 인증 취소 상태 확인 (0) | 2019.07.19 |
[SPRING] Spring Boot에서 ActiveMQ 포트를 설정하는 방법은 무엇입니까? (0) | 2019.07.19 |
[SPRING] Spring MVC Controller NumberFormat BigDecimal의 주석 패턴 문제 (0) | 2019.07.19 |