2021. 2. 14. 17:28ㆍ프로그래밍 언어/Spring Framework
[인프런 김영한] JPA - 객체지향 쿼리 언어(JPQL, CRITERIA, QueryDSL, 네이티브 SQL, JDBC)
해당 글은 인프런 김영한강사님의 영상을 보고 정리한 글입니다.
Spring Boot, Spring Data JPA를 사용해 실습하였습니다.
김영한 인프런 : www.inflearn.com/users/@yh
▣ JPQL 등장 배경
* JPA를 사용하면 Entity 객체를 중심으로 개발
- 하지만 문제는 검색 쿼리
- 검색ㄱ을 할 때도 Table이 아닌 Entity객체를 대상으로 검색
* 모든 DB데이터를 객체로 변환해서 검색하는 것을 불가능
- 애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요
▣ JPQL
* JPA는 SQL을 추상화한 JPQL이라는 객체지향쿼리 언어 제공
- SQL과 문법 유사(SELECT, FROM, WHERE, JOIN 지원) , ANSI표준 문법은 다 지원함.
* JPQL은 Entity 객체를 대상으로 쿼리
- SQL을 추상화해서 특정 DB SQL에 의존하지 않는다.
- JPQL을 한마디로 정의하면 객체지향 SQL
* SQL은 DB Table을 대상으로 쿼리
@Query("select m from Member m where m.username like '%kim%'")
List<Member> findByMemberName();
//실행
Hibernate:
select
member0_.member_id as member_i1_2_,
member0_.city as city2_2_,
member0_.street as street3_2_,
member0_.zipcode as zipcode4_2_,
member0_.username as username5_2_
from
member member0_
where
member0_.username like '%kim%'
▣ 단점
* 동적쿼리문 만듥기가 힘듬
(쉼표, 띄어쓰기 등 신경쓸께 많음)
- 그래서 Mybatis는 동적쿼리 만들기 쉬워서 병행해서 사용하기도 한다.
* 동적쿼리 만들기 힘들기 때문에 Criteria를 사용함.
▣ Criteria
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Member> query = cb.createQuery(Member.class);
// 쿼리를 코드로 작성
Root<Member> m = query.from(Member.class);
CriteriaQuery<Member> cq = query.select(m).where(cb.equal(m.get("username"), "kim"));
List<Member> resultList = em.createQuery(cq).getResultList();
//실행
Hibernate:
select
member0_.member_id as member_i1_2_,
member0_.city as city2_2_,
member0_.street as street3_2_,
member0_.zipcode as zipcode4_2_,
member0_.username as username5_2_
from
member member0_
where
member0_.username=?
| 쿼리를 코드로 작성하는것을 볼 수 있다.
나중에 테이블이 많아지고 복잡해지면 작성하기 힘들다.
* 쿼리 오류를 바로 알 수 있다. IDE에서 알려준다.
* 동적쿼리를 만들기 쉽다.
* SQL스럽지 않다는게 단점이다.
- 김영한님은 실무에서 한두번 써봤지만 알아보기 힘들고 유지보수하기 힘들어서 사용하지 않는다.
- Criteria를 사용하지 않으면 어떤걸 사용하고 있나 -> QueryDSL 사용 권장
▣ QueryDSL
// 세팅이 필요하며 QueryDSL은 다른 강의에서 자세히
* 문자가 아닌 자바코드로 JPQL을 작성할 수 있음
* JPQL 빌더 역활
* 컴파일 시점에 문법 오류를 찾을 수 있음.
* 동적쿼리 작성 편리함
* 단순하고 쉬움
* 실무사용 권장
▣ 네이티브 SQL
* JPA가 제공하는 SQL을 직접 사용하는 기능
* JPQL로 해결할 수 없는 특정 데이터베이스에 의존적인 기능
( 오라클 CONNECT BY, 특정 DB만 사용하는 SQL 힌트 )
// 네이티브 SQL
List resultList1 = em.createNativeQuery("select MEMBER_ID, city from MEMBER").getResultList();
▣ JDBC 직접 사용, SpringJdbcTemplate 등
* JPA를 사용하면서 JDBC 커넥션을 직접 사용하거나, 스프링 JdbcTemplate, Mybatis를 함께 사용
* 단 영속성 컨텍스트를 적절한 시점에 강제로 플러시 필요
( JPA를 우회해서 SQL을 실행하기 직전에 영속성 컨텍스트를 수동으로 플러시 )
// JDBC 주의사항
Member member = new member();
member.setUsername("member");
em.persist(member);
// em.flush()를 하지 않으면 db에 값이 없기 때문에 결과는 0
em.flush(); // 수동으로 flush
// dbconn.excuteQuery("select * from member");
for(Member member1 : resultList){
System.out.println("member1 = " + member1);
}
tx.commit;
▣ 김영한님의 추천 조합 ▣
JPQL + QueryDSl
'프로그래밍 언어 > Spring Framework' 카테고리의 다른 글
[인프런 김영한] JPA - JPQL 프로젝션(SELECT) (0) | 2021.02.16 |
---|---|
[인프런 김영한] JPA - JPQL 기본문법 (0) | 2021.02.15 |
[인프런 김영한] JPA - 값 타입 컬렉션 (0) | 2021.02.14 |
[인프런 김영한] JPA - 값 타입과 불변 객체 (0) | 2021.02.12 |
[인프런 김영한] JPA - 임베디드 타입(복합 값 타입) (0) | 2021.02.12 |