BackEnd/Spring Boot

JPA 응용 방법 _ Specification_1

Raconer 2023. 4. 17. 23:14
728x90

JPA 응용

기본으로 제공되는

  • Repository <T,ID>
  • CrudRepository <T,ID>
  • PagingAndSotringRepository <T,ID>
  • JpaRepository <T,ID>
    만으로는 모든 Query를 처리하기에 매우 한계가 있다.
    예를 들면 Mybatis는 xml 파일에서 if, choose, where, set 등 수많은 옵션? 을 제공하는데 JPA도 이와 비슷하게 구현할수 있다.

Entity

JPA 응용 방법 _ Specification에서 사용될 기본 Entity입니다.

기본 Repository

  public interface UserRepository extends Repository<User, String> {

      // Create, Update
      User save(User user);

      // Read
      // Find By Method는 단순할 경우에만 사용할것
      Optional<User> findById(String email);

      List<User> findByNameLike(String name);

      // Use Specification
      List<User> findAll(Specification<User> spec);

      // Delete
      void delete(User user);
  }
  @AllArgsConstructor
  @NoArgsConstructor
  @Data
  @Entity
  @Table(name = "user")
  public class User implements Persistable<String> {

      @Id
      private String email;
      private String name;

      @Column(name = "create_date")
      private LocalDateTime createDate;

      @Transient
      private boolean isNew = true;

      @Override
      @Nullable
      public String getId() {
          return email;
      }

      @Override
      public boolean isNew() {
          return false;
      }
  }

1.동적 쿼리(Specification)

  1. Specification 인터페이스 구현

Specification 인터페이스를 구현하여 동적 쿼리를 작성합니다. Specification은 toPredicate() 메서드를 구현해야 합니다. toPredicate() 메서드는 CriteriaBuilder와 CriteriaQuery 객체를 사용하여 조건을 작성하고, Predicate 객체를 반환해야 합니다.

  public class UserSpecification implements Specification<User> {

    private SearchCriteria criteria;

    public UserSpecification(SearchCriteria criteria) {
      this.criteria = criteria;
    }

    @Override
    public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder builder) {

      if (criteria.getOperation().equalsIgnoreCase(">")) {
          return builder.greaterThanOrEqualTo(
            root.<String> get(criteria.getKey()), criteria.getValue().toString());
      } 
      else if (criteria.getOperation().equalsIgnoreCase("<")) {
          return builder.lessThanOrEqualTo(
            root.<String> get(criteria.getKey()), criteria.getValue().toString());
      } 
      else if (criteria.getOperation().equalsIgnoreCase(":")) {
          if (root.get(criteria.getKey()).getJavaType() == String.class) {
              return builder.like(
                root.<String>get(criteria.getKey()), "%" + criteria.getValue() + "%");
          } else {
              return builder.equal(root.get(criteria.getKey()), criteria.getValue());
          }
      }
      return null;
    }
  }
  1. Specification 객체 생성

Specification 객체는 CriteriaQuery 객체와 함께 사용되며, where() 메서드를 사용하여 Specification을 적용합니다.

  public List<User> searchUser(SearchCriteria searchCriteria) {
      Specification<User> specification = new UserSpecification(searchCriteria);
      return userRepository.findAll(specification);
  }
  1. 쿼리 실행

Specification을 적용한 CriteriaQuery 객체를 사용하여 쿼리를 실행합니다. findAll() 메서드는 Specification을 인자로 받을 수 있으며, Predicate 객체를 반환합니다.

    List<User> users = userRepository.findAll(specification);

위와 같이 Specification 인터페이스를 구현하여 JPA에서 동적인 쿼리를 작성할 수 있습니다.

728x90

'BackEnd > Spring Boot' 카테고리의 다른 글

mysql-connector-j와 mysql-connector-java  (0) 2023.04.30
JPA 응용 방법 _ Specification_2  (0) 2023.04.18
JPA 간단 사용법  (0) 2023.04.17
Bean Life Cycle  (0) 2023.04.16
Redis 설정  (0) 2023.04.16