application-context.xml
1) @Respository 로 DAO scanning 및 bean 설정 문장
<context:component-scan base-package="trust.repository" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
</context:component-scan>
2) @Transactional 을 위한 설정 문장
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
<!-- a PlatformTransactionManager is still required -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- (this dependency is defined somewhere else) -->
<property name="dataSource" ref="dataSource"/>
</bean>
mybatis-context.xml
1) sqlSessionFactory 지정
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="/WEB-INF/config/mybatis-config.xml"/>
</bean>
2) sqlSessoinTemplate 지정
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sqlSessionFactory"/>
</bean>
TestRepositoryImpl.java
@Repository
public class TestRepositoryImpl extends SqlSessionDaoSupport implements TestRepository
{
/** Test Data 조회 **/
public List<TestModel> getTestData() throws DataAccessException
{
return getSqlSession().selectList("test.list", 0);
}
}
위의 3가지 내용만 보면 TestRepositoryImpl 과 mybatis 의 연관 관계가 명확하지 않다.
mybatis 문서(http://www.mybatis.org/spring/sqlsession.html#SqlSessionDaoSupport) 를 보아도
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. These can be set explicitly or autowired by Spring. If both properties are set, the sqlSessionFactory 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>
에서 처럼 xml 에 DAO 에 대한 설정을 하도록 되어 있다.
그런데 TestRepositoryImpl 에 대한 별도의 bean 설정 없이도 잘 동작한다.
이유는 org.mybatis.spring.support.SqlSessionDaoSupport 를 사용하였기 때문이다.
SqlSessionDaoSupport 에는 setter 가 두가지 존재한다.
두가지 setter 는 다음과 같이 정의 되어 있다.
@org.springframework.beans.factory.annotation.Autowired(required=false)
public void setSqlSessionFactory(org.apache.ibatis.session.SqlSessionFactory sqlSessionFactory);
@org.springframework.beans.factory.annotation.Autowired(required=false)
public void setSqlSessionTemplate(org.mybatis.spring.SqlSessionTemplate sqlSessionTemplate);
mybatis-context.xml 에 정의된 bean sqlSessionFactory, sqlSessionTemplate
이 SqlSessionDaoSupport 에 injection 되도록,
method 에 @Autowired annotation 이 사용되어 있기 때문에 DAO 에 대한 ref bean 설정 없이도 잘 동작 하는 것 이다.
결론, org.mybatis.spring.support.SqlSessionDaoSupport 를 사용하여 DAO 를 구성하면
다음과 같이 sqlSessionFactory 와 sqlSessionTemplate 만 정의하면 된다.
별도의 DAO 와 sqlSession ref 설정은 하지 않아도 된다.
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="/WEB-INF/config/mybatis-config.xml"/>
</bean>
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sqlSessionFactory"/>
</bean>
===========================================================================
펌 http://purred.tistory.com/11
iBatis RowHandler
- 개발팀 남한희 대리
1. iBatis RowHandler 란..
A. 용량 또는 레코드 수가 많은 레코드셋을 처리할수 있는 방법
B. 레코드를 한번에 다 가져오지 않고 레코드 하나하나씩을 핸들러에서 처리하는 방식
C. iBatis 특성상 Recordset 을 모두 List 에 저장해야 되는 단점을 극복할수 있는 방법
D. List 에 전부 저장하지 않고 바로바로 처리 하여 메모리를 절약할수 있고 실행 속도 또한 절약 할 수 있다.
2. 핸들러 만들기
A. 핸들러 클래스는 com.ibatis.sqlmap.client.event.RowHandler 를 구현해야 한다.
B. RowHandler 인터페이스의 void handleRow (Object valueObject) 를 구현한다.
C. handleRow 에 넘어오는 valueObject 는 ResultMap 에 해당하는 Class 가 리턴한다.
해당 클래스로 캐스팅하여 데이터를 처리한다.
D. 핸들러 클래스는 생성을 하여 iBatis 에 넘기는 구조이기 때문에 다른 여러 부가적인 처리가 가능하다.
3. 핸들러 호출
A. 핸들러 클래스를 생성한 다음 sqlMapClient 함수중 queryWithRowHandler 를 호출한다.
B. queryWithRowHandler ([Select ID], [Parameter Data], [RowHandler Interface]);
C. 로우 핸들러는 당연히 Select ID 에만 매칭이 된다.
D. queryWithRowHandler ("res.getsResource", sData, rowHandler);
4. 스프링에서의 호출
A. 스프링의 getSqlMapClientTemplete () 에는 해당 함수가 없다.
B. 그러기에 getSqlMapClient () 를 호출하여 직접 sqlMapClient 에 접근하여 호출한다
============================================================================
펌 http://javastore.tistory.com/62
iBatis - SqlMapClient class 만들어 주는 util
iBatis를 사용할때 template를 쓰지 않을때는 항상 SqlMapConfig파일을 통해 SqlMapClient를 생성해야 한다. 그것을 쉽게 해주기 위한 Abstract class이다.
package com.myhome.manager;
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
public abstract class SQLManager {
private SqlMapClient sc = null;
public SQLManager(){
try{
sc = SqlMapClientBuilder.buildSqlMapClient(
Resources.getResourceAsReader(
"com/myhome/manager/SqlMapConfig.xml")); //sql설정이 들어가 있는 SqlMapConfig파일 위치 지정
//classes 폴더에 있으면 SqlMapClient.xml로 바로 지정 해도 됨
}catch(java.io.IOException ie){
ie.printStackTrace();
}
}
public SqlMapClient getSqlMap(){
return sc;
}
}
사용방법은 extends로 다음 클래스 파일을 확장 받은다음에 getSqlMap을 통해 SqlMapCleint를 생성한다.
예)
public void insert(UploadDTO dto) throws SQLException{
this.getSqlMap().insert("uploadInsert",dto);
}
=============================================================================
Spring Bean 정보는 싱글톤 객체로 생성되기 때문에
메모리에 존재한다고 보면 된다 ..
ApplicationContext appContext = ContextLoaderListener.getCurrentWebApplicationContext(); (SqlMapClient) appContext.getBean("sqlMapClient"); |
위 방식으로 빈이름 sqlMapClient 과 케스팅 클레스 SqlMapClient 형태로 변환하면 내가 등록한 BEAN 정보를 가지고 올수 있다.
=============================================================================
펌 http://blog.naver.com/PostView.nhn?blogId=namoyo&logNo=110150099499
xml 에 dao 빈을 설정하고 sqlMapClient를 주입하는 방식 말고 자바 클래스에서 어노테이션으로 Dao클래스에
예 member-dao.xml
<bean id="memberDao" class="com.test.dao.MemberDaoImpl">
<property name="sqlMapClient" ref="sqlMapClient" />
</bean>
이 xml을 없애고 @Repository 이용하기
1. XML로 빈을 설정하지 않으려면 메인 설정 xml에
<context:component-scan base-package="com.test.*" />
가 필요하다.
2. MemberDaoImpl 클래스에 어노테이션 추가
- 방법1
MemberDaoImpl.java
@Repository @Override |
- 클래스 명에 @Repository를 명세하고 setSuperSqlMapClient 메소드를 통해 sqlMapClient 를 주입한다.
- 방법2.
- setSuperSqlMapClient 메소드 대신에 생성자로 sqlMapClient를 주입한다.
@Autowired |
===========================================================================================================================
펌 http://blog.naver.com/PostView.nhn?blogId=ssallow&logNo=60103459223
iBatis에서 대용량의 쿼리 사용시 유용하게 사용할 수 있는 방법은 RowHandler를 이용하는 방법이다..
먼저 RowHandler 인터페이스를 구현해 주고... (Object 파라미터 하나를 갖는 handleRow 메소드 하나 밖에 없다...)
쿼리를 실행할 때 queryWithRowHandler(id, rowHandler)로 실행하면 된다...
rowHandler의 Object는 SqlMap에 정의된 <select> id의 리턴 타입으로 캐스트 하여 사용하면 되겠다..
-
iBATIS도 역시 친절하게 XML을 반환해주는 능력이 있다.
그렇지만 일반적으로 iBATIS에서 XML 사용은 권장하지 않는다고 한다.
XML 을 사용하는 건 쿼리를 객체에 매핑하는 작업을 단순하게 만들고자 하는 iBATIS 의 철학은 어울리지 않기 때문이다.
그래도 방법은 있으니 한 번 공부해보자.
- iBATIS 는 아래처럼 매핑 구문을 통하여 XML 로 결과를 생성할 수 있다.
매핑구문에서 xml 로 결과 처리
-
<select id="getByIdValueXml" resultClass="xml" xmlResultName="account">
SELECT
DEPTNO,COUNT(DEPTNO) AS DEPT_COUNTFROM EMP
GROUP BY DEPTNO
</select>
- 위 코드의 반환한 결과는 아래와 같다.
iBATIS 가 xml을 반환해주는 값
- [
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<dept>
<DEPTNO>30</DEPTNO>
<DEPT_COUNT>6</DEPT_COUNT>
</dept>,
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<dept>
<DEPTNO>20</DEPTNO>
<DEPT_COUNT>5</DEPT_COUNT>
</dept>,
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<dept>
<DEPTNO>10</DEPTNO>
<DEPT_COUNT>3</DEPT_COUNT>
</dept>
]
-
뭔가 이상하지 않나? 위 처럼 하나의 결과가 여러개 합쳐진 꼴로 반환하게 된다..
그래서 iBATIS의 매핑 구문의 resultClass , xmlResultName을 속성을 이용하여 XML을 만드는 것은결과 집합이 단일 일 때 ( 게시물을 카운팅한다거나..) 유용하다.
- 그러면 결과 집합이 여러개 일때 이것을 한 묶음으로 결과를 얻으려면 어떻게 해야하나?
이 때 사용해볼 것이 바로 RowHandler 인터페이스 이다. - RowHandler 인터페이스는 매우 간단하며, 매핑 구문의 결과 셋을 처리하는 과정에 특정 행위를 삽입하도록 해준다.
그리고 오직 한 개의 메서드만을 포함하고 있다.
RowHandler 인터페이스 원형
- public interface RowHandler {
- void handleRow(Object valueObject);
- }
- handleRow 메서드는 매핑 구문 결과 셋의 각 행마다 한 번씩 호출된다. 이 인터페이스를 사용하면
대용량의 데이터를 메모리에 한꺼번에 올리지 않고도 다룰 수 있게 된다.
오직 1 행의 데이터만이 메모리에 적재되어 코드(handleRow)를 호출하고 난 뒤 데이터 객체를 메모리에서 제거하여
모든 결과를 처리할 때까지 이 과정을 반복한다.
- 그럼 이 RowHandler 인터페이스를 이용하여 XML 문서를 생성해보자.
RowHandler 를 사용해도 여전히 객체들을 순회하지만 리스트에서 한 번에 오직 한 개의 요소만을 처리하게 된다!
RowHandler 를 이용해서 XML 문서를 처리
- public class DeptXmlRowHandler implements RowHandler {
- private StringBuffer xmlDocument = new StringBuffer("<TOTAL>");
- private String returnValue = null;
- @override
- public void handleRow(Object valueObject) {
- DeptnoVO dvo = (DeptnoVO) valueObject;
xmlDocument.append("<DEPT>"); - xmlDocument.append("<DEPTNO>");
- xmlDocument.append("dvo.getDeptNo()");
- xmlDocument.append("</DEPTNO>");
- xmlDocument.append("<DEPT_COUNT>");
- xmlDocument.append("dvo.getDeptCount()");
- xmlDocument.append("</DEPT_COUNT>");
- xmlDocument.append("</DEPT>");
- }
- public String getDeptListXML() {
- if( null == returnValue) {
- xmlDocument.append("</TOTAL>");
- returnValue = xmlDcoument.toString();
- }
- return returnValue;
- }
- }
- 기본 설계 방향은
- RowHandler 인스턴스를 생성
- 실행할 매핑 구문과 이 매핑 구문에 필요한 파라미터, 그리고 rowHandler 인스턴스를 넘겨준다.
- queryWithRowHandler 메서드를 호출
으로 잡으면 된다.
XML 문서로 인코딩된 최종 정보를 생성.
- DeptXMLRowHandler drh = new DeptXmlRowHandler();
- deptDao.queryWithRowHandler("Dept.getAll", null, drh);
-
xmlData = drh.getDeptListXML(); // 루트태그(TOTAL) 중간 부분에 vo 에 담겨진 모든 데이터를 끼어 넣어진 뒤 완성된 XML을 반환.
최종적으로 반환된 XML 문서 형태
- <TOTAL>
- <DEPT>
- <DEPTNO>30</DEPTNO>
- <DEPT_COUNT>6</DEPT_COUNT>
- </DEPT>
- <DEPT>
- <DEPTNO>20</DEPTNO>
- <DEPT_COUNT>5</DEPT_COUNT>
- </DEPT>
- <DEPT>
- <DEPTNO>10</DEPTNO>
- <DEPT_COUNT>3</DEPT_COUNT>
- </DEPT>
- </TOTAL>
- XML의 DOM 파서나 SAX 처럼 확장성은 떨어지만 그래도 iBATIS에도 xml을 파싱하는 방법이 있다는 것에 의의를 두자.^^
DB 연동을 하려면 DB와 커넥션을 맺어야 하는데 이게 꽤나 비용이 큰 작업이다..
이걸 좀 줄여보자고 나온게 커넥션 풀이란 개념인데 요걸 이용하고자 DataSource를 설정해줘야 한다...
Spring에서는 3가지를 제공하는데 차근 차근 살펴보자..
1. DBCP
말 그대로 apache commons의 DBCP를 이용해서 DataSource를 설정하는 방법이다..
MySQL을 사용한다면 대충 아래와 같이 설정해주면 바로 사용할 수 있다..
* org.springframework.jdbc.datasource.SimpleDriverDataSource 이것도 있다.
<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:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="user"/>
<property name="password" value="password"/>
</bean>
BasicDataSource는 위 4가지 말고도 여러가지 옵션이 있는데 자세한 내용은 아래 URL을 참고하자.
http://commons.apache.org/dbcp/configuration.html
2. JNDI
요건 JNDI라고 해서 J2EE에서 사용하는 건데 대충 리소스를 등록하고 찾기 위해 사용하는 거라고 볼 수 있다...
JNDI에 DataSource를 등록하는건 찾아보면 많으니 알아서 찾아보고 등록된 것을 사용하려면 아래와 같이 사용하면 된다..
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jee="http://www.springframework.org/schema/jee"
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-2.5.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/dataSource" resource-ref="true"/>
...
</beans>
위와 같이 jee 네임스페이스와 스키마를 추가해주고 jee태그를 사용하면 된다.
jndi-name 속성에 등록한 JNDI 이름을 넣어주면 된다..
resource-ref 속성이 true로 지정되면 jndi-name에 지정된 값에 java:comp/env 가 prefix로 붙는다...
저렇게 사용하기 싫다면 아래와 같이 bean을 하나 등록해서 사용하면 된다...
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/dataSource"/>
<property name="resourceRef" value="true"/>
</bean>
3. DriverManager
그냥 닥치고 아래와 같이 하면 된다..
<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?useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="user"/>
<property name="password" value="password"/>
</bean>
DataSource를 설정했으니 이제 직접 가져다 쓰기만 하면 된다...
Connection conn = dataSource.getConnection();
conn.close();
하지만... Spring에서 제공하는 트랜잭션을 사용하고 싶다면 아래와 같이 사용하는 것이 좋다..
Connection conn = DataSourceUtils.getConnection(dataSource);
DataSourceUtils.releaseConnection(conn, dataSource);
=========================================================================================================================
http://elindreams.egloos.com/820087
Datasource설정
1. Apache그룹의 Common라이브러리를 이용해서 설정하는 방법
[applicationContext.xml]
<beans ...>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource“
destroy-method="close">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@localhost:1521:xe</value>
</property>
<property name="username">
<value>sa</value>
</property>
<property name="password">
<value>sa</value>
</property>
</bean>
</beans>
=> 가장 많이 사용되는 Apache그룹의 Common라이브러리를 이용해서 설정한 것으로 Common라이브러리의
BasicDataSource클래스를 빈으로 등록하고 Connection 연결에 필요한 정보를 Setter Injection 형태로 설정함.
2. Spring Framework가 제공하는 DataSoruce구현 클래스를 이용하는 방법
[applicationContext.xml]
<beans ...>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@localhost:1521:xe</value>
</property>
<property name="username">
<value>hr</value>
</property>
<property name="password">
<value>hr</value>
</property>
</bean>
</beans>
3. WAS(톰캣,웹로직 등등)에서 제공하는 DataSource를 이용하는 방법
[applicationContext.xml]
<beans ...>
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc:comp/env/jdbc/myOracle" />
</bean>
</beans>
[출처] spring mybatis @Repository|작성자 바이콩
'Mybatis > 노하우정보' 카테고리의 다른 글
Spring Boot의 Java Config, myBatis를 통해 Datasource 연동하기 (0) | 2017.11.19 |
---|---|
iBatis VS. myBatis (0) | 2016.04.28 |
mybatis-resultType을 배열로 (1) | 2016.04.27 |
MyBatis에서 Batch처리(SqlSession과 foreach) (0) | 2016.04.27 |
MyBatis 내장 cache 에 대해서 (0) | 2016.04.27 |
Spring Transaction propagation mode에 따른 내부 동작 메커니즘 (0) | 2016.04.27 |
Spring Transaction 내부 동작 메커니즘 (0) | 2016.04.27 |
TransactionTemplate 을 이용한 Spring Transaction 사용 (0) | 2016.04.27 |