Develop/JPA
[자바 ORM 표쥰 JPA 프로그래밍] 25일차 - NativeSQL
자라선
2021. 11. 18. 17:33
1. Native SQL
JPQL은 표준 SQL로 지원해서 특정 DB에 종속적이진 않지만 이 때문에 특정 DB의 기능을 사용하지 못하게 된다.
그래서 NativeSQL을 지원하여 이러한 문제점을 해결해준다.
- 특정 DB만 지원하는 함수나 문법, SQL의 쿼리 힌트
- 인라인 뷰(From 절에 서브쿼리), UNION, INRTERSECT 등
- 프로시저
String sql = "SELECT id, age, username, members FROM Member WHERE age > ?";
final Query query = em.createNativeQuery(sql, Member.class).setParameter(1, 20);
query.getResultList();
NativeSQL를 사용한 코드인데 것만 보면 일반 JDBC API를 사용하여 쿼리 호출한것과 비슷하지만
가장 큰 차이점은 쿼리의 결과물을 영속성 컨텍스트에 담아준다는 것이다.
2. NamedQuery
직접 개발자가 SQL을 소스상에 작성하기에는 가독성을 위해 줄바꿈 처리를 매번 하게 되는데
JAVA에서는 줄바꿈처리를 하게되면 작성하기 힘들어진다.
JPQL의 NamedQuery 처럼 XML에 동일하게 작성하여 적용할 수 도 있다.
META-INF/ormMember.xml
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm" version="2.1">
<!-- result-set-mapping 속성으로 지정하여 반환되는 컬럼을 지정해준다. -->
<named-native-query name="Member.memberWithOrderCountXml" result-set-mapping="memberWithOrderCountResultMap">
<query>
<![CDATA[
SELECT M.ID, AGE, USERNAME, TEAM_ID, I.ORDER_COUNT
FROM MEMBER M
LEFT OUTER JOIN (SELECT IM.ID, COUNT(*) AS ORDER_COUNT
FROM ORDERS O, MEMBER IM
WHERE O.MEMBER_ID = IM.ID
GROUP BY IM.ID) I
ON M.ID = I.ID
]]>
</query>
</named-native-query>
<!-- 반환되는 컬럼을 지정 -->
<sql-result-set-mapping name="memberWithOrderCountResultMap">
<entity-result entity-class="jpa.entity.Member" />
<column-result name="ORDER_COUNT" />
</sql-result-set-mapping>
</entity-mappings>
// Object[] 로 받아 각 row 별로 출력한다.
final List<Object[]> resultList = em.createNamedQuery("Member.memberWithOrderCountXml")
.getResultList();