버전이 올라가면서 이름도 IBatis에서 MyBatis로 바뀌고 내부 구현도 거의 새로 만든 수준으로 많은 부분이 바꼈다는 이야기를 들었습니다.
그래서 몇 달 전부터 함 써봐야지 했는데 이래저래 열심히 놀다 보니 이제서야 써보게 됐네요. ㅎㅎ
대충(?) 사용해본 제 느낌으로는 내부 구현은 어찌됐든 사용자 입장에서 보면 엄청나게 까지는 달라진것 같지는 않습니다.
하지만 눈에 띄는 몇가지 변화는 보이네요.
일단 그런건 나중에 차차 설명하기로 하고 실제로 어떻게 구성했는지 먼저 알려드리겠습니다.
대략 제가 테스트한 프로젝트 구조입니다.(욕하라고 붙여놓은게 아니라 이해하기 편하라고 붙여놨어요 -_- )
[web.xml]
....(생략)....
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
.....(생략).....
[root-context.xml]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!-- Root Context: defines shared resources visible to all other web components -->
<import resource="mybatis/mybatis-context.xml"/>
</beans>
여기까진 그닥 중요한 내용은 아닙니다. 꼭 이렇게 할 필요도 없구요.
자..여기서부터 mybatis관련된 설정입니다.
mybatis-context.xml 에는 datasource 관련된 내용과 sqlSessionFactory, sqlSessionTemplate 에 관한 설정을 합니다.
[mybatis-context.xml]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<!-- JNDI 로 datasource를 받아오는 경우 -->
<!--
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${jdbc.datasource}"/>
<property name="resourceRef" value="true" />
</bean>
-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="/WEB-INF/spring/mybatis/mybatis-config.xml"/>
</bean>
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sqlSessionFactory"/>
</bean>
</beans>
mybatis-config.xml 에는 실제 쿼리가 담겨있는 xml파일의 위치와 typeAlias 로 설정된 model 클래스 정보가 들어있습니다.
예전에 ibatis에서는 typeAlias가 실제 쿼리가 들어가는 파일에 넣을수 있었는데 제가 잘 몰라서 안되는건지 아니면 mybatis로 올라가면서 바뀐건지 잘 모르겠습니다.
[mybatis-config.xml]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "HTTP://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="cacheEnabled" value="false" />
<setting name="useGeneratedKeys" value="true" />
<setting name="defaultExecutorType" value="REUSE" />
</settings>
<typeAliases>
<typeAlias type="kr.co.nethru.vo.UserVo" alias="UserVo"/>
</typeAliases>
<mappers>
<mapper resource="kr/co/nethru/dao/sql/user-manager.xml" />
</mappers>
</configuration>
db 접속 정보는 알아서 수정하시구요 ㅋㅋㅋ
[jdbc.properties]
jdbc.datasource=jdbc/DataSource
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?autoReconnect=true
jdbc.username=root
jdbc.password=password1234
여기까지 설정 관련된 내용은 끝입니다.
사용자는 DAO에서 SqlSessionDaoSupport 을 상속받은 뒤 getSqlSession() 로 sqlSession 받아서 사용하시면 됩니다.
IBatis에서 SqlMapClientDaoSupport 클래스와 같은 역할입니다.
[UserManagerDaoImpl.java]
package kr.co.nethru.dao.impl;
import kr.co.nethru.dao.IUserManagerDao;
import kr.co.nethru.vo.UserVo;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.stereotype.Repository;
/**
* @author 박헌웅
* 사용자 정보에 대한 DB작업을 담당한다.
*/
@Repository
public class UserManagerDaoImpl extends SqlSessionDaoSupport implements IUserManagerDao {
...(생략)...
//사용자 정보를 DB에 삽입한다.
@Override
public boolean insertUser(UserVo userVo) {
int insertResult = (int)getSqlSession().insert("user.insertUser", userVo);
boolean isInsertedData = (insertResult > 0) ? true : false;
return isInsertedData;
}
...(생략)...
}
참고로 아래는 SqlSessionDaoSupport 의 코드입니다.
내용을 보면 mybatis-context.xml 에서 설정한 sqlSessionTemplate 가 어떻게 주입되는지 확인 할 수 있습니다.
[참고하세요]
public abstract class SqlSessionDaoSupport extends DaoSupport {
.....(생략).....
@Autowired(required = false)
public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
this.sqlSession = sqlSessionTemplate;
this.externalSqlSession = true;
}
.....(생략).....
}
아.. 쿼리가 빠졌네요 -_-;;;
쿼리에서 파라메터 매핑하는 방법이 좀 달라졌다는거 보이시죠?
예전에는 #param1# 또는 $param1$ 이렇식으로 하던게 #{param1}, ${param1} 이런식으로 바꼈습니다.
그리고 <mapper>에 namaspace 보이시죠?? 요게 필수가 됐습니다. 그래서 반드시 DAO에서 쿼리를 호출할때 "user."을 붙이셔야합니다. 그 외에도 몇가지 바뀌거나 추가된 내용이 있는데 그건 나중에 차차 포스팅 하도록 하겠습니다.
[user-manager.xml]
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="user">
<!-- 사용자 정보를 저장 -->
<insert id="insertUser" parameterType="UserVo">
insert /* [user-manager.xml][insertUser] */
into ow_user
(user_id, user_pw, user_name, auth_level, join_date, login_date)
values (#{userId}, password(#{userPw}), #{userName}, 1, now(), now())
</insert>
<!-- 인자로 받은 아뒤와 비번에 해당하는 사용자 정보를 가져온다 -->
<select id="selectUser" parameterType="UserVo" resultType="UserVo">
select user_id userId, user_pw userPw, user_name userName, auth_level authLevel
from ow_user
where user_id = #{userId}
and user_pw = password(#{userPw})
limit 1
</select>
<!-- 인자로 받은 사용자 아이디에 해당하는 데이터를 삭제한다 -->
<delete id="deleteUser" parameterType="string">
delete /* [user-manager.xml][deleteUser] */
from ow_user
where user_id = #{userId}
</delete>
</mapper>
대충 다 된것 같습니다.
혹시 제 포스팅 한 내용 중 잘못된 내용이 있거나 더 좋은 내용이 있으면 혼자만 알고 있지말고 저도 귀뜸을..ㅜㅜ
아... mybatis-spring framework3 를 위해 필요한 jar가 몇개 있는데요.
mybatis-spring-1.0.0-RC3.jar
mybatis-3.0.3.jar
spring-jdbc-3.0.5.RELEASE.jar
일단 기본적으로 요딴게 필요합니다. 필요한 jar가 더 있을지도 모르겠습니다. -_- (귀차니즘 ㅎㅎ)
참조 :
출처 - http://kaludin.egloos.com/2717395
===================================================================================
오랜만에 Spring을 만져보게 되었는데 3.x로 오면서 예전에 바래왔던것들이 상당부분 적용 된것 같네요. 특히 완벽한 어노테이션 환경이 도입된거 같아 좋습니다. 어노테이션으로 할 수 있는 것들이 엄청나게 많아졌네요. component scan 한방에 모든게 해결되는 느낌입니다.
예전에는 iBatis라는 ORM 라이브러리를 사용했었는데요. 당시에도 MyBatis라는것이 있었던걸로 알고 있었는데 지금보니 iBatis팀이 완전히 MyBatis로 이름을 바꿔 옮겨간것이군요. iBatis의 운명은 사실상 끝나는것이 아닐까 하는 생각이 드는군요. 아무튼 이전개발자들이 똑같은 호환성으로 계속해서 업그레이드 해나간다는 MyBatis를 스프링에 연동해 보기로 하겠습니다. 근데 정말 희안하게도 스프링에서 사실상 myBatis와의 연동을 지원하지 않는군요. 언제쯤 정식 지원할지 모르겠지만 아무튼 연동하기 위한 라이브러리 또한 구할 수 있습니다.
Spring 프레임워크 다운로드 :
http://www.springsource.org/spring-framework
MyBatis 라이브러리 다운로드 :
http://code.google.com/p/mybatis/downloads/list?can=3&q=%22mybatis-3%22+-migrations
MyBatis Spring 연동 라이브러리 다운로드 :
http://code.google.com/p/mybatis/downloads/list?can=3&q=Product%3DSpring
Spring 프레임워크를 이용한 프로젝트를 세팅하는 방법은 생략하도록 하겠습니다. 예전에 썼던글이지만 [이곳]을 참고하시는것도 괜찮을것 같습니다. 프로젝트에 다운받은 다음의 라이브러리를 추가합니다. (현재 글쓴 시점의 버전으로 적어두겠습니다)
mybatis-3.0.6.jar
mybatis-spring-1.0.2.jar
context 설정에 다음의 bean들을 추가해 줍니다.<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations"
value="classpath:kr/pe/theeye/dao/mapper/*.xml" />
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
여기서 대부분의 설정은 보시면 어떤 의미를 갖는지 단번에 이해하실것 같은데 굳이 설명해 보자면 sqlSessionFactory빈을 정의할때 사용되는 mapperLocations에 대해 첨언을 해보자면 위와같이 쿼리 매핑을 위한 XML파일을 검색하여 자동 추가하도록 설정할 수 있습니다. 만약에 위의 설정을 다음과 같이 한다면 하위 디렉토리의 모든 파일을 검색하게 됩니다.<property name="mapperLocations"
value="classpath:kr/pe/theeye/dao/mapper/**/*.xml" />
자, 여기까지만 보면 기존의 iBatis 2.x대를 사용하시던 분들이 보기에도 특별히 새로울것이라곤 없습니다. 그냥 클래스 이름 몇개 바뀌었나 싶을 정도밖에 안되죠. 그런데 여기서 중요한 개념이 한가지 추가되었습니다.kr.pe.theeye.dao 패키지 위치에 ExampleDao 인터페이스 생성public interface ExampleDao
{
public String getUserName(@Param("userId") String userId);
}
kr.pe.theeye.dao.mapper 패키지 위치에 ExampleMapper.xml 생성<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="kr.pe.theeye.dao.ExampleDao">
<select id="getUserName" parameterType="string" resultType="string">
SELECT USER_NAME FROM USERS WHERE USER_ID = #{userId}
</select>
</mapper>
여기서 매우매우 중요한점은 DAO클래스를 일단 인터페이스로 선언을 하고 iBatis에서 namespace는 선택사항이었지만 지금부터는 필수라는것입니다. namespace에는 패키지명을 포함한 DAO인터페이스의 경로를 정확히 써줍니다. 그리고 각각의 쿼리문들의 id는 DAO인터페이스에서 정의한 메소드명과 일치하여야 합니다.한번 그림으로 그려보았습니다. 이제 사실상 준비는 끝났습니다. 이제 컨트롤러에서 sqlSession빈을 가져다 쓰시면 됩니다.@Controller
public class ExampleController
{
@Autowired
private SqlSession sqlSession;
@RequestMapping("/test/mybatis/{userId}")
@ResponseBody
public String testMybatis(@PathVariable("userId") String userId)
{
ExampleDao exampleDao = sqlSession.getMapper(ExampleDao.class);
return exampleDao.getUserName(userId);
}
}
위와 같이 DAO를 꺼내쓰기만 하면 실제 쿼리가 XML에 정의된 쿼리들과 자동 매핑되어 결과값이 반환됩니다. 특별히 바뀐부분은 이 부분이 대부분이라 나머지 부분은 iBatis를 쓰시던 분들도 레퍼런스 조금만 들여다 보시면 바로 적용하실 수 있을것으로 보입니다.위와 다르게 단순히 어노테이션 만으로 쿼리문을 작성한다던가 코드를 작성하듯이 쿼리문을 짠다던가 다양한 방법을 MyBatis에서 제공하고 있지만 기존의 iBatis사용자들이 가장 익숙하게 갈아탈 수 있는 방법은 이런 방법이 아닐까 생각됩니다. DAO인터페이스들을 구현하여 사용하는등의 다양한 방법론들이 있지만 그런것은 개발자분들의 의향에 맞게 설계하시면 될 것 같습니다. 다른 예제들은 레퍼런스에 잘 나와있습니다.
출처 - http://theeye.pe.kr/entry/simple-way-to-integration-spring-3-with-mybatis-3