Whiteship's Note

[하이버네이트 Criteria] 목록 사이즈 구하기

모하니?/Coding : 2010.05.27 10:47


난 편의상 이런 메서드들을 만들어 놓고 쓴다.

    private Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    private Criteria getCriteriaOf(Class clazz){
        return getSession().createCriteria(clazz);
    }

이 두개가 있다고 했을 때.. Criteria API를 이용해서 목록 사이즈를 구하는 코드를 작성해보자.

    public int totalSize() {
        return getCriteriaOf(Code.class).list().size();
    }

캬.. 얼마나 명시적인가. 하지만 이러면 안된다. ㅠ.ㅠ.. 난 하이버가 좀 더 똑똑해져서 저렇게 짜더라도 알아서 count 쿼리를 만들어 주면 좋겠지만 그러지 않는다. 전부다 select 해온다. 로그를 보면..

Hibernate: select this_.id as id0_0_, this_.code as code0_0_, this_.descr as descr0_0_, this_.name as name0_0_ from Code this_

이렇다. 필요한건 사이즈 뿐인데 Code 테이블에 있는걸 전부다 가져온 셈이다. 크헉.. 따라서 목록 사이즈를 구할 때는 이런 쿼리를 쓰면 안된다.. 절대로; 그럼 어떻게 할까나..

    public int totalSize() {
        return (Integer)getCriteriaOf(Code.class)
            .setProjection(Projections.count("id"))
            .uniqueResult();
    }

이렇게 하면된다. Projections를 이용하면 count 말고도 max, min등을 사용할 수 있다. 코드가 좀 길어지고 Projection API에 적응해야 한다는 단점이 있지만 쿼리는 깔끔해진다.

Hibernate: select count(this_.id) as y0_ from Code this_

딱 내가 원하던 쿼리다. 하이버네이트를 쓸땐 이렇게 Criteria나 HQL이 생성해주는 SQL도 일일히 확인하는것이 좋다. 사실 일일히 확인하는 작업을 DBA가 해주면 좋겠지만 하이버네이트랑 친한 DBA가 있을 때의 이야기이고 그렇지 않다면 본인이 해야겠다. 아니면 하이버네이트를 마스터해서 어떤 쿼리가 생성되는지 달달달 꽤고 있다면 시간을 좀 단축 시킬 수 있을 것 같기도 하다.

하이버네이트를 마스터 하기 위해서는 조마간 나올 하이버네이트 번역서가 필수라는....앗..  광고를 하려고 시작한 글은 아니었는데;; ㅋㅋㅋ

ps1: Criteria를 사용해서 좀 더 간결한 코딩으로 가져오는 방법이 있으면 알고 싶다.
ps2: 반드시 Criteria를 써야 한다. 나중에 저 쿼리에 검색 조건이 임의로 추가될텐데 그럴때 Criteria가 빛을 발하기 때문이다. 난 동적쿼리를 SQL이나 HQL로 짜지 못하겠다. 짜증난다.
top

  1. Favicon of http://lckymn.com BlogIcon Kevin 2010.05.27 18:36 PERM. MOD/DEL REPLY

    본문과는 좀 다른 얘긴데요,
    최근에 나온 Hibernate에서도 JPA 2.0을 지원하기
    시작해서 관련된 얘길 잠깐... ^^;

    하이버네이트가 JPA 2.0 지원 시작하면서 바로 갈아타고
    JPQL도 전부 Typesafe query API 사용하는걸로 대체 했습니다만...
    이거 API가... 영...ㅡ_ㅡ; 코드 가독성을 떨어뜨리네요.
    typesafety 말고는 QL 언어보다 장점을 못 찾겠습니다.
    (뭐 사실 그걸 장점으로 내세운거긴 합니다만...ㅡ_ㅡ; )
    부가 코드만 늘어나고... 장점에 따라오는 단점이 좀...

    리턴 타입이야 generics 사용해서 Query 랑 EntityManager 확장해서
    어느정도 typesafe 하게 만들수 있다보니,
    JPA 2.0의 typesafe queries 는 리턴타입 이외에도
    parameter의 typesafety 를 보장해준다는거 정도밖에는 장점을
    못 느끼겠습니다. 이게 꽤 큰 장점이긴 하지만,
    그나마도 따로 @StaticMetamodel annotation을 마킹한 class를
    작성해야 가능하니... 없이 만들면 기존의 setParameter 와 별 다를바가...

    나름대로 필요한 객체들 묶어서 CriteriaManager 를 만들어서 쓰니 조금 편하긴한데
    이래도 가독성 높이려면 뭔가 한참은 부족하네요...ㅡ_ㅡ;

    암튼 그래서 Querydsl 을 사용해 볼까도 고민중이긴 합니다만...
    http://source.mysema.com/display/querydsl/Querydsl

    Favicon of http://whiteship.me BlogIcon 기선 2010.05.27 23:50 PERM MOD/DEL

    저도 JPA2로 갈아탈까 고민했었는데 아직 스프링 번들 저장소에 라이브러리가 뜨지도 않았고 스프링 3.0.2 의존성도 아직 JPA2로 넘어가질 않아서 일단 하이버 3.4 쓰고 있습니다.

    JPA2에 있는 Criteria랑 하이버에 있던 Criteria랑 사용하는게 많이 다른가요? 하이버 Criteria API랑 많이 다르지만 않다면 넘어가볼까 합니다.

    쿼리 자체가 복잡하면 Criteria로 표현하는 것도 복잡하지만 SQL도 어쩔 수 없이 복잡해지지 않을까 싶네요. 하지만 SQL에 익숙하신 분들은 정말 Criteria가 더 복잡해 보일 수도 있을 것 같아요. 본문에 있는 내용도 거의 머;; @_@;;

  2. Favicon of https://slothink.tistory.com BlogIcon 편현장 2010.06.30 00:59 신고 PERM. MOD/DEL REPLY

    Projections.rowCount() 나, Projections.distinctCount() 도 좋지요. 보통 이런건 자주 쓰는거랑 하이버네이트 공통 클래스에다가 넣고 사용하곤 하는데, Code.class 에 대한 클래스 정의도 Dao 클래스에서 추상화시키면 더 간단해질거 같습니다. 그나저나, 하이버네이트 번역서 오늘 받아서 13장 패치 부분을 다 읽었는데 정말 좋군요. 감사합니다..^^

    Favicon of http://whiteship.me BlogIcon 기선 2010.06.30 06:54 PERM MOD/DEL

    rowCount()가 있었군요!
    GenericDao에 적용해볼 만한 내용이군요.
    감사합니다!!

Write a comment.




: 1 : ··· : 93 : 94 : 95 : 96 : 97 : 98 : 99 : 100 : 101 : ··· : 2638 :