Whiteship's Note


12.2.3. The HibernateTemplate

Spring/Chapter 12 : 2007.04.23 19:04


이 전 글에서 Spring Container에 등록한 SessionFactoryBean을 사용하여 HibernateTemplate을 생성할 수 있습니다.

따라서 HibernateTemplate을 사용할 DAO 클래스에 setter injection을 사용하기 위해 보통 다음과 같이 설정합니다.
<beans>

  <bean id="myProductDao" class="product.ProductDaoImpl">
    <property name="sessionFactory" ref="mySessionFactory"/>
  </bean>

</beans>

어플리케이션에서 사용할 때는 다음과 같이 콜백을 사용하여 session에 접근합니다.
public class ProductDaoImpl implements ProductDao {

    private HibernateTemplate hibernateTemplate;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.hibernateTemplate = new HibernateTemplate(sessionFactory);
    }

    public Collection loadProductsByCategory(final String category) throws DataAccessException {
        return this.hibernateTemplate.execute(new HibernateCallback() {
            public Object doInHibernate(Session session) {
                Criteria criteria = session.createCriteria(Product.class);
                criteria.add(Expression.eq("category", category));
                criteria.setMaxResults(6);
                return criteria.list();
            }
        };
    }
}

HibernateTemplate이 Session의 생성이나 소멸, 트랜잭션을 책임집니다. 따라서 콜백을 사용하여 단순하게 할 일(find, select, insert 등) 만 코딩해 주면됩니다.

HibernateTemplate의 execute() 메소드 소스 코드를 보시면 어떤 일을 해주는지 짐작할 수 있습니다.

한 단계 더 나가서 HibernateTemplate을 DAO 클래스 내부에 직접 멤버 변수로 선언하지 않고 DAO 클래스가 HibernateDaoSupport 클래스를 상속 받도록 하면 getHibernateTemplate() 메소드르 사용하여 원할 때 마다 HibernateTemplate을 사용할 수 있습니다.

public class ProductDaoImpl extends HibernateDaoSupport implements ProductDao {

    public Collection loadProductsByCategory(String category) throws DataAccessException {
        return this.getHibernateTemplate().find(
            "from test.Product product where product.category=?", category);
    }
}

이런식으로 사용하면 DAO마다 setter injection 해야하는 수고를 덜 수 있겠습니다.
top


HibernateTemplate

Hibernate/study : 2007.01.26 14:20


8.4. 기능구현 여기서 던졌던 의문에 실마리를 찾은 듯...

HibernateTemplate은 Spring에 있는 API로 Hibernate를 사용해서 데이타에 접근하는 것을 좀 더 편리하게 해주고 Checked Exception인 HibernateException을 Unchecked인 DataAccessException으로 바꿔 준다고 합니다.
    @SuppressWarnings("unchecked")
    public List<KMember> getMembers(final String name) {
        return getHibernateTemplate().executeFind(new HibernateCallback(){
            public Object doInHibernate(Session s) throws HibernateException, SQLException {
                Query q = s.createQuery("from k_Member m where m.name like :name order by m.name asc")
                           .setParameter("name", "%" + name +"%");
                return q.list();
            }
        });
    }

    @SuppressWarnings("unchecked")
    public List<KMember> getMembers(final String name) {
        Session s = getSession();
        Query q = s.createQuery("from k_Member m where m.name like :name order by m.name asc")
                      .setParameter("name", "%" + name +"%");
        return q.list();
    }

위나 아래나 같은 일을 하는 것 처럼 보이지만.. 아래는 Exception에 대한 고려도 없고 Session을 열고 닫아 주는 일을 수동으로 해줘야 하는 군요. HibernateTemplate API를 대강 읽어봤는데 역시 영어 실력이 OTL...

'Hibernate > study' 카테고리의 다른 글

책을 샀습니다.  (0) 2007.02.04
DisplayTag1.1 예제 보기  (0) 2007.01.30
DisplayTag 써보기  (2) 2007.01.30
Criteria에서 Join하기  (0) 2007.01.29
숙제 2  (0) 2007.01.26
HibernateTemplate  (0) 2007.01.26
HQL과 @Entity에 있는 name 속성의 관계  (0) 2007.01.24
Fluent Interface  (2) 2007.01.24
DbUnit  (2) 2007.01.23
Hibernate에서 쿼리 날리는 방법  (0) 2007.01.19
객체들의 상태 변화(in Hibernate)  (2) 2007.01.19
top


8.4. 기능 구현



검색 기능을 구현해 봅니다.

1. Dao 테스트에 다음과 같이 "s"로 검색 했을 때 두명이 나올 것이라고 예상합니다. 이런 예상의 근거는 DBUnit을 사용해서 XML에 있는 Data를 넣어서 사용할 것이기 때문에 XML에 있는 데이타를 근거로 삼았습니다.

    public void testGetMembers() throws Exception{
        insertFlatXmlDataSet("test/src/keesun/kSampleData.xml");
        assertEquals(2, kMemberDao.getMembers("s").size());
    }

2. 그리고 이클립스를 보고 있으면 컴파일 에러가 발생하는 것을 확인할 수 있습니다. 당연하죠. getMembers(String)이라는 인터페이스가 MemberDao 에 없기 때문입니다. 만들어 주면 되죠.

public interface KMemberDao extends GenericDao<KMember, Integer>{

    public List<KMember> getMembers(String string);

}

3. 인터페이스에 추가해 줬더니 이젠 이걸 구현한 쪽에서 에러가 발생합니다. 이것을 구현해 주고 테스트의 결과 녹색불이 들어오면 구현이 끝납니다.

    @SuppressWarnings("unchecked")
    public List<KMember> getMembers(final String name) {
        return getHibernateTemplate().executeFind(new HibernateCallback(){
            public Object doInHibernate(Session s) throws HibernateException, SQLException {
                Query q = s.createQuery("from k_Member m where m.name like :name order by m.name asc")
                           .setParameter("name", "%" + name +"%");
                return q.list();
            }
        });
    }

위 코드에서 getHibernateTemplate()으로 HibernateTemplate객체를 받아오고 이 객체의 executeFind() 메소드를 사용해서 자기가 할일을 남(HibernateCallback)을 시켜서 합니다.

구현을 아래 처럼 간단하게 할 수도 있는데요.
        Session s = getSession();
        Query q = s.createQuery("from k_Member m where m.name like :name order by m.name asc")
                      .setParameter("name", "%" + name +"%");
        return q.list();

callback을 사용하는 이유가 있겠죠? 궁금하네요~ *_*

'Hibernate > 주소록 만들기' 카테고리의 다른 글

9. Tag만들기  (0) 2007.02.12
8.4. 기능 구현  (0) 2007.01.25
8.3. Criteria 공부하기  (0) 2007.01.25
8.2. HQL 공부하기  (0) 2007.01.24
8.2.4. HQL 공부하기 - inner join  (0) 2007.01.24
8.2.3. HQL 공부하기 - order by절  (0) 2007.01.24
8.2.2. HQL 공부하기 - where절  (0) 2007.01.24
8.2.1. HQL 공부하기 - select절  (0) 2007.01.24
8.1. DbUnit 사용하기  (0) 2007.01.24
8. DAO 기능 구현하기  (4) 2007.01.23
7.3. 새로운 타입으로 맵핑하기.  (0) 2007.01.22
top