ParkJongin Blog

ParkJongin Blog

Spring 에서 IBatis 설정 방법

들어가기전에..

ibatis를 사용하기 위해서는 ibatis 관련 라이브러리를 설치해줘야 한다. maven 프로젝트인 경우 pom.xml에서 maven repository를 이용해서 받아주면 된다. maven 프로젝트가 아닌경우 lib파일을 받아서 직접 넣어줘야 한다. 또한 mysql, oracle등 사용할 디비접속에 필요한 jdbc 라이브러리를 받아줘야 한다.

MVC SPRING

스프링 프래임워크는 MVC 패턴을 따르고 있다. ibatis를 이용해서 db에 접근하는 것은 MVC패턴에서 M과 C의 관계가 아닐까 생각한다. 이 말은.. MODEL을 만들고 CONTROLLER 혹은 SERVICE에서 실제 데이터 처리를 위한 로직을 만들게 되는데, 데이터 처리를 하기 위해 필요한 데이터는 MODEL에서 가져오게 된다. 이 MODEL은 일종의 데이터를 담는 그릇이고 중간에 DAO(Data Access Object)를 둬서 Database에 접근, 제어를 하게되고 결과값을 리턴받아 MODEL에 넣게 된다. 이 데이터 MODEL을 갖고 CONTROLLER나 SERVICE에서 처리를 한다. 아래 그림이 예를 들어 설명한 것이다.

spring 데이터 처리 과정

DAO를 통해 DB의 데이터를 이용하고 데이터 반환과 SERVICE나 CONTROLLER에서 MODEL에 저장된 반환값을 이용한다.

IBATIS 사용하기

JDBC API와 SQL의 조합으로는 엔터프라이즈 애플리캐이션의 거대한 데이터를 처리하는 데에 제약과 문제점이 있다. 좀 더 효과적인 방식으로 사용가능하도록 추상화하고 개선하기 위해 나온것이 IBATIS 와 같은것이 있다. 스프링에서는 DATASOURCE라는 하나의 독립된 빈으로 등록하도록 강력하게 권장하고 있다. DB CONNECTION에 관련된 정보를 담고 있는것 같다. 스프링에서 IBATIS를 사용하기 위해서는 root-context(app-context)와 sqlmap, sqlmapconfig, dao, model 등이 필요하다. 먼저 IBATIS를 이용하기 위한 환경설정을 위해 root-context를 수정해보자.

model 만들기

먼저 어떤 모델을 만들어서 데이터를 처리할 것인지 정하는 것이 필요하다. 나는 article이라는 모델을 만들고 처리해 보았다. model을 만들때 데이터를 담는 VO와 DAO가 필요하다. VO는 순수 모델에 관련된 데이터를 담기위한 클래스이다. DAO는 디비를 제어할 때 필요한 중간자 역할을 해주는 것이다.

public class Article {

	Integer	id;
	String	title;
	String	author;
	String	link;
	String	description;
	String	content;
	String	date;

	// getter, setter 메소드는 자동 generate기능을 이용했다.
}
Article 클래스(모델)

위 코드는 Article 모델 클래스를 정의한 것이다. 이 모델에 맞는 데이터를 데이터베이스에서 가져와야 하는데 컨트롤러에서나 서비스에서 DAO를 통해 접근을 할 것이다. DAO를 통해 접근해서 얻은 결과 데이터를 Article모델에 담아서 반환해 줄 것이다.

	@Repository()
	public class ArticleDAO extends SqlMapClientDaoSupport{
		
		public ArrayList<Article> selectArticleList(){
		 
			ArrayList<Article> articleList = null;
			articleList = (ArrayList<Article>)this.getSqlMapClientTemplate().queryForList("ArticleDAO.getArticleList");
			return articleList;
		}
	}
ArticleDAO 코드

위 코드는 ArticleDAO 코드이다. SqlMapClientDaoSupport를 상속받는 것이 중요하다. 나중에 밑에 ibatis 설정을 하고 나서 articleDAO에 DI를 해줘야 하기 때문이다. @Repository는 스프링 빈으로 등록하기 위해서 @Component대신 더 스코프를 좁힌 개념으로 DAO, DB와 관련된 일을 한다고 명시해주기 위해 Repository를 붙여줬다.

이제 모두 모델은 준비가 되었다. ibatis - rootcontext 설정을 해보자.

ibatis - rootcontext(appcontext).xml 수정

	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
	    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
	    <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8"/>
	    <property name="username" value="root"/>
	    <property name="password" value="root"/>
	</bean>
	<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
	    <property name="configLocation" value="/WEB-INF/ibatis/config/sqlMapConfig.xml"/>
	    <property name="dataSource" ref="dataSource"/>
	</bean>
	<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
	    <property name="sqlMapClient" ref="sqlMapClient"/>
	</bean>		
	
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  		<property name="dataSource" ref="dataSource"></property>
 	</bean>
 
ibatis application context에서 설정
  • 먼저 제일 중요한 dataSource를 빈으로 등록해 준다. driverClassName에는 사용할 db의 드라이버 클래스 이름을 적어준다. 그 외 DB의 주소, 아이디, 패스워드 등을 설정해준다.
  • 다음 sqlMapClient에 sqlmap(실제 sql을 작성하는 xml문서) 환경설정 파일이 있는 경로 설정과 dataSource를 DI 해준다. configLocation에서 경로는 classPath를 등록해줘야 하는데 이것은 맨 아래에서 설명하겠다.
  • sqlMapClient는 iBatis의 핵심 API의 인터페이스가 담겨져 있다. 이를 이용하려면 sqlMapClient가 구현된 오브젝트가 실제 있어야 하는데 이 것을 sqlMapClientFactoryBean에서 해준다. sqlMapClientFactoryBean을 이용해서 sqlMapClient를 싱글톤 빈으로 등록한다.
  • sqlMapClientTemplate은 sqlMapClient를 DI받아서 ibatis의 기능을 이용한다. sqlMapClient를 직접 이용하는 대신 sqlMapClientTemplate을 이용하는 것이 좋은데, 그 이유는 sqlMapClientTemplate에서 기본적으로 예외변환, 스프링 트랜잭션, 동기화 등이 지원되기 때문이다.

이렇게 root context 설정이 끝나고 나면 sqlmapconfig와 sqlmap이 필요하다.

ibatis - sqlmapconfig, sqlmap 설정

이제 실제적으로 우리가 쿼리를 작성해야 하는 부분이다. sqlmapconfig는 sqlmap설정과 실제 sqlmap파일이 있는 경로를 적어주게 된다.

<?xml version="1.0" encoding="UTF-8"?>
 
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" 
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">
 
<sqlMapConfig>
 	<settings enhancementEnabled="true" maxTransactions="5"
        maxRequests="32" maxSessions="10" useStatementNamespaces="true"/>
    <sqlMap resource="./app/sqlMap.xml"/>
</sqlMapConfig>
 
sqlmapconfig 설정
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">
 
<sqlMap namespace="ArticleDAO">
 
    <typeAlias alias="Article" type="com.pji.article.Article" />
 
    <select id="getArticleList" resultClass="com.pji.article.Article">
        SELECT * 
        FROM article
        ORDER BY date ASC;
    </select>
     
</sqlMap>
sqlmap 설정
  • 모두 설정이 되어있으면 이제 사용할때 주의해야 할 부분이 있다. DAO에서 queryForList(“ArticleDAO.getArticleList”) 메소드를 이용해서 쿼리를 요청하고 싶을때 naspace.selectid로 파라메터를 넘겨줘야한다. 또한 resultClass와 parametaClass를 작성해서 만약 쿼리내에서 변수를 사용하고 싶을때는 parametaClass를 이용해서 받아야 한다. resultClass는 결과 반환을 어떤 형식으로 할지 정한다. 우리는 아까 정의한 article모델로 데이터를 반환한다.

이제 다했다. Controller 혹은 Service에서 @Autowired나 직접 bean으로 등록한 후 ArticleDAO를 DI해주고 ArticleDAO.selectArticleList()로 호출하면 된다. 아래 코드는 사용 예시이다.

@Service
public class ArticleService {
	
	@Autowired
	ArticleDAO articleDAO;

	public void articleService(){
		
		Article article = null;	
		article = articleDAO.getArticleList().get(id);
	}
}
Service에서 articleDAO 사용 예시

configLocation에서 classpath 적용하기.

먼저 ibatis map혹은 config.xml 파일을 넣을 폴더를 생성한다. 그리고 나서 아래 그림과 같이 한다.

classpath설정 1

properties를 선택해주고,

classpath설정 1

java build path -> source -> add folder… 을 눌러서 방금 생성한 폴더를 선택한 후 ok를 누르면 classpath가 된다.