Query Method, @Query 어노테이션
Spring Data JPA에서 검색을 위해 아래 방법을 활용할 수 있음
- 쿼리 메서드(Query Method) : 메서드의 이름 자체가 쿼리의 구문으로 처리되는 기능
- @Query: SQL과 유사하게 엔티티 클래스의 정보를 이용해서 쿼리를 작성하는 기능
- Querydsl등의 동적 처리 기능
쿼리 메서드(Query Method)
https://docs.spring.io/spring-data/jpa/reference/jpa/query-methods.html
JPA Query Methods :: Spring Data JPA
By default, Spring Data JPA uses position-based parameter binding, as described in all the preceding examples. This makes query methods a little error-prone when refactoring regarding the parameter position. To solve this issue, you can use @Param annotati
docs.spring.io
주로 'findBy...', 'getBy...'의 형태로 시작하며 이후 필드 조건에 And, Or, Between과 같은 키워드 활용
// 다음과 같은 형식으로 활용
Page<Memo> result = memoRepository.findByMnoBetween(10L, 50L, pageable);
Page<Memo> result = memoRepository.findAll(pageable);
memoRepository.findByMemoTextContaining("i").stream().forEach(e -> {
System.out.println(e);
});
memoRepository.deleteById(mno);
memoRepository.deleteMemoByMnoLessThan(10L);
@Query 어노테이션
속성(value값)에 JPQL 쿼리문을 담으며, 다음과 같은 작업을 실행할 수 있음.
- 필요한 데이터만 선별적으로 추출
- DB에 맞는 순수한 SQL(Native SQL) 사용
- select가 아닌 DML(update, delete, insert) 등을 처리(@Modifying과 함께 사용)
테이블 대신에 엔티티 클래스, 컬럼 대신에 클래스에 선언된 필드를 이용
// 다음과 같이 사용할 수 있음
@Query("select m from Memo m order by m.mno desc"
List<Memo> getListDesc();
@Query 파라미터 바인딩
where 구문과 그에 맞는 파라미터를 처리하는 경우가 많으며 다음과 같은 방식 사용
?1, ?2
와 1부터 시작하는 파라미터의 순서를 이용하는 방식:xxx
와 같이:파라미터 이름
을 활용하는 방식:#{ }
와 같이 자바 빈 스타일을 이용 (해당 형태는 객체로 되어있을 때만 사용할 수 있음)
return 값이 Object[](Object 배열)
쿼리 메서드는 엔티티 타입의 데이터만을 추출하지만 쿼리 어노테이션은 Object[] 형태로 선별적 추출이 가능함
select m from Memo m → m은 객체, 테이블에서 한 행이라고 생각하면 됨
JOIN이나 COUNT등 존재하지 않는 엔티티 타입을 활용해야하기 때문에 Object 배열을 유용하게 사용가능함
@Query 파라미터 사용해보기
// JPQL
// repository
@Query("select m from Memo m where memoText like %:memo% order by mno desc")
List<Memo> findMemoTextLike(String memo); // like에 있는 memo와 파라미터 memo의 이름이 동일해서 값이 들어감. 만약 이름이 다를 경우 @Param어노테이션 사용해야함
// testrepository
@Test
public void testSearch3() {
memoRepository.findMemoTextLike("1").stream().forEach(e -> {
System.out.println(e);
});
}
// Navice SQL(nativeQuery을 true로 해줘야함 기본 값 false)
// repository
@Query(value = "select * from tbl_memo where memo_text like concat('%', ?1, '%') order by mno desc", nativeQuery = true)
List<Memo> findMemoTextLike2(String memo);
// testrepository
@Test
public void testSearch4() {
memoRepository.findMemoTextLike2("1").stream().forEach(e -> {
System.out.println(e);
});
}
Querydsl
동적인 SQL도 객체로 활용할 수 있게 해줌
Querydsl JPA Support, Querydsl APT Support 두 dependency 추가
// jakarta를 뒤에 붙여줘야 패키지가 javax.~~가 아닌 jakarta.~~로 나옴
implementation 'com.querydsl:querydsl-jpa:5.1.0:jakarta'
annotationProcessor(
"jakarta.persistence:jakarta.persistence-api",
"jakarta.annotation:jakarta.annotation-api",
'com.querydsl:querydsl-jpa:5.1.0:jakarta'
)
활용
// repository
public QMemo(PathMetadata metadata) {
super(Memo.class, metadata);
}
// testrepository
@Test
public void testQuerydsl(){
String searchType = "t";
String searchWord = "9";
// 빌더 객체
BooleanBuilder builder = new BooleanBuilder();
QMemo memo = QMemo.memo;
// 동적 조건
if("t".equals(searchType)){
builder.and(memo.memoText.like("%"+searchWord+"%"));
}
Page<Memo> result = memoRepository.findAll(builder, PageRequest.of(0, 10));
result.get().forEach(e -> System.out.println(e));
}
* 신한DS아카데미 수강 내용 기반
* 코드로 배우는 스프링 부트 웹 프로젝트 책 기반
'WEB > Back-end' 카테고리의 다른 글
Thymeleaf 레이아웃(SpringBoot) (0) | 2024.07.30 |
---|---|
Thymeleaf 기본(SpringBoot) (0) | 2024.07.30 |
(SQL) 숫자데이터 가공 함수 (0) | 2024.07.29 |
(SQL) 함수, 문자데이터 가공 함수 (0) | 2024.07.29 |
(SQL) SQL 표준, SELECT문 (0) | 2024.07.29 |