[SPRING] JPA - @Query ( Custom Query )

RuiN·2022년 8월 1일
0

Spring

목록 보기
2/8
post-thumbnail

Necessity

JPA Repository 는 아주 간단하게 사용할 수 있는 인터페이스입니다.
그러나~ 만약 조건이 길게 늘어진다면??

    List<Book> findByCategoryIsNullAndNameEqualsAndCreatedAtGreaterThanEqualAndUpdatedAtGreaterThanEqual(String name, LocalDateTime createdAt,LocalDateTime updatedAt);

이런느낌으로! 길어진다면 가독성은 물론 비효율적인 느낌이 듭니다.
TEST에서도

    @DisplayName("4. QueryTest")
    @Test
    void test_4(){
        System.out.println("findByCategoryIsNullAndNameEqualsAndCreatedAtGreaterThanEqualAndUpdatedAtGreaterThanEqual : " + bookRepository.findByCategoryIsNullAndNameEqualsAndCreatedAtGreaterThanEqualAndUpdatedAtGreaterThanEqual(
                "JPA 초격차 패키지",
                LocalDateTime.now().minusDays(1L),
                LocalDateTime.now().minusDays(1L)
        ));
 }

이렇게 가독성이 너무 떨어집니다.
또, 만약에

insert into book(`id`, `name`, `publisher_id`, `created_at`, `updated_at`) values(1, 'JPA 초격자 패키지', 1, false, now(), now());
insert into book(`id`, `name`, `publisher_id`, `created_at`, `updated_at`) values(2, 'Spring', 1, false, now(), now());
insert into book(`id`, `name`, `publisher_id`, `created_at`, `updated_at`) values(3, 'Spring Security', 1, true, now(), now());

위 처럼 쿼리에서
created_at / updated_at 을 매~~~번 넣어줘야 하는 불편함도 있습니다.

여기서 아주 센스있게 작성할 수 있게 하는게 Custom Query 입니다.


BaseEntity

저번 포스팅중에서 Auditing 참고!

@Data
@MappedSuperclass
@EntityListeners(value = AuditingEntityListener.class)
public class BaseEntity implements Auditable {
    @CreatedDate
    @Column(columnDefinition = "datetime(6) default now(6) comment '생성시간'",nullable = false, updatable = false)
    private LocalDateTime createdAt;
    @LastModifiedDate
    @Column(columnDefinition = "datetime(6) default now(6) comment '수정시간'",nullable = false)
    private LocalDateTime updatedAt;
}

@Column 어노테이션으로 쿼리의 기본 설정을 해줄 수 있다.

  • nullable = false
    • create table 에서 not null 설정
  • updatable = false
    • 말 그대로 값이 update 되지 않음
  • columnDefinition
    • "datetime(6) default now(6) comment '생성시간'" 이라고 설정 한다면!
    •    create table author (
            id bigint not null auto_increment,
             created_at datetime(6) default now(6) comment '생성시간' not null,
             updated_at datetime(6) default now(6) comment '수정시간' not null,
             country varchar(255),
             name varchar(255),
             primary key (id)
         ) engine=InnoDB
      종합하면 이런 식으로 BaseEntity를 상속받은 Entity는 다음과 같은 Table 을 Create 한다.

Custom Query

자 ! 봅시다 !

    List<Book> findByCategoryIsNullAndNameEqualsAndCreatedAtGreaterThanEqualAndUpdatedAtGreaterThanEqual(String name, LocalDateTime createdAt,LocalDateTime updatedAt);

위 처럼 너무 긴~ 조건을 가진 조건 메소드가 있습니다

이러한 메소드를 Custom Query로 작성한다면

@Query(value = "select b from Book b " +
            "where name = :name and createdAt >= :createdAt and updatedAt >= :updatedAt and category is null")
    List<Book> findByNameRecently(
            @Param("name") String name,
            @Param("createdAt")LocalDateTime createdAt,
            @Param("updatedAt")LocalDateTime updatedAt);

다음과 같이 작성하게 됩니다.

@Param("컬럼명") 으로 파라미터마다 선언해주고,
@Query(value = "select ~ from ~ where name = :" ) 안에 쿼리문을 작성해주면!
그에 맞는 자리에 들어가 native query가 실행된다.

@Query(value = "select b from Book b " +
            "where name = ?1 and createdAt >= ?2 and updatedAt >= ?3 and category is null")
    List<Book> findByNameRecently(
            String name,
            LocalDateTime createdAt,
            LocalDateTime updatedAt);

위와 같이 작성해줘도 똑같은 결과를 가져옵니다.


profile
어디까지 올라갈지 궁금한 하루

0개의 댓글