diff --git a/src/main/java/kr/re/etri/security/jwt/service/ProjectService.java b/src/main/java/kr/re/etri/security/jwt/service/ProjectService.java index 391e0d3..ed6f5eb 100644 --- a/src/main/java/kr/re/etri/security/jwt/service/ProjectService.java +++ b/src/main/java/kr/re/etri/security/jwt/service/ProjectService.java @@ -24,6 +24,8 @@ import java.util.Optional; public class ProjectService { private final ProjectRepository projectRepository; + private final ProjectSpecification projectSpecification; + private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); public List findAll() { @@ -41,11 +43,10 @@ public class ProjectService { Sort.by(Sort.Direction.fromString(request.getSortDirection()), request.getSortField()) ); - // String -> LocalDate 변환 LocalDate startDate = parseDate(request.getStartDate()); LocalDate endDate = parseDate(request.getEndDate()); - Specification spec = ProjectSpecification.searchByConditions( + Specification spec = projectSpecification.searchByConditions( request.getSearchType(), request.getKeyword(), startDate, diff --git a/src/main/java/kr/re/etri/security/jwt/specification/ProjectSpecification.java b/src/main/java/kr/re/etri/security/jwt/specification/ProjectSpecification.java index a02e6e6..fb4f455 100644 --- a/src/main/java/kr/re/etri/security/jwt/specification/ProjectSpecification.java +++ b/src/main/java/kr/re/etri/security/jwt/specification/ProjectSpecification.java @@ -1,38 +1,68 @@ package kr.re.etri.security.jwt.specification; -import jakarta.persistence.criteria.Path; -import jakarta.persistence.criteria.Predicate; +import jakarta.annotation.PostConstruct; +import jakarta.persistence.EntityManager; +import jakarta.persistence.metamodel.Attribute; +import jakarta.persistence.metamodel.EntityType; +import jakarta.persistence.metamodel.Metamodel; import kr.re.etri.security.jwt.entity.ProjectEntity; import lombok.extern.slf4j.Slf4j; import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Component; + +import jakarta.persistence.criteria.Predicate; import java.time.LocalDate; import java.util.Set; +import java.util.stream.Collectors; @Slf4j +@Component public class ProjectSpecification { - public static Specification searchByConditions( + private final EntityManager entityManager; + + private Set stringFields; + + public ProjectSpecification(EntityManager entityManager) { + this.entityManager = entityManager; + } + + // 스프링 빈 초기화 후 실행 + @PostConstruct + public void init() { + Metamodel metamodel = entityManager.getMetamodel(); + EntityType entityType = metamodel.entity(ProjectEntity.class); + + // 문자열 타입 필드명만 추출 + stringFields = entityType.getAttributes().stream() + .filter(attr -> attr.getJavaType().equals(String.class)) + .map(Attribute::getName) + .collect(Collectors.toSet()); + + log.info("ProjectEntity string fields: {}", stringFields); + } + + public Specification searchByConditions( String searchType, String keyword, LocalDate startDate, LocalDate endDate) { return (root, query, cb) -> { Predicate predicate = cb.conjunction(); - // 문자열 필드만 지정 (날짜 필드 제외) - Set stringFields = Set.of("prjNm", "prjDesc", "delYn"); - if (keyword != null && !keyword.isEmpty()) { if ("전체".equalsIgnoreCase(searchType) || "all".equalsIgnoreCase(searchType)) { - predicate = cb.and(predicate, cb.or( - cb.like(cb.lower(root.get("prjNm")), "%" + keyword.toLowerCase() + "%"), - cb.like(cb.lower(root.get("prjDesc")), "%" + keyword.toLowerCase() + "%"), - cb.like(cb.lower(root.get("delYn")), "%" + keyword.toLowerCase() + "%") - )); + Predicate orPredicate = cb.disjunction(); + for (String field : stringFields) { + orPredicate = cb.or(orPredicate, + cb.like(cb.lower(root.get(field)), "%" + keyword.toLowerCase() + "%")); + } + predicate = cb.and(predicate, orPredicate); + } else if (stringFields.contains(searchType)) { predicate = cb.and(predicate, cb.like(cb.lower(root.get(searchType)), "%" + keyword.toLowerCase() + "%")); } - // searchType이 날짜 컬럼이면 keyword 검색 안함 + // 날짜 타입 필드 검색 시 무시 } if (startDate != null) { @@ -48,4 +78,4 @@ public class ProjectSpecification { return predicate; }; } -} \ No newline at end of file +}