spring mybatis @Repository

 

http://blog.naver.com/PostView.nhn?blogId=vikong&logNo=60180414100

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란..
  2. 용량 또는 레코드 수가 많은 레코드셋을 처리할수 있는 방법
  3. 레코드를 한번에 다 가져오지 않고 레코드 하나하나씩을 핸들러에서 처리하는 방식
  4. iBatis 특성상 Recordset 을 모두 List에 저장해야 되는 단점을 극복할수 있는 방법
  5. List에 전부 저장하지 않고 바로바로 처리 하여 메모리를 절약할수 있고 실행 속도 또한 절약 할 수 있다.

 

  1. 핸들러 만들기
  2. 핸들러 클래스는 com.ibatis.sqlmap.client.event.RowHandler를 구현해야 한다.
  3. RowHandler 인터페이스의 void handleRow (Object valueObject)를 구현한다.
  4. handleRow 에 넘어오는 valueObject 는 ResultMap 에 해당하는 Class가 리턴한다. 해당 클래스로 캐스팅하여 데이터를 처리한다.
  5. 핸들러 클래스는 생성을 하여 iBatis에 넘기는 구조이기 때문에 다른 여러 부가적인 처리가 가능하다.
  6. 핸들러 호출
  7. 핸들러 클래스를 생성한 다음 sqlMapClient 함수중 queryWithRowHandler를 호출한다.
  8. queryWithRowHandler ([Select ID], [Parameter Data], [RowHandler Interface]);
  9. 로우 핸들러는 당연히 Select ID에만 매칭이 된다.
  10. queryWithRowHandler (“res.getsResource”, sData, rowHandler);

 

  1. 스프링에서의 호출
  2. 스프링의 getSqlMapClientTemplete ()에는 해당 함수가 없다.
  3. 그러기에 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 class UploadDAO extends SQLManager{

public void insert(UploadDTO dto) throws SQLException{
this.getSqlMap().insert(“uploadInsert”,dto);
}

 

=============================================================================

http://wecuffe.com/158

 

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.*” />

가 필요하다.

 

  1. MemberDaoImpl 클래스에 어노테이션 추가
  • 방법1
MemberDaoImpl.java

 

@Repository public class MemberDaoImpl extends SqlMapClientDaoSupport implements MemberDao {    @Resource(name=”sqlMapClient”)  public void setSuperSqlMapClient(SqlMapClient sqlMapClient){   super.setSqlMapClient(sqlMapClient);  }    @Override  public void insert(MemberVo vo) {   getSqlMapClientTemplate().insert(“member.insert”, vo);  }

@Override  public List<MemberVo> selectList() {   Map<String,Integer> params = new HashMap<String,Integer>();   return getSqlMapClientTemplate().queryForList(“member.selectList”,params);  } }

 

  • 클래스 명에 @Repository를 명세하고 setSuperSqlMapClient 메소드를 통해 sqlMapClient 를 주입한다.
  • 방법2.
  • setSuperSqlMapClient 메소드 대신에 생성자로 sqlMapClient를 주입한다.
 @Autowired  public MemberDaoImpl(SqlMapClient sqlMapClient){   super();   setSqlMapClient(sqlMapClient);  }

[출처] ibatis sqlMapClient 을 @Repository 어노테이션을 이용하여 Dao에 주입하기|작성자 아유

 

===========================================================================================================================

펌 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 로 결과 처리
  1. <select id=”getByIdValueXml” resultClass=”xml” xmlResultName=”account”>FROM EMP</select>
  2. GROUP BY DEPTNO
  3. SELECT DEPTNO,COUNT(DEPTNO) AS DEPT_COUNT

 

  • 위 코드의 반환한 결과는 아래와 같다.

 

iBATIS 가 xml을 반환해주는 값
  1. [ <?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 인터페이스 원형
  1. public interface RowHandler {
  2. void handleRow(Object valueObject);
  3. }

 

  • handleRow 메서드는 매핑 구문 결과 셋의 각 행마다 한 번씩 호출된다. 이 인터페이스를 사용하면 대용량의 데이터를 메모리에 한꺼번에 올리지 않고도 다룰 수 있게 된다. 오직 1 행의 데이터만이 메모리에 적재되어 코드(handleRow)를 호출하고 난 뒤 데이터 객체를 메모리에서 제거하여 모든 결과를 처리할 때까지 이 과정을 반복한다.

 

  • 그럼 이 RowHandler 인터페이스를 이용하여 XML 문서를 생성해보자. RowHandler 를 사용해도 여전히 객체들을 순회하지만 리스트에서 한 번에 오직 한 개의 요소만을 처리하게 된다!

 

RowHandler 를 이용해서 XML 문서를 처리
  1. public class DeptXmlRowHandler implements RowHandler {
  2. private StringBuffer xmlDocument = new StringBuffer(“<TOTAL>”);
  3. private String returnValue = null;
  4. @override
  5. public void handleRow(Object valueObject) {
  6. DeptnoVO dvo = (DeptnoVO) valueObject; xmlDocument.append(“<DEPT>”);
  7. xmlDocument.append(“<DEPTNO>”);
  8. xmlDocument.append(“dvo.getDeptNo()”);
  9. xmlDocument.append(“</DEPTNO>”);
  10. xmlDocument.append(“<DEPT_COUNT>”);
  11. xmlDocument.append(“dvo.getDeptCount()”);
  12. xmlDocument.append(“</DEPT_COUNT>”);
  13. xmlDocument.append(“</DEPT>”);
  14. }
  15. public String getDeptListXML() {
  16. if( null == returnValue) {
  17. xmlDocument.append(“</TOTAL>”);
  18. returnValue = xmlDcoument.toString();
  19. }
  20. return returnValue;
  21. }
  22. }

 

  • 기본 설계 방향은
  1. RowHandler 인스턴스를 생성
  2. 실행할 매핑 구문과 이 매핑 구문에 필요한 파라미터, 그리고 rowHandler 인스턴스를 넘겨준다.
  3. queryWithRowHandler 메서드를 호출

으로 잡으면 된다.

 

XML 문서로 인코딩된 최종 정보를 생성.
  1. DeptXMLRowHandler drh = new DeptXmlRowHandler();
  2. deptDao.queryWithRowHandler(“Dept.getAll”, null, drh);
  3. xmlData = drh.getDeptListXML(); // 루트태그(TOTAL) 중간 부분에 vo 에 담겨진 모든 데이터를 끼어 넣어진 뒤 완성된 XML을 반환.

 

 

최종적으로 반환된 XML 문서 형태
  1. <TOTAL>
  2. <DEPT>
  3. <DEPTNO>30</DEPTNO>
  4. <DEPT_COUNT>6</DEPT_COUNT>
  5.  </DEPT>
  6. <DEPT>
  7. <DEPTNO>20</DEPTNO>
  8. <DEPT_COUNT>5</DEPT_COUNT>
  9. </DEPT>
  10. <DEPT>
  11. <DEPTNO>10</DEPTNO>
  12. <DEPT_COUNT>3</DEPT_COUNT>
  13. </DEPT>
  14. </TOTAL>

 

  • XML의 DOM 파서나 SAX 처럼 확장성은 떨어지만 그래도 iBATIS에도 xml을 파싱하는 방법이 있다는 것에 의의를 두자.^^

=============================================================================================================

http://blog.naver.com/inho1213?Redirect=Log&logNo=80165344493

다른 참조 문서 : http://chanwook.tistory.com/607

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

 

  1. 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>

  1. 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>