[SPRING] 사양을 사용하는 다중 열 검색 관련된 엔티티 내의 스프링 데이터 Jpa?
SPRING사양을 사용하는 다중 열 검색 관련된 엔티티 내의 스프링 데이터 Jpa?
이 질문을 취하고 있습니다. 단일 테이블의 날짜, 정수 및 문자열 데이터 형식 필드에서 다중 열 검색을 수행 하시겠습니까? 이 메소드는 Java 8에서 Specification
사실 저는 글로벌 검색의 일부뿐만 아니라 협회 엔티티 내에서 검색하고 싶었습니다. JPA 2 사양 API를 사용할 수 있습니까?
저는 직원 및 부서를 @OneToMany 양방향 관계로 보았습니다.
Employee.java
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "EMPLOYEE_ID")
private Long employeeId;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;
@Column(name = "EMAIL_ID")
private String email;
@Column(name = "STATUS")
private String status;
@Column(name = "BIRTH_DATE")
private LocalDate birthDate;
@Column(name = "PROJECT_ASSOCIATION")
private Integer projectAssociation;
@Column(name = "GOAL_COUNT")
private Integer goalCnt;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "DEPT_ID", nullable = false)
@JsonIgnore
private Department department;
}
Department.java
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Department implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "DEPT_ID")
private Long departmentId;
@Column(name = "DEPT_NAME")
private String departmentName;
@Column(name = "DEPT_CODE")
private String departmentCode;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "department")
@JsonIgnore
private Set<Employee> employees;
}
아래와 같이 데이터를 저장했습니다. MyPaginationApplication.java
@SpringBootApplication
public class MyPaginationApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(MyPaginationApplication.class, args);
}
@Autowired
private EmployeeRepository employeeRepository;
@Autowired
private DepartmentRepository departmentRepository;
@Override
public void run(String... args) throws Exception {
saveData();
}
private void saveData() {
Department department1 = Department.builder()
.departmentCode("AD")
.departmentName("Boot Depart")
.build();
departmentRepository.save(department1);
Employee employee = Employee.builder().firstName("John").lastName("Doe").email("john.doe@gmail.com")
.birthDate(LocalDate.now())
.goalCnt(1)
.projectAssociation(2)
.department(department1)
.build();
Employee employee2 = Employee.builder().firstName("Neha").lastName("Narkhede").email("neha.narkhede@gmail.com")
.birthDate(LocalDate.now())
.projectAssociation(4)
.department(department1)
.goalCnt(2)
.build();
Employee employee3 = Employee.builder().firstName("John").lastName("Kerr").email("john.kerr@gmail.com")
.birthDate(LocalDate.now())
.projectAssociation(5)
.department(department1)
.goalCnt(4)
.build();
employeeRepository.saveAll(Arrays.asList(employee, employee2, employee3));
}
}
EmployeeController.java
@GetMapping("/employees/{searchValue}")
public ResponseEntity<List<Employee>> findEmployees(@PathVariable("searchValue") String searchValue) {
List<Employee> employees = employeeService.searchGlobally(searchValue);
return new ResponseEntity<>(employees, HttpStatus.OK);
}
EmployeeSpecification.java
public class EmployeeSpecification {
public static Specification<Employee> textInAllColumns(Object value) {
return (root, query, builder) -> builder.or(root.getModel().getDeclaredSingularAttributes().stream()
.filter(attr -> attr.getJavaType().equals(value.getClass()))
.map(attr -> map(value, root, builder, attr))
.toArray(Predicate[]::new));
}
private static Object map(Object value, Root<?> root, CriteriaBuilder builder, SingularAttribute<?, ?> a) {
switch (value.getClass().getSimpleName()) {
case "String":
return builder.like(root.get(a.getName()), getString((String) value));
case "Integer":
return builder.equal(root.get(a.getName()), value);
case "LocalDate":
return builder.equal(root.get(a.getName()), value);//date mapping
default:
return null;
}
}
private static String getString(String text) {
if (!text.contains("%")) {
text = "%" + text + "%";
}
return text;
}
}
/ employees / {searchValue}를 치면 Department 테이블에서 Employee 테이블과 같은 조인을 사용하고있을 수 있습니다. 그게 가능하니? 그렇다면 어떻게 할 수 있습니까?
또는: 여기에 넣는 것이 좋은 방법일까요? @Query 사용법 참조
@Query("SELECT t FROM Todo t WHERE " +
"LOWER(t.title) LIKE LOWER(CONCAT('%',:searchTerm, '%')) OR " +
"LOWER(t.description) LIKE LOWER(CONCAT('%',:searchTerm, '%'))")
List<Todo> findBySearchTerm(@Param("searchTerm") String searchTerm);
해결법
from https://stackoverflow.com/questions/57167639/multi-column-search-using-specifications-spring-data-jpa-within-associated-entit by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] AttributeConverter 클래스 내의 Spring 빈에 접근하기 (0) | 2019.07.25 |
---|---|
[SPRING] 자바 - OkHttp 비동기 GET 결과 검색 (0) | 2019.07.24 |
[SPRING] 봄 부팅 - BeanDefinitionOverrideException : 잘못된 Bean 정의 (0) | 2019.07.23 |
[SPRING] 스프링 데이터 - 다중 열 검색 (0) | 2019.07.23 |
[SPRING] 인증 전에 Spring Security에서 X509 인증 취소 상태 확인 (0) | 2019.07.19 |