일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- DDD
- 코테공부
- 코테준비
- 스프링
- 기술면접공부
- nestjs
- JPA공부
- 플러터 공부
- 기술공부
- querydsl
- nestjs공부
- Kafka
- Axon framework
- 알고리즘공부
- 스프링공부
- JPA
- 스프링부트공부
- K8S
- Flutter
- 프로그래머스
- 자료구조공부
- 스프링부트
- JPA예제
- 플러터 개발
- 스프링 공부
- 자바공부
- JPA스터디
- nestjs스터디
- JPA 공부
- 카프카
- Today
- Total
DevBoi
[JPA] QueryDsl 사용하기 본문
사용을 위한 기본구성
1. JpaFactory
package com.practice.demo.config;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.persistence.EntityManager;
@Configuration
public class JpaFactory {
@Autowired
EntityManager em;
@Bean
public JPAQueryFactory jpaQueryFactory(){
return new JPAQueryFactory(em);
}
}
2.Book
package com.practice.demo.domain;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Book {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long bookId;
@Column
private String bookName;
}
3. BookRepository
package com.practice.demo.repository;
import com.practice.demo.domain.Book;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface BookRepository extends JpaRepository<Book,Long> {
}
4. BookController
package com.practice.demo.controller;
import com.practice.demo.domain.Book;
import com.practice.demo.domain.QBook;
import com.practice.demo.repository.BookRepository;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class BookController {
@Autowired
private JPAQueryFactory query;
@Autowired
BookRepository bookRepository;
@RequestMapping("/insert")
public void insertBook(){
Book b1 = new Book();
bookRepository.save(b1);
}
@RequestMapping("/get")
public List<Book> insertBook2(){
return query.selectFrom(QBook.book).fetch();
}
}
간단하게 insert,select 를 하는 동작을 하는 걸 구현해봤다.
몇가지 추가적으로 개발을 한 내용은 아래와같다.
@RequestMapping("/get1")
public List<Book> get2(){
//
List<Book> list = query.selectFrom(QBook.book).where(QBook.bookId.between(1L,2L )).fetch();
//같은지 체크
return query.selectFrom(QBook.book).where(QBook.bookId.eq(1L)).fetch();
}
조건문에 대한건 코드 추천으로 더 활용가능하다.
추가적으로 궁금한것은 그때 찾아봤다.
1. fetch()와 fetchall()의 차이는?
우선 return 문이 다르다.
그니까, 쉽게 말하면 목적에 따라서 다르다기보다
아예 기능자체가 다른것이다.
fetchr관련 사용은 위와 같다.
한개냐 페이징이냐, 개수냐 에 따라서 다르게 쓰는것이다.
그러면... fetchall은 무엇에 쓰는걸까?
@Override
public Q fetchAll() {
return queryMixin.fetchAll();
}
@Override
@SuppressWarnings("unchecked")
public List<T> fetch() {
try {
Query query = createQuery();
return (List<T>) getResultList(query);
} finally {
reset();
}
}
우선 정의된 클래스의 이름도 다르다.,
fetch()는 AbstactJPAQuery에 존재하고
fetchAll()은 JPAQueryBase에 존재한다.
fetchAll()은 Q엔티티를 리턴하는것으로 보아, join이나 여러개의 엔티티를 복합적으로 사용시에 사용하는 것이고
fetch()는 결과에 대한 리턴을 받고자 할 때 사용한다.
2. Qbook을 static 하게 사용하는 방법은?
List<Book> list = query.selectFrom(QBook.book).where(QBook.book.bookId.between(1L,2L )).fetch();
//같은지 체크
return query.selectFrom(QBook.book).where(QBook.book.bookId.eq(1L)).fetch();
요로케 사용했었는데
매번, Q클래스를 타고 가는게 귀찮다.
이럴떄는 static 하게 선언하고, 북으로 바로가는게 좋다.
맥 기준 옵션 +엔터치면 스태택으로 변경할 수 있도록 설정가능하고
이를 설정하게 되면, import문이 이렇게 바뀐다.
이러면 좀 더 깔끔하게 사용이 가능하다.
3. 정렬하는 법은?
List<Book> list = query.selectFrom(book).where(
book.bookId.between(1L,2L ),
book.bookName.eq("gd")
).orderBy(book.bookName.desc())
.fetch();
4. where 절의 조건이 여러개일때는?
List<Book> list = query.selectFrom(book).where(
book.bookId.between(1L,2L ),
book.bookName.eq("gd")
).fetch();
where 절에 콤마를 붙이면 기본적으로 and 연산이 된다.
기본적인 사용방법은 위와 같다.
궁금증도 해결했고 이제 기초를 해봤으니, 어느정도 심화 개념을 공부하면서,
프로젝트를 써보면 좀더 깊이 있게 사용할 수 있을 듯하다.
페이징 처리 해보기
offset,limit을 사용하면 된다.
다만 좀 특이한게 fetch가 아니라 fetchResult로 사용할 수 있다.
이는 페이징 관련 내용을 사용할 수 있도록 객체로 리턴해주는 것이다.
@RequestMapping("/page")
public List<Book> page(){
//같은지 체크
QueryResults<Book> result = query.selectFrom(book)
.where(book.bookId.eq(1L))
.offset(0)
.limit(10)
.fetchResults();
List<Book> resultData = result.getResults();
long offset = result.getOffset();
long limit = result.getLimit();
long total = result.getTotal();
return resultData;
}
페이징 처리할때 필요한 요소들을 전부 리턴해준다.
이를 객체로 하던, 별도 맵으로 하던은 자기 마음대로이겠지만 ..
다음에는 엔티티 몇개를 더 만들어서 조인이랑 여러가지 기본적인 동작을 해보자
'Develop > [JPA]' 카테고리의 다른 글
[Jpa] java.sql.SQLNonTransientConnectionException: (conn=48) Got a packet bigger than 'max_allowed_packet' bytes (0) | 2023.07.22 |
---|---|
[Spring] Mariadb - JPA 세팅 (0) | 2023.07.21 |
[QueryDSL] QueryDSL 세팅 (0) | 2023.05.01 |
JPA orphanRemoval 이란? (0) | 2023.01.09 |
[Jpa] delete 관련 잘 안됨 (0) | 2023.01.09 |