본문 바로가기

TIL

[TIL 2022-3-7] JPQL, BOJ10830 행렬 제곱

JPA JPQL

JPA는 SQL을 추상화한 객체지향 쿼리언어 JPQL을 제공한다. JPQL을 통해 검색 조건을 포함한 SQL을 테이블이아닌 객체를 대상으로 검색할 수 있다. 기본적으로 select, from, where, group by, having, join을 지원하기 때문에 거의 유사한 형태로 쿼리작성이 가능하다.(count, sum, av, max, min 등 사용 가능)

 

JPQL은 SQL을 추상화해서 사용하는 것 이므로 특정 데이터베이스에 의존하지 않는다. 즉 데이터베이스가 바뀌더라도 JPQL은 수정할 필요 없다. 결국 JPQL은 하이버네이트에 의해 설정된 SQL언어에 맞게 SQL로 변환되어 실행된다.

 

 

기본문법

JPQL 쿼리를 사용해서 나이가 19세 이상인 멤버리스트를 데이터베이스에서 가져와 이름과 나이를 순서대로 출력하는 코드를 작성하였다. sql과 다른점은 테이블이 아닌 엔티티를 통해 조회하므로 엔티티의 이름과 속성은 대소문자를 구분해야한다. 또 필수적으로 별칭을 만들어 사용해야한다(m). select, from 등은 sql과 같이 대소문자를 구분하지않는다.

 

위 코드의 결과로 JPA를 통해 아래와 같은 select 문이 만들어져 실행된다.

출력 결과

 

프로젝션

select 절에서 조회할 대상을 지정하는 것을 프로젝션이라고 한다. 예를들어 Member 엔티티를 대상으로 조회할 때 전체를 조회한다면 아래와 같이 JPQL을 작성할 수 있다.

Member 엔티티와 매핑된 테이블 전체 조회

 

 

또는 연관관계에 있는 Team 을 조회하려고 한다면 아래와 같이 할 수 있다.

Member 객체와 조인된 Team 객체에 매핑된 테이블 조회

이 JPQL을 통해 아래와 같은 SQL 이 생성된다.

위에서 설명한 JPQL 쿠리는 'select m.team from Member m' 과 똑같은 SQL쿼리를 만들지만 이는 하는 것이 좋다. 기본적으로 JPQL만 보고도 SQL쿼리를 쉽게 유추할 수 있어야 하므로 명시적으로 join 을 지정주자.

 

마지막으로 아래와 같이 스칼라 타입을 통한 조회가 가능하다.

 

이를 통해 원하는 데이터를 위해선 크게 두가지 방법이 존재한다.

일단 m.name, m.age는 따로 엔티티나 임베디드된 객체가 아니므로 조회하는 한 요소당 Object 배열로 매핑된다. 때문에 이를 Object 배열 리스트로 받아 사용할 수 있다. 위 코드의 실행 결과는 아래와 같다.

 

또는 필요한 데이터를 매핑하는 새로운 DTO 객체를 만들어 JPQL에서 new 키워드를 통해 데이터를 받는다.

다만 이때, DTO 객체는 패키지 경로까지 모두 적어줘야한다. Intellij 에 의해 보정되지만 결국 JPQL 또한 문자열이기 때문에 발생하는 한계라고 한다.

 

 

다른 부분에서는 JPQL이 엄청 편했는데 스칼라 타입을 조회하는 부분에서 매우 불편하게 느껴졌다. 이와 같은 부분들은 나중에 공부할 QueryDSL에서 해결된다는데 빨리 공부해보고 싶다!

 


코테 공부

2022.03.08 - [코테 공부] - 재귀에서 함수 호출 비용

 

재귀에서 함수 호출 비용

https://www.acmicpc.net/problem/10830 10830번: 행렬 제곱 크기가 N*N인 행렬 A가 주어진다. 이때, A의 B제곱을 구하는 프로그램을 작성하시오. 수가 매우 커질 수 있으니, A^B의 각 원소를 1,000으로 나눈 나머..

unannn.tistory.com

 

'TIL' 카테고리의 다른 글

[TIL] @DataJpaTest  (0) 2022.05.04
TDD의 장점  (0) 2022.04.08
[TIL 2022-3-6] 평범한 배낭  (0) 2022.03.07
[TIL 2022-2-28]스프링 부트와 AWS로 혼자 구현하는 웹 서비스  (0) 2022.02.28
[TIL 2022-2-25] JPA 값 타입, PriorityQueue  (0) 2022.02.26