본문 바로가기
  • 실행력이 모든걸 결정한다
Spring Series/Spring Framework

[Spring] Hibernate

by 김코더 김주역 2022. 7. 6.
반응형

1. Hibernate란?

- Hibernate는 JPA를 구현한 ORM 라이브러리들 중 하나다.

- Spring과 Hibernate는 비슷한 시기에 POJO 프로그래밍을 바탕으로 자바 엔터프라이즈 개발의 혁신을 가져온 대표적인 기술이다.

 

 

 

 

2. SessionFactory

1) SessionFactory란?

- Hibernate의 핵심 엔진 역할을 하는 인터페이스다.

- SessionFactory는 bean으로 등록된 DataSource를 이용하여 spring이 제공하는 트랜잭션 매니저와 연동할 수 있도록 설정되어 있다.

- Spring에서는 SessionFactory bean을 생성해주는 LocalSessionFactoryBean과 AnnotationSessionFactoryBean을 제공한다.

 

 

 

2) SessionFactoryBean

(1) LocalSessionFactoryBean

- 다음 예시와 같이 매핑파일 목록과 프로퍼티를 담은 hibernate.cfg.xml 설정 파일을 이용한다.

<hibernate.cfg.xml>

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
    <session-factory>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="connection.pool_size">1</property>
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">create</property>
        <mapping resource=".../Member.hbm.xml" />
        <!-- mapping class="com.example.demo.hibernate.Member" / -->
    </session-factory>
</hibernate-configuration>

※ mapping 파일 경로의 기준은 classpath이다.

 

- <mapping>의 resource 속성을 사용하면 클래스와 테이블 사이의 매핑 정보를 담고 있는 xml 설정 파일들을 등록할 수도 있다. 예를 들어, 매핑 파일에는 다음과 같은 내용이 들어갈 수 있다.

<Member.hbm.xml>

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.example.demo.hibernate">
    <class name="Member" table="MEMBER">
    	<id name="id" column="ID" />
        <property name="name" column="NAME" length="20" />
        <property name="point" column="POINT" not-null="false" type="double" />
</hibernate-mapping>

 

- 기본적인 SessionFactory bean은 DataSource bean과 hibernate.cfg.xml 파일을 이용하여 생성할 수 있는데,

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configLocation" value=".../hibernate.cfg.xml" />
</bean>

만약 hibernate.cfg.xml 파일을 생략하고 싶다면 아래 두 프로퍼티들을 이용하면 된다.

 

<1> mappingLocations

- hibernate.cfg.xml에 있는 <mapping> 태그를 이용하는 대신 mappingLocations라는 이름의 프로퍼티를 사용하는 방법으로, 아래와 같이 <list><value> 형식으로 여러 매핑 파일들을 지정할 수 있다.

<property name="mappingLocations">
    <list>
        <value>[매핑 파일1 경로]</value>
        <value>[매핑 파일2 경로]</value>
    </list>
</property>

<2> hibernateProperties

- hibernate.cfg.xml 안에 넣어주는 DB 설정 값을 hibernateProperties라는 이름의 프로퍼티를 통해서 지정하는 방법이다. Properties 타입이므로 <props><prop> 형식을 이용하여 프로퍼티를 추가하면 된다.

<property name="hibernateProperties">
    <props>
        <prop key="dialect">org.hibernate.dialect.MySQLDialect</prop>
        <prop key="connection.pool_size">1</prop>
        <prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
        <prop key="show_sql">true</prop>
        <prop key="hbm2ddl.auto">create</prop>
    </props>
</property>

- LocalSessionFactoryBean에는 캐시 프로바이더, 이벤트 리스너와 같은 프로퍼티들도 제공된다.

 

 

(2) AnnotationSessionFactoryBean

- xml 매핑 파일 대신 어노테이션을 이용하여 SessionFactory를 생성하는 방법이다.

- 기본적인 property들의 설정 방법은 LocalSessionFactoryBean과 동일하며, 추가로 annotatedClasses, packageToScan 프로퍼티가 제공된다.

 

<1> annotatedClasses

- @Entity와 같은 매핑 어노테이션이 부여된 클래스의 목록을 지정한다.

<property name="annotatedClasses">
    <list>
        <value>[매핑 클래스 경로]</value>
        <value>[매핑 클래스 경로]</value>
    </list>
</property>

<2> packagesToScan

- 해당 패키지 내에 있는 @Entity 클래스들을 자동으로 찾아서 등록해준다.

<property name="packageToScan" value="com.example.demo.hibernate" />

 

 

 

3) TransactionManager

- SessionFactory를 이용하여 DAO를 만들 때 트랜잭션을 적용하려면 트랜잭션 매니저가 필요하다. Hibernate에 적용할 수 있는 트랜잭션 매니저로는 아래 두 가지가 있다.

 

(1) HibernateTransactionManager

- 단일 DB를 사용하고 JTA를 이용할 필요가 없을 때 사용된다.

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

- JDBC DAO와 동일한 DataSource를 사용한다면 같은 트랜잭션을 공유할 수도 있다.

 

(2) JtaTransactionManager

- 서버가 제공하는 글로벌 트랜잭션 기능을 이용할 때 사용된다.

- JtaTransactionManager는 DataSource나 SessionFactory 등의 bean을 참조하지 않고, JNDI를 통하여 서버에 등록된 TransactionManager와 UserTransaction을 가져와서 JTA로 트랜잭션을 관리해준다. 

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>

 TransactionManager의 디폴트 JNDI 이름은 java:comp/TransactionManager, java:appserver/TransactionManager, java:pm/TransactionManager, java:/TransactionManager으로 총 4개가 있고, UserTransaction의 디폴트 JNDI 이름은 java:comp/UserTransaction이다. 디폴트 이름을 쓰지 않는다면 transactionManagerName과 userTransactionName 프로퍼티로 이름을 지정해준다.

- WAS의 지원 없이도 애플리케이션 안에 JTA 기능을 내장하는 독립형 JTA 방식도 존재한다. 이 방식에서는 XA를 지원하는 XA DataSource를 사용해야 하고, TransactionManager bean과 UserTransaction bean을 직접 만들어야 한다.

※ 독립형 JTA 트랜잭션 매니저로는 대표적으로 JOTM과 Atomikos가 있다. Atomikos를 이용하는 예시는 https://m.blog.naver.com/xcv1524/220508445415를 참고하자.

 

 

 

3. Session

- Hibernate의 핵심 API

- SessionFactory로부터 생성되며 일반적으로 트랜잭션과 동일한 스코프를 갖는다. Hibernate DAO는 spring이 관리하는 트랜잭션과 동기화된 Session을 가져와서 사용한다.

- Session을 생성하는 방법으로는 HibernateTemplate를 사용하는 방법과 SessionFactory의 getCurrentSession() 메소드를 사용하는 방법이 있다.

 

1) HibernateTemplate

- SessionFactory를 생성자로 넣어 생성한다.

- HibernateDaoSupport 클래스를 상속하면 getHibernateTemplate() 메소드를 통해 템플릿 오브젝트를 가져올 수 있다.

- Session의 대부분의 기능을 메소드를 통해 이용할 수 있게 해준다.

- 자동커밋 방식으로 동작한다.

- Hibernate가 제공하는 API를 직접 사용하지 못하고 템플릿 구조에 종속된다는 단점이 있다.

사용 예시

public void addMember(Member member) {
    hibernateTemplate.save(member);
}

 

 

2) SessionFactory의 getCurrentSession() 메소드

- 현재 진행 중인 트랜잭션에 연결되어 있는 hibernate Session을 반환해준다.

- Spring API가 아닌 hibernate의 API를 사용하는 방법이다.

- 트랜잭션이 시작된 후에만 사용할 수 있다는 단점이 있다.

사용 예시

public void addMember(Member member) {
    sessionFactory.getCurrentSession().save(member);
}

 

 

 

 

● 참고 자료 : 토비의 스프링 3.1 Vol.2 

반응형

댓글