일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 대용량 업로드
- jqGrid
- DevOps
- 자동배포
- poi
- 자동빌드
- Stream
- JPA
- Jenkins
- apache.poi
- rabbitmq
- ci/cd
- docker
- Javascript
- mom
- ORM
- spring
- 자바8
- MessageQueue
- stream api
- java
- 제이쿼리그리드
- sqlserver
- mssql
- JQuery
- QueryDSL
- 스트림
- 엑셀 업로드
- 그리드
- 보안
- Today
- Total
개발 메모장
[QueryDSL] QueryDSL 사용방법(1) 본문
#. Q타입 호출하기
- Entity를 생성하고 @Entity 어노테이션을 추가한 뒤 QueryDSL을 build 하면 plugin에서 설정한 경로에 Q타입을 생성할 것입니다.
- 해당 Q타입 객체를 사용하기 위해 아래 내용을 입력해 줍니다.
- 또한 jpaQueryFactory 사용을 위해 JPAQueryFactory 또한 선언해 줍니다.
- custom 한 레파지토리를 사용할 경우 상속 및 해당 customRepository에 선언해 주시면 됩니다.
@Autowired
private JPAQueryFactory jpaQueryFactory;
private QMemberEntity qMember = QMemberEntity.memberEntity;
#. fetch를 통한 데이터 반환
- fetch를 이용해 호출한 데이터의 return 결과를 정할 수 있습니다.
- fetch를 이용한 결과 반환의 경우 보통 5가지로 구분합니다.
1. fetchOne()
- 호출한 데이터가 단건일 때 사용합니다.
- 다건의 데이터를 호출하게 될 경우 오류가 발생(NonUniqueResultException) 합니다.
@GetMapping("fetch")
public void fetchTest() {
MemberEntity result = jpaQueryFactory.select(qMember)
.from(qMember)
.fetchOne();
}
2. fetchFirst()
- 호출한 데이터들 중 첫 번째 값을 반환합니다.
- 단건이건 다건이건 무조건 첫 번째 값만 반환합니다.
- 실행 시 아래와 같이 쿼리를 생성하여 데이터를 조회합니다.
@GetMapping("fetch")
public void fetchTest() {
MemberEntity result = jpaQueryFactory.select(qMember)
.from(qMember)
.fetchFirst();
}
3. fetch()
- 호출한 데이터들을 List로 반환합니다.
@GetMapping("fetch")
public ResponseEntity<List<MemberEntity>> fetchTest() {
List<MemberEntity> result = jpaQueryFactory.select(qMember)
.from(qMember)
.fetch();
return ResponseEntity.ok(result);
}
4. fetchCount()
- 호출한 데이터의 개수를 반환합니다.
- deprecated 되었지만 간단하게 처리할 때 사용가능합니다.
@GetMapping("fetch")
public ResponseEntity<Long> fetchTest() {
Long result = jpaQueryFactory.select(qMember)
.from(qMember)
.fetchCount();
return ResponseEntity.ok(result);
}
5. fetchResults()
- QueryDSL에서 제공하는 리턴타입인 QueryResults를 통해 번들 데이터를 반환받습니다.
- offSet, Total, 호출 데이터 등을 반환받습니다.
- 이 또한 deprecated 되어 거의 사용하진 않습니다.
@GetMapping("fetch")
public ResponseEntity<QueryResults<MemberEntity>> fetchTest() {
QueryResults<MemberEntity> result = jpaQueryFactory.select(qMember)
.from(qMember)
.fetchCount();
return ResponseEntity.ok(result);
}
#. where 절 연산하기
- where 조건 인스턴스에 들어갈 연산에 대한 내용으로 and, or, =, !=, berween 등을 표현할 수 있습니다.
1. eq
- query에서 =과 같은 역할을 합니다.
@GetMapping("oper")
public ResponseEntity<List<MemberEntity>> operTest(String keyword) {
List<MemberEntity> eqResult = jpaQueryFactory.selectFrom(qMember)
.where(qMember.name.eq("홍글동"))
.fetch();
return ResponseEntity.ok(eqResult);
}
2. ne
- query에서 !=, <>과 같은 역할을 합니다.
@GetMapping("oper")
public ResponseEntity<List<MemberEntity>> operTest(String keyword) {
List<MemberEntity> neResult = jpaQueryFactory.selectFrom(qMember)
.where(qMember.name.ne("홍글동"))
.fetch();
return ResponseEntity.ok(neResult);
}
3. between
- query에서 between과 같은 역할을 합니다.
@GetMapping("oper")
public ResponseEntity<List<MemberEntity>> operTest(String keyword) {
List<MemberEntity> betResult = jpaQueryFactory.selectFrom(qMember)
.where(qMember.age.between(30, 35))
.fetch();
return ResponseEntity.ok(betResult);
}
4. in
- 마찬가지로 in과 같은 역할을 하며 인자 구분은 콤마로 합니다.
@GetMapping("oper")
public ResponseEntity<List<MemberEntity>> operTest(String keyword) {
List<MemberEntity> inResult = jpaQueryFactory.selectFrom(qMember)
.where(qMember.age.in(34, 35))
.fetch();
return ResponseEntity.ok(inResult);
}
5. like
- like와 같은 역할을 하며 인자로 String형이 입력되어야 합니다.
- 입력 시 % 기호를 같이 넣어줘야 합니다.
@GetMapping("oper")
public ResponseEntity<List<MemberEntity>> operTest(String keyword) {
List<MemberEntity> likeResult = jpaQueryFactory.selectFrom(qMember)
.where(qMember.name.like("%덕배%"))
.fetch();
return ResponseEntity.ok(likeResult);
}
6. contains
- like와 비슷한 역할을 합니다.
- like 인스턴스에는 %를 직접 처리해야 했으나 contains에선 String 인자에 %%를 붙여줍니다.
@GetMapping("oper")
public ResponseEntity<List<MemberEntity>> operTest(String keyword) {
List<MemberEntity> containsResult = jpaQueryFactory.selectFrom(qMember)
.where(qMember.name.contains("드록"))
.fetch();
return ResponseEntity.ok(containsResult);
}
#. Sorting
- order by의 역할을 하는 정렬을 처리하는 방법에 대해 알아보도록 하겠습니다.
- 여느 order by와 동일하게 컬럼.asc, desc로 처리 가능합니다.
- 해당 컬럼의 null 값이 있을 경우 먼저(nullsFirst()) 또는 마지막(nullsLast())으로 호출하는 인스턴스도 있으니 필요에 따라 사용하시길 바랍니다.
@GetMapping("sort")
public ResponseEntity<List<MemberEntity>> sortTest() {
List<MemberEntity> result = jpaQueryFactory.selectFrom(qMember)
.orderBy(qMember.nickname.desc().nullsFirst())
.fetch();
return ResponseEntity.ok(result);
}
#. Group By & Having
- query에서 사용하는 group by와 having은 queryFactory의 인스턴스를 이용해 바로 처리가 가능합니다.
- return 하여 화면에 뿌려주기 위해 ListMap에 담아 처리하였습니다.
@GetMapping("grouping")
public ResponseEntity<List<Map<String, Object>>> groupingTest() {
List<Tuple> result = jpaQueryFactory.select(qMember.name, qMember.age, qMember.email)
.from(qMember)
.groupBy(qMember.age, qMember.email)
.having(qMember.age.eq(34))
.orderBy(qMember.age.asc())
.fetch();
List<Map<String, Object>> resultMapList = new ArrayList();
for (Tuple tuple : result) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("name", tuple.get(qMember.name));
resultMap.put("ageCount", tuple.get(qMember.age));
resultMap.put("email", tuple.get(qMember.email));
resultMapList.add(resultMap);
}
return ResponseEntity.ok(resultMapList);
}
#. join
- join 할 테이블을 하나 만들어주기 위해 OrderEntity를 만들어 줍니다.
- MemberEntity와 동일하기 getter, setter, builder를 생성해 주고 controller에서 insert 하는 로직을 만듭니다.
- 추가로 jpa를 상속받고 있는 MemberRepository의 제네릭은 MemberEntity이므로 OrderRepository에 새로 상속하였습니다.
- query에서의 조인과 동일하게 사용할 수 있습니다. 다만 N+1 문제가 발생할 수 있으므로 상황에 따라 fetchJoin()을 사용하시는 것이 좋습니다.
@GetMapping("join")
public ResponseEntity<List<Map<String, Object>>> joinTest() {
List<Tuple> result = jpaQueryFactory.select(qMember.name, qMember.age, qOrder.name, qOrder.sp)
.from(qMember)
.join(qOrder).fetchJoin()
.on(qMember.id.eq(qOrder.id))
.fetch();
List<Map<String, Object>> serializedResult = new ArrayList<>();
for (Tuple tuple : result) {
Map<String, Object> tupleMap = new HashMap<>();
tupleMap.put("name", tuple.get(qMember.name));
tupleMap.put("orderName", tuple.get(qOrder.name));
tupleMap.put("age", tuple.get(qMember.age));
tupleMap.put("sp", tuple.get(qOrder.sp));
serializedResult.add(tupleMap);
}
return ResponseEntity.ok(serializedResult);
}
#. 함수
- avg, sum, min, max, round, floor, ceil 등 호출한 컬럼값을 기본적으로 제공해 주는 함수를 이용해 쉽게 얻을 수 있습니다.
@GetMapping(value = "func", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Map<String, Object>> funcTest() {
List<Tuple> result = jpaQueryFactory.select(qMember.age.avg().round(),
qMember.age.sum(),
qMember.age.max(),
qMember.age.min(),
qMember.age.count())
.from(qMember).fetch();
Tuple tupleResult = result.get(0);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("avg", tupleResult.get(0, Double.class));
resultMap.put("sum", tupleResult.get(1, Integer.class));
resultMap.put("max", tupleResult.get(2, Integer.class));
resultMap.put("min", tupleResult.get(3, Integer.class));
resultMap.put("count", tupleResult.get(4, Long.class));
return ResponseEntity.ok(resultMap);
}
===========================================================
틀린 내용이 있거나 이견 있으시면 언제든 가감 없이 말씀 부탁드립니다!
===========================================================
'ORM' 카테고리의 다른 글
[QueryDSL] QueryDSL Projection (0) | 2024.02.01 |
---|---|
[QueryDSL] QueryDSL 사용방법(2) (1) | 2024.01.31 |
[JPA] JPA의 정의와 사용 예제 (1) | 2024.01.10 |
[QueryDSL] QueryDSL 정의 및 설정방법 (0) | 2024.01.08 |
[myBatis] myBatis 사용방법 (1) | 2023.12.26 |