HQL - API

Hibernate 2008. 4. 13. 02:04
session.createQuery("hql...") 메서드는 hql 질의를 위한 Query 타입의 객체를 생성합니다.
이제 돌려 받은 Query 타입의 객체로부터 질의를 수행할 수 있습니다.

list() 메서드를 이용해 하나 이상의 객체를 조회할 수 있습니다.
Query query = session.createQuery("from Article");
List<Article> list = query.list();

페이징도 아주 간단 합니다.
Query query = session.createQuery("from Article");
query.setFirstResult(0);
query.setMaxResult(20);
List<Article> list = query.list();
setFirstResult() 메서드의 인자는 첫번째 행을 0부터 시작합니다.
setMaxResult() 메서드의 인자는 가져올 행의 수 입니다.

또는 단 하나의 객체만 조회할 수 도 있습니다.
Query query = session.createQuery("from Article a where a.id = 5");
Article article = (Article)query.uniqueResult();

JDBC 스타일의 ?(위치 파라미터)도 지원 합니다.
Query query = session.createQuery("from Article a where a.id = ?");
query.setInt(0, 5);
JDBC의 그것과 다를 것 없이 메서드들이 너무나 친숙 합니다.
다른점이 있다면 JDBC의 파라미터 인덱스는 1부터 시작하지만 hql에서는 0부터 시작 합니다.

명명된 파라미터는 ?(위치 파라미터)보다 더 직관적 입니다.
Query query = session.createQuery("from Article a where a.id = :id");
query.setInt("id", 5);
순서에 영향을 받지 않고 동일한 파라미터에 대해 모두 적용되며 쿼리문 자체로 문서 역할을 해줍니다.

파라미터 설정을 위한 또 다른 메서드 입니다.

setParameter(String name, Object val)
첫번째 인자는 명명된 파라미터, 두번째 인자는 값 입니다. 타입은 하이버네이트가 판단 합니다.
setParameter(String name, Object val, Type type)
위 메서드와 동일하며 세번째 인자로 타입을 지정하는데 지정되는 타입들은 Hibernate 클래스에 상수로 정의되어 있습니다.

객체지향 쿼리인 만큼 파라미터에 엔티티를 설정 할 수 있습니다.
Member member = session.get(Member.class, 1);
Query query = session.createQuery("from Article a where a.member = :member);
query.setEntity("member", member);
List<Article> list = query.list();
조회를 하면 select ... from Article a where a.memberid = ? 형태의 쿼리가 수행 됩니다.

엔티티 대신 엔티티의 프로퍼티들을 설정 할 수도 있습니다.
Article article = (Article)session.get(Article.class, 1);
Query query = session.createQuery("from Article a where a.title = :title and a.date = :date");
query.setProperties(article);

엔티티가 아닌 프로퍼티들을 조회할 수 있습니다.
Query query = session.createQuery("select id, title from Article");
List<Object []> list = query.list();
for (Object[] row : list) {
    System.out.println(row[0]);
    System.out.println(row[1]);
}
Object 배열을 리스트로 돌려 준다는걸 명심해야 합니다.

캐쉬를 활용할 수 있습니다.
list() 메서드는 수행할 때마다 DB에서 객체의 모든 프로퍼티를 조회하는 반면
iterate() 메서드는 객체의 식별 값만 조회 한다는 차이가 있습니다. 식별 값만 조회하는 이유는 1, 2차 캐쉬를 이용하기 위해서 입니다.
Query query = session.createQuery("from Article");
Iterator<Article> iter = query.iterate();
while (iter.hasNext()) {
    Article article = iter.next();
    System.out.println(article.getTitle());
}
iter.next() 로 리턴되는 객체는 1, 2차 캐쉬에 존재한다면 캐쉬에 있는 객체를 리턴하고
캐쉬에 없다면 식별자 값을 가지고 있는 프록시 객체를 리턴 하고 프로퍼티 사용 시점에 데이터를 조회 합니다.
한번 열려진 iterator 는 모든 행을 읽거나 Session이 종료될 때까지 열려 있게 되는데 명시적으로 Hibernate.close(iter) 메서드를 통해 닫을 수 있습니다.

스크롤 할 수 있습니다.
scroll() 메서드는 JDBC의 스크롤 가능한 ResultSet과 동일한 기능을 수행하는 ScrollableResults 객체를 리턴 합니다.
Query query = session.createQuery("from Article");
ScrollableResults scroll = query.scroll();
주요 메서드는 생략 하겠습니다.

코드를 줄일 수 있습니다.
Query 인터페이스의 파라미터 설정 메서드들은 모두 자기 자신을 리턴 합니다.
따라서 이런 식으로 코드를 줄일 수 있습니다.
Article aritlce = (Article)session.createQuery("from Article a where a.id = ?")
                        .setInt(0, 5).uniqueResult();

iBATIS 스타일(네임드 쿼리)
iBATIS 처럼 쿼리를 매핑 파일로 분리할 수 있습니다.
<hibernate-mapping>
    <query name="getArticle">
    <![CDATA[
        from Article where id = :id
    ]]>
    </query>
</hibernate-mapping>

분리된 쿼리는 getNamedQuery() 메서드를 통해 가져올 수 있습니다.
Query query = session.getNamedQuery("getArticle");

'Hibernate' 카테고리의 다른 글

HQL - where 절  (0) 2008.04.13
HQL - 시작, from 절  (0) 2008.04.13
HQL - API  (0) 2008.04.13
늦은로딩과 조회방식  (0) 2008.04.09
동시 접근 제어  (0) 2008.03.29
openSession()과 currentSession()의 close()  (0) 2008.03.04
Posted by 째코

댓글을 달아 주세요