사용자 도구

사이트 도구


java:jpa:nativequery

JPA and Native Query (SQL)

NativeSQL 결과 암묵적 Entity 매핑

  • Native Query 결과를 entity 로 받는 방법으로 암묵적으로 할수도 있다.
  • EntityManager.createNativeQuery(“SQL”, EntityClass.class).getSingleResult() 사용
Book b = (Book) em.createNativeQuery("SELECT * FROM book b WHERE id = 1", Book.class).getSingleResult();

NativeSQL 결과 명시적 Entity 매핑 : ResultSetMapping

  • 단일 엔티티에 대한 Native Query 실행은 매핑이 필요없다.
  • 다중 Entity를 결과로 받는 Native Query는 @SqlResultSetMapping로 매핑 정보를 지정해야 하며 그 결과는 List<Object[]>로 리턴한다.
    • Object[]에는 SqlResultSetMapping에 지정된 순서대로 결과 엔티티 객체가 들어온다.
  • NativeQuery Result Set Mapping은 모든 필드를 명백히 기술해서 매핑해 주자. 그렇지 않으면 컬럼의 변경이 발생하거나 두 개 이상 엔티티에 대한 매핑시 동일 컬럼 이름 존재시 심각한 오류가 발생할 수 있다.
  • 두 개 이상의 엔티티를 로딩하는데 그 것들이 서로 연관 관계일 경우 이미 연관 관계가 자동으로 채워진 상태의 엔티티가 생성된다. 이미 Native Query 결과 객체(result set mapping)내에 연관에 관한 데이터 매핑이 있으면 다시 쿼리를 날리지 않는다.
  • 애노테이션보다는 JPA XML Configuration - orm.xml을 이용해서 매핑을해주는 것이 더 합리적으로 보인다.

XML 예제

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings
  xmlns="http://java.sun.com/xml/ns/persistence/orm"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
    http://java.sun.com/xml/ns/persistence/orm
    http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
  version="2.0">
  <sql-result-set-mapping name="nativesql_mapping_example">
    <entity-result entity-class="kr.pe.kwonnam.Book">
      <field-result name="id" column="bk.id" />
      <field-result name="title" column="bk.title" />
      <field-result name="price" column="bk.price" />
      <!-- Author writer, Long writerId 매핑이 함께 존재할경우 -->
      <field-result name="writerId" column="bk.writer_id" />
      <field-result name="writer" column="bk.writer_id" />
    </entity-result>
    <entity-result entity-class="kr.pe.kwonnam.Author">
      <field-result name="id" column="at.id" />
      <field-result name="name" column="at.name" />
    </entity-result>
  </sql-result-set-mapping>
</entity-mappings>

필드 매핑시 주의할 점

  • @ManyToOne의 One 측에 대한 매핑 컬럼이 존재하는 경우에 해당 컬럼과 필드명도 매핑해야한다.
    • 예를들어 ArticleBoard의 자식이고 Article에 대해 매핑할 경우
    • Article.boardIdArticle.board 필드 두개를 모두 매핑해두었다면
    • boardIdarticle.board_id와, boardarticle.board_id 이렇게 두 번의 필드 매핑을 해줘야 한다.

in 파라미터 매핑

  • JPA (2.1 에서 테스트) 일반 Query / Native Query 모두 in 파라미터 매핑을 지원
  • 단, 파라미터 매핑시 in (:paramName) 형태가 아닌 in :paramName 형태로 쿼리를 만들어야 한다.

참고

java/jpa/nativequery.txt · 마지막으로 수정됨: 2021/01/05 14:38 저자 kwon37xi