다양하게 있는데 진짜 왠만하면 JPQL, QueryDSL로 대부분 해결되고 진짜 안되는게 있을 땐 SpringJdbcTemplate로 해결한다. 거의 무조건 QueryDSL 사용을 추천.
jpql은 쌩 sql과 매우 유사하며 대상이 테이블 객체가 아니라 jpa 객체라는데에 있다.
위 jpql의 경우 쌩 string을 넣기 때문에 동적 쿼리가 힘듬. 그래서 criteria라고 공식으로 지원하는 스펙이 있고, 자바 코드로 짜기 때문에 문법 오류 잡아주고 동적쿼리 하기 쉽고 하다는 장점이 있지만 진짜 뒤지도록 복잡하다.. 걍 안쓴다.
querydsl은 진짜 직관적이고 정말 좋다. 자바코드라 문법도 잡아주고 동적도 정말 쉽고 왠만한건 다 이걸로 해결된다. 그냥 이거 써라.
jpal말고 진짜 쌩 sql도 날릴 수 있는데 이건 oracle이나 mysql같은 그 언어 방언을 직접 써야 할 때 사용한다. 주의점은 이것도 jpa에서 관리해주기 때문에 이걸 날리기 전에 jpa에서 실제 db에 반영하기 위해 flush를 날리지만 가끔 어떻게 어떻게 해서 아직 영속성 컨텍스트에만 있어서 반영이 안되었는데 조회 쿼리를 날리는게 가능한 경우가 있다. 그래서 직접 flush를 해주고 사용하자.
jpql 문법을 알아보자.
진짜 sql이랑 거의 유사하다. count 같은것도 쓸 수 있다.
getSingleResult의 경우, 결과가 없으면 예외를 내는것에 논란이 좀 있었다고 한다. 그냥 null 하는게 맞지않나 하고.. 그래서 jpa는 저 예외만 try catch로 잡아서 Optional로 해서 예외가 아닌 null을 반환한다.
파라미터도 설정할 수 있다.
select로 대상 지정하는 경우들을 보자.
엔티티 프로젝션이라고 하는 이유는 진짜 추적 가능한 엔티티를 주기 때문.
엔티티이기에 추적해서 update 한다.
해당 객체 안에 있는 다른 객체를 불러올 경우, 안에서 자체적으로 join을 한다. 근데 그러면 안에서 join이 일어난다는 사실을 모르니 직접 적어주는 편이 좋음.
임베디드는 어딘가에 소속되어 있기 때문에 직접 from Address 식으로 적을 순 없고 소유하고 있는 객체를 한번 거쳐야 한다.
스칼라 타입 프로젝션이든 select해서 여러개 받는 방법은 또 방법이 여러개 있다.
Object로 cast해서 받아오기
타입 cast를 미리 해서 생략하기
다음은 추천하는 방법인 이 select를 위한 dto 클래스를 만들고 new를 써서 추적가능한 entity로 만든 뒤 깔끔하게 가져오기.
페이징 API는 이 페이징을 위한 sql코드라는게 각 db마다 달라가지고 막 머리빠져서 추상화해서 사용할 수 없을까 해주는걸 jpa가 해준거. setFirstResult로 offset을 설정하는 것과, 어디까지 가져갈지 setMaxResults 2개만 하면 자기가 각 db 방언들로 알아서 번역해서 해준다.
설정을 다른 db로 바꾸면 sql 다르게 바뀌어서 나감.
세타 조인은 연관관계 없는것도 어거지로 하려고 있는것. 그냥 cross join
jpa 버전이 업 되면서 추가 가능 2가지를 제공하는데, 조인 할 대상에 이미 필터링을 한번 한 뒤 조인하는 것. 그래서 성능을 향상시킬 수 있고 연관관계가 없는 엔티티도 외부조인 할 수 있다.
보면 and해서 미리 필터링 한 뒤 join하는걸 볼 수 있음.
연관관계 없는거는 외래키로 엮은게 아니라도 해주는거
쿼리 안의 쿼리인 서브쿼리~
한계가 중요
from절 서브 쿼리를 안써도 보통 select 절의 서브 쿼리로 해결할 수 있고, 정 안되면 네이티브 sql을 쓰던가 sql문을 2번 사용하던가 하면 된다. 이것마저도 안되면 그냥 가져와 서버단에서 처리해도 되고. 사실 하이버네이트 6부터는 지원한다.
근데 굳이 막 타입까지 변수로 저장해서 하고 막 할 필요는 잘 없다. 어차피 querydsl 쓸거거든..
타입도 잘함. 타입은 엔티티 부모 자식 관계에서 DTYPE 있었는데 이거에 쓰는거
그냥 sql이랑 똑같다.
함수는 크게 2가지 종류로 볼 수 있는데, 기본으로 주어지는 sql과 유사한 함수와 직접 정의하는 사용자 정의 함수다.
함수를 사용할 일이 정말 많지만 다행히도 이미 각 db에 따라 정의되어 있는 함수들이 많다.
jpa만을 위한 특이한 함수인 size. 해당 컬렉션 엔티티에 얼마나 들어있나 보여줌.
사용자 정의 함수는 이미 있는걸 참고해서 만들면 된다.
'CS > 김영한 스프링 강의' 카테고리의 다른 글
실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화 - 섹션1. API 개발 기본 (0) | 2023.10.05 |
---|---|
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 섹션 11. 객객체지향 쿼리 언어2 - 중급 문법 (JPQL) (0) | 2023.10.04 |
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 섹션 9. 값 타입 (0) | 2023.09.23 |
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 섹션 8. 프록시와 연관관계 관리 (1) | 2023.09.23 |
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 섹션 7. 고급 매핑 (0) | 2023.09.22 |