8장. Native 질의

당신은 또한 당신의 데이터베이스의 native SQL dialect 내에 질의들을 표현할 수 있다. 당신이 Oracle에 있는 질의 힌트들 또는 CONNECT BY 옵션과 같은 데이터베이스에 특정한 특징들을 활용하고자 원할 경우에 이것이 유용하다. 그것은 또한 하나의 직접적인 SQL/JDBC 기반의 어플리케이션으로부터 Hibernate로의 하나의 명료한 이전 경로를 제공한다. Hibernate3은 모든 create, update, delete, 그리고 load 연산들에 대해 (내장 프로시저를 포함한) 손으로 작성된 SQL을 지정하는 것을 당신에게 허용해줌을 노트하라(추가 정보는 참조 안내서를 참조하길 바란다.)

8.1. 결과셋을 표현하기

하나의 SQL 질의를 사용하기 위해, 당신은 SQL 결과셋을 설명할 필요가 있고, 이 설명은 EntityManager으로하여금 당신의 컬럼들을 엔티티 프로퍼티들 상으로 매핑시키기는 것을 도와줄 것이다. 이것은 @SqlResultSetMapping 주해를 사용하여 행해진다. 각각의 @SqlResultSetMappingEntityManager 상에 한 개의 SQL 질의를 생성시킬 때 사용되는 한 개의 이름을 갖는다.

@SqlResultSetMapping(name="GetNightAndArea", entities={
    @EntityResult(name="org.hibernate.test.annotations.query.Night", fields = {
        @FieldResult(name="id", column="nid"),
        @FieldResult(name="duration", column="night_duration"),
        @FieldResult(name="date", column="night_date"),
        @FieldResult(name="area", column="area_id")
    }),
    @EntityResult(name="org.hibernate.test.annotations.query.Area", fields = {
        @FieldResult(name="id", column="aid"),
        @FieldResult(name="name", column="name")
    })
    }
)

//or
@SqlResultSetMapping(name="defaultSpaceShip", entities=@EntityResult(name="org.hibernate.test.annotations.query.SpaceShip"))

@SqlResultSetMapping.에 대한 추가 정보는 Hibernate Annotations 참조 안내서를 참조하길 바란다.

참고

현재의 구현은 native SQL 질의들 내에 스칼라 결과들을 지원하지 않는다.

8.2. native SQL 질의들을 사용하기

TODO: 이것은 사기처럼 들린다...

결과 셋이 설명되고, 우리가 native SQL 질의를 실행하는 가용성이 있다는 점을 노트하라. EntityManager는 모든 필요한 API들을 제공한다. 첫 번째 메소드는 바인딩을 행하는데 한 개의 SQL 결과셋 이름을 사용하는 것이고, 두 번째 메소드는 엔티티 디폴트 매핑을 사용한다(반환된 컬럼은 매핑에서 사용된 컬럼 이름과 동일한 이름을 가져야 한다). (아직 Hibernate 엔티티 관리자에 의해 지원되지 않는) 세 번째 메소드는 순수 스칼라 결과들을 반환한다.

String sqlQuery = "select night.id nid, night.night_duration, night.night_date, area.id aid, "
    + "night.area_id, area.name from Night night, Area area where night.area_id = area.id "
    + "and night.night_duration >= ?";
Query q = entityManager.createNativeQuery(sqlQuery, "GetNightAndArea");
q.setParameter( 1, expectedDuration );
q.getResultList();

이 native 질의는 GetNightAndArea 결과 셋에 기반하여 night들과 area를 반환한다.

String sqlQuery = "select * from tbl_spaceship where owner = ?";
Query q = entityManager.createNativeQuery(sqlQuery, SpaceShip.class);
q.setParameter( 1, "Han" );
q.getResultList();

두 번째 버전은 당신의 SQL 질의가 메타데이터 내에 매핑된 컬럼들과 동일한 컬럼들을 재사용하여 한 개의 엔티티를 반환할 때 유용하다.

8.3. 명명된 질의들

native 명명된 질의들은 EJB-QL 명명된 질의들과 동일한 호출 API를 공유한다. 당신의 코드는 둘 사이의 차이점을 알 필요가 없다. 이것은 SQL로부터 EJB-QL로의 이관에 매우 유용하다:

Query q = entityManager.createNamedQuery("getSeasonByNativeQuery");
q.setParameter( 1, name );
Season season = (Season) q.getSingleResult();