2015년 8월 3일 월요일

[mybatis] SqlSession / SqlSessionTemplate


[mybatis] 
SqlSession / SqlSessionTemplate


원본 출처 : http://mybatis.github.io/spring/ko/sqlsession.html
PS. mybatis는 오픈소스 프로젝트임으로 사전 동의없이 본 게시자가 documentaion을 인용하였으나 저작권 분쟁 발생시 즉각 삭제하겠습니다.
또한 mybatis는 오픈소스 프로젝트임으로 이 글을 상업적인 용도로 무단 복제,배포로 인한
책임은 모두 사용자에게 있습니다.

---------------------------------------------------------------------------------



Using an SqlSession


마이바티스에서는 SqlSession를 생성하기 위해 SqlSessionFactory를 사용한다. 세션을 한번 생성하면 매핑구문을 실행하거나 커밋 또는 롤백을 하기 위해 세션을 사용할수 있다. 마지막으로 더 이상 필요하지 않은 상태가 되면 세션을 닫는다. 마이바티스 스프링 연동모듈을 사용하면 SqlSessionFactory를 직접 사용할 필요가 없다. 왜냐하면 사용할 빈이SqlSession에 주입될수 있기 때문이다. 이때 SqlSession은 스프링 트랜잭션 설정에 따라 세션을 자동으로 커밋, 롤백하고 닫는 쓰레드에 안전하다.

SqlSessionTemplate

SqlSessionTemplate은 마이바티스 스프링 연동모듈의 핵심이다. SqlSessionTemplateSqlSession을 구현하고 코드에서 SqlSession를 대체하는 역할을 한다.SqlSessionTemplate 은 쓰레드에 안전하고 여러개의 DAO나 매퍼에서 공유할수 있다.
getMapper()에 의해 리턴된 매퍼가 가진 메서드를 포함해서 SQL을 처리하는 마이바티스 메서드를 호출할때 SqlSessionTemplate은 SqlSession이 현재의 스프링 트랜잭션에서 사용될수 있도록 보장한다. 추가적으로 SqlSessionTemplate은 필요한 시점에 세션을 닫고, 커밋하거나 롤백하는 것을 포함한 세션의 생명주기를 관리한다. 또한 마이바티스 예외를 스프링의 DataAccessException로 변환하는 작업또한 처리한다.
SqlSessionTemplate은 마이바티스의 디폴트 구현체인 DefaultSqlSession 대신 항상 사용된다. 왜냐하면 템플릿은 스프링 트랜잭션의 일부처럼 사용될 수 있고 여러개 주입된 매퍼 클래스에 의해 사용되도록 쓰레드에 안전하다. 동일한 애플리케이션에서 두개의 클래스간의 전환은 데이터 무결성 이슈를 야기할수 있다.
SqlSessionTemplate은 생성자 인자로 SqlSessionFactory를 사용해서 생성될 수 있다.
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
  <constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
이 빈은 DAO빈에 직접 주입될 수 있다. 다음처럼 빈 설정에서 SqlSession 프로퍼티를 설정하면 된다.
public class UserDaoImpl implements UserDao {

  private SqlSession sqlSession;

  public void setSqlSession(SqlSession sqlSession) {
    this.sqlSession = sqlSession;
  }

  public User getUser(String userId) {
    return (User) sqlSession.selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
  }
}
그리고 다음처럼 SqlSessionTemplate 를 주입하자.
<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl">
  <property name="sqlSession" ref="sqlSession" />
</bean>
SqlSessionTemplate은 인자로 ExecutorType를 가지는 생성자를 가지고 있다. 이 인자는 예를들면 스프링 설정 XML을 다음처럼 설정해서 배치형태의 SqlSession를 만들수도 있다.
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
  <constructor-arg index="0" ref="sqlSessionFactory" />
  <constructor-arg index="1" value="BATCH" />
</bean>
DAO의 코드를 다음처럼 작성했다면 모든 구문은 배치형태로 실행이 될 것이다.
public void insertUsers(User[] users) {
   for (User user : users) {
     sqlSession.insert("org.mybatis.spring.sample.mapper.UserMapper.insertUser", user);
   }
 }
이러한 설정형태는 SqlSessionFactory의 디폴트 형태가 아닌 다른형태로 메서드를 실행해야 할때만 사용할 필요가 있다.
이러한 형태에 대해 굳이 경로를 하자면 메서드를 호출할때 ExecutorType이 다르면 이미 시작된 트랜잭션을 사용하지 못할것이다. 다른 실행자(executor) 타입을 사용할때는SqlSessionTemplate의 메서드를 구분된 트랜잭션(PROPAGATION_REQUIRES_NEW를 사용하는)이나 트랜잭션 외부에서 호출하는지 확실히해야 한다.

SqlSessionDaoSupport

SqlSessionDaoSupport는 SqlSession을 제공하는 추상클래스이다. getSqlSession()메서드를 호출해서 다음처럼 SQL을 처리하는 마이바티스 메서드를 호출하기 위해 사용할SqlSessionTemplate을 얻을 수 있다.
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
  public User getUser(String userId) {
    return (User) getSqlSession().selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
  }
}
대개 MapperFactoryBean은 추가적인 코드가 필요없기 때문에 이 클래스를 선호한다. 하지만 DAO에서 마이바티스가 필요하지 않고 구현된 클래스가 필요하지 않을때만 유용하다.
SqlSessionDaoSupport는 sqlSessionFactory 와 sqlSessionTemplate 프로퍼티를 셋팅할 필요가 있다. 두개의 프로퍼티를 모두 셋팅하면 sqlSessionFactory는 무시된다.
SqlSessionDaoSupport의 하위클래스인 UserDaoImpl가 있다고 하면 스프링에서는 다음처럼 설정될 수 있다.
<bean id="userMapper" class="org.mybatis.spring.sample.mapper.UserDaoImpl">
  <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>


-----------------------------------------------------------------------------------------------------

Publish to English-speaking users.

[mybatis] 
SqlSession / SqlSessionTemplate
-----------------------------------------------------------------------------------------------------

Using an SqlSession

In MyBatis you use the SqlSessionFactory to create an SqlSession. Once you have a session, you use it to execute your mapped statements, commit or rollback connections and finally, when it is no longer needed, you close the session. With MyBatis-Spring you don't need to useSqlSessionFactory directly because your beans can be injected with a thread safe SqlSession that automatically commits, rollbacks and closes the session based on Spring's transaction configuration.

SqlSessionTemplate

SqlSessionTemplate is the heart of MyBatis-Spring. It implements SqlSession and is meant to be a drop-in replacement for any existing use ofSqlSession in your code. SqlSessionTemplate is thread safe and can be shared by multiple DAOs or mappers.
When calling SQL methods, including any method from Mappers returned by getMapper()SqlSessionTemplate will ensure that the SqlSessionused is the one associated with the current Spring transaction. In addition, it manages the session life-cycle, including closing, committing or rolling back the session as necessary. It will also translate MyBatis exceptions into Spring DataAccessExceptions.
SqlSessionTemplate should always be used instead of default MyBatis implementation DefaultSqlSession because the template can participate in Spring transactions and is thread safe for use by multiple injected mapper classes. Switching between the two classes in the same application can cause data integrity issues.
SqlSessionTemplate can be constructed using an SqlSessionFactory as a constructor argument.
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
  <constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
This bean can now be injected directly in your DAO beans. You need a SqlSession property in your bean like the following
public class UserDaoImpl implements UserDao {

  private SqlSession sqlSession;

  public void setSqlSession(SqlSession sqlSession) {
    this.sqlSession = sqlSession;
  }

  public User getUser(String userId) {
    return (User) sqlSession.selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
  }
}
And inject the SqlSessionTemplate as follows
<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl">
  <property name="sqlSession" ref="sqlSession" />
</bean>
SqlSessionTemplate has also a constructor that takes an ExecutorType as an argument. This allows you to construct, for example, a batchSqlSession by using the following in Spring's configuration xml:
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
  <constructor-arg index="0" ref="sqlSessionFactory" />
  <constructor-arg index="1" value="BATCH" />
</bean>
Now all your statements will be batched so the following could be coded in a DAO
public void insertUsers(User[] users) {
   for (User user : users) {
     sqlSession.insert("org.mybatis.spring.sample.mapper.UserMapper.insertUser", user);
   }
 }
Note that this configuration style only needs to be used if the desired execution method differs from the default set for the SqlSessionFactory.
The caveat to this form is that there cannot be an existing transaction running with a different ExecutorType when this method is called. Either ensure that calls to SqlSessionTemplates with different executor types run in a separate transaction (e.g. with PROPAGATION_REQUIRES_NEW) or completely outside of a transaction.

SqlSessionDaoSupport

SqlSessionDaoSupport is an abstract support class that provides you with a SqlSession. Calling getSqlSession() you will get aSqlSessionTemplate which can then be used to execute SQL methods, like the following:
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
  public User getUser(String userId) {
    return (User) getSqlSession().selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
  }
}
Usually MapperFactoryBean is preferred to this class, since it requires no extra code. But, this class is useful if you need to do other non-MyBatis work in your DAO and concrete classes are required.
SqlSessionDaoSupport requires either an sqlSessionFactory or an sqlSessionTemplate property to be set. If both properties are set, thesqlSessionFactory is ignored.
Assuming a class UserDaoImpl that subclasses SqlSessionDaoSupport, it can be configured in Spring like the following:
<bean id="userMapper" class="org.mybatis.spring.sample.mapper.UserDaoImpl">
  <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>




PS-참고 소스(게시자가 직접 작성한 코드)

SqlSessionTemplate은 마이바티스 스프링 연동모듈의 핵심이다.
여러개의 dao에서 공유할수 있기 때문에 메모리 관리에 있어서 최적화된 테크닉이며,
SqlSessionTemplate은 생성자 인자로 SqlSessionFactory를 사용해서 생성될 수 있다.

그렇기 때문에 PropertyPlaceholderConfigurer 클래스로 jdbc.poperties 데이터를 읽어들인후
BasicDataSource클래스로 dataSource설정후
sqlSessionFactoryBean 으로 sqlSession을 생선한다음
SqlSessionTemplate으로 재가공 해냅니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?xml version="1.0" encoding="UTF-8"?>
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd
                        ">
        <bean id="propertyConfigurer" 
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="location" value="config/jdbc.properties"></property>
        </bean>
        
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
            <property name="driverClassName" value="${jdbc.driverClassName}"></property>
            <property name="url" value="${jdbc.url}"></property>
            <property name="username" value="${jdbc.username}"></property>
            <property name="password" value="${jdbc.password}"></property>
            <property name="initialSize" value="${jdbc.initialSize}"></property>        
            <property name="maxActive" value="${jdbc.maxActive}"></property>
        </bean>
        
        <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <property name="configLocation" value="config/mybatis-config13.xml"></property>
        </bean>
        
        <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
            <constructor-arg ref="sqlSessionFactoryBean"></constructor-arg>
        </bean>
        
        <context:component-scan base-package="mybatis.service.user.impl"/>
        
</beans>


댓글 없음:

댓글 쓰기