1. Interface dto로 Projection
- DTO
public interface InterfaceDTO {
// 규칙에 맞게 메소드 정의 (필드처럼 사용 가능)
int getTableId();
String getName();
String getBrand();
}
- JPA Repository (Pageable이 필요하다는 가정)
Pageable로 페이징 가능,
Pageable에 정의된 Sort방식 적용 가능!!
(1) Page 객체로 받을 때 : countQuery 속성 꼭 필요!!
interface dto가 가지고 있는 필드 명에 맞게 alias를 정의하면 자동으로 매칭됨
@Query(value= "SELECT tn.id as tableId, tn.name as name, tn.brand as brand "
+ "FROM TableName tn WHERE tn.name = :keyword"
countQuery= "select count(*) "
+ "FROM TableName tn WHERE tn.name=:keyword",
nativeQuery=true)
Page<InterfaceDTO> searchKeyword(@Param("keyword") String keyword, Pageable pageable);
(2) List 객체로 받을 때 : countQuery 속성 생략 가능
@Query(value= "SELECT tn.id as tableId, tn.name as name, tn.brand as brand "
+ "FROM TableName tn WHERE tn.name = :keyword"
nativeQuery=true)
List<InterfaceDTO> searchKeyword(@Param("keyword") String keyword, Pageable pageable);
2. Class DTO로 Projection (NamedNativeQuery 필요)
별로 추천하는 방식은 아님. 차라리 query dsl을 사용하는게 코드 가독성이나 유지보수에 용이함.
- DTO
projection 할 필드에 대한 생성자 반드시 필요!
public class ClassDTO {
private int tableId;
private String name;
private String brand;
public ClassDTO() {
super();
}
// projection 할 필드에 대한 생성자 반드시 필요!
public ClassDTO(int tableId, String name, String brand) {
super();
this.tableId = tableId;
this.name = name;
this.brand = brand;
}
// getter, setter 생략
}
- Entity
entity 객체에 NamedNativeQuery, SqlResultSetMapping 정의
@Entity
@Table(name="TableName")
@NamedNativeQuery(
name = "searchWithNamedQuery",
query = "SELECT tn.table_id as tableId, tn.name as name, tn.brand as brand "
"FROM TableName tn",
resultSetMapping = "tableclassdto"
)
@SqlResultSetMapping(
name = "tableclassdto",
classes = @ConstructorResult(
targetClass = ClassDTO.class,
columns = { // 생성자 파라미터 순서에 유의
@ColumnResult(name = "tableId", type = Integer.class),
@ColumnResult(name = "name", type = String.class),
@ColumnResult(name = "brand", type = String.class),
}
)
)
public class TableName {
// 이하 생략
}
- JPA Repository (Pageable이 필요하다는 가정)
Pageable로 페이징 가능,
Pageable에 정의된 Sort방식 적용 불가능 (order by 사용해야 함)
(1) Page 객체로 받을 때 : NamedNativeQuery에 countQuery 속성 꼭 필요!!
@Query(name="searchWithNamedQuery", nativeQuery = true)
Page<ClassDTO> searchWithNamedQuery(@Param("keyword") String keyword, Pageable pageable);
(2) List 객체로 받을 때 : NamedNativeQuery에 countQuery 속성 생략 가능
@Query(name="searchWithNamedQuery", nativeQuery = true)
List<ClassDTO> searchWithNamedQuery(@Param("keyword") String keyword, Pageable pageable);
** 참고
class DTO projection에서 jpa repository를 interface DTO projection 방식대로 사용한다면 convert exception이 발생한다.
NamedNativeQuery를 사용해야만 class DTO로 projection이 가능하다.
'개발 > 스프링부트' 카테고리의 다른 글
@SpringbootApplication의 baseScanPackage 설정 이슈 (0) | 2024.07.13 |
---|---|
@Transactional 사용시 주의점(feat.AOP,Proxy) (4) | 2022.11.13 |
서블릿 MVC 와 스프링 MVC 비교하기 (2) | 2022.06.04 |
@Component, @Controller, @Service, @Repository의 차이 (8) | 2022.05.08 |
이전 댓글