코드를 보다보니, 아래와 같은 코드가 있어서 확인해 봤습니다.. ^^;;

try {
session = createSqlSession();
// db 처리.. .
} finally {
// db 세션 종료
if(session != null) {
session.commit();
session.close();
}
}

그래서, http://code.google.com/p/mybatis/source/browse/tags/mybatis-3.0.4/src/main/java/org/apache/ibatis/session/defaults/DefaultSqlSession.java 의 session코드에서 commit메쏘드와 close메쏘드를 살펴 봤습니다..

* commit() : 오버로딩하는 두개의 메쏘드가 있네요.. ^^
  public void commit() {
    commit(false);
  }

  public void commit(boolean force) {
    try {
      executor.commit(isCommitOrRollbackRequired(force));
      dirty = false;
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error committing transaction.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

* close()
  public void close() {
    try {
      executor.close(isCommitOrRollbackRequired(false));
      dirty = false;
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error closing transaction.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

위 코드를 보시면, commit();close(); 코드와 close();가 있습니다..
코드를 따라가다 보면, 결국, http://code.google.com/p/mybatis/source/browse/tags/mybatis-3.0.4/src/main/java/org/apache/ibatis/transaction/jdbc/JdbcTransaction.java 에서, 아래와 같은 코드를 볼 수 있습니다.

  public void commit() throws SQLException {
    if (!connection.getAutoCommit()) {
      connection.commit();
    }
  }

  public void close() throws SQLException {
    resetAutoCommit();
    connection.close();
  }

  protected void resetAutoCommit() {
    try {
      if (!connection.getAutoCommit()) {
        // for compatibility we always use true, as some drivers don't like being left in "false" mode.
        connection.setAutoCommit(true);
      }
    } catch (SQLException e) {
      // Only a very poorly implemented driver would fail here,
      // and there's not much we can do about that.
      throw new TransactionException("Error configuring AutoCommit.  " +
          "Your driver may not support getAutoCommit() or setAutoCommit(). Cause: " + e, e);
    }
  }

흠, 따라서 commit();close();와 close();가 동일할 거라는 심증만 가지게 되네요..^^;;
commit();close();해야 하나요?? close();만 하면 되까요?? ㅋㅋ
저작자 표시
http://novathin.kr/님께서 알려준, 오라클 db conn detect할 수 있는 옵션입니다.
<dataSource type="POOLED"> 안에 아래의 property를 넣어주면 됩니다..
<property name="poolPingEnabled" value="true"/>
<property name="poolPingQuery" value="select 1 from dual"/>
아, 좋네요.. ^^
저작자 표시
위와 같은 에러가 나올경우..
흠.. 알면 쉬운데.. 왜 나는지 정확하게 모르면 엄청 고생하게 되네요..

위 내용은 Mapper에 선언되어 있는 메쏘드 이름과 mapper 파일의 select나 insert등의 이름과 일치하지 않아서 발생합니다.. 아래 처럼 말이죠.. ^^;;

ex) 인터페이스 이름
public String print(String x) throws Exception;

ex) mapper.xml
<select id="prints" statementType="CALLABLE" parameterType="String" resultType="String">
        .........................
</select>


저작자 표시
Tag // iBATIS, Mapper, mybatis
mssql 2008을 ibatis에서 사용하기 위한 세팅입니다.
흠.. mssql을 잘 몰라서 포트 세팅하는데 힘들었네요.. ^^;;
전에는 default port가 1433이었는데..

Sql Server Configuration Manager --> SQL Server 네트워크 구성 --> TCP/IP 사용의 속성창을 보시면 아래의 화면이 나옵니다.. 그리고 TCP 동적포트로 접근을 하시면 됩니다.. ^^;;



<sqlMapConfig>
    <transactionManager type="JDBC" commitRequired="false">
        <dataSource type="SIMPLE">
            <property name="JDBC.Driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
            <property name="JDBC.ConnectionURL" value="jdbc:sqlserver://computer-name\SQLEXPRESS:4147;databaseName=testdb;integratedSecurity=true;"/>
            <property name="JDBC.Username" value="id"/>
            <property name="JDBC.Password" value="password"/>
            <property name="Pool.MaximumIdleConnections" value="5"/>
            <property name="Pool.MaximumCheckoutTime" value="120000"/>
            <property name="Pool.TimeToWait" value="500"/>
        </dataSource>
    </transactionManager>
    <sqlMap resource="article.xml"/>
</sqlMapConfig>

그리고, 혹시  경고: Failed to load the sqljdbc_auth.dll 메세지를 뿌르게 되면..
플랫폼에 맞는 sqljdbc_auth.dl를 windows\system32폴더에 카피를 하시면 됩니다. 

Apache iBatis에서 다중의 데이타 베이스에 접속하는 방법에 대한 내용입니다.

1. database.properties

driver=oracle.jdbc.driver.OracleDriver
jdbc.url1=jdbc:oracle:thin:@mimuluserdb:1521:mimuluser
username1=mimuluser
password1=mimuluser

jdbc.url2=jdbc:oracle:thin:@pepsiuserdb:1521:pepsiuser
username2=pepsiuser
password2=pepsiuser

2. sqlmap1.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
        PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
        "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
    <properties resource="com/mimul/dwr/app/
               resource/database.properties"/>
    <settings
            cacheModelsEnabled="true"
            enhancementEnabled="true"
            lazyLoadingEnabled="true"
            maxRequests="40"
            maxSessions="20"
            maxTransactions="5"
            useStatementNamespaces="false"
            />
    <transactionManager type="JDBC">
        <dataSource type="DBCP">
            <property name="driverClassName" value="${driver}"/>
            <property name="url" value="${jdbc.url1}"/>
            <property name="username" value="${username1}"/>
            <property name="password" value="${password1}"/>

            <!-- OPTIONAL PROPERTIES BELOW -->
            <property name="initialSize" value="5"/>
            <property name="maxActive" value="30"/>
            <property name="maxIdle" value="20"/>
            <property name="maxWait" value="60000"/>
            <property name="poolPreparedStatements" value="true"/>
            <property name="validationQuery" value="select 0 from dual"/>
            <property name="testOnBorrow" value="true"/>
            <property name="maximumActiveConnections" value="10"/>
            <property name="maximumIdleConnections" value="5"/>
            <property name="maximumWait" value="60000"/>
            <property name="logAbandoned" value="false"/>
            <property name="removeAbandoned" value="false"/>
            <property name="removeAbandonedTimeout" value="50000"/>
        </dataSource>
    </transactionManager>
    <sqlMap resource="com/mimul/dwr/app/sql/Mimul.xml"/>
</sqlMapConfig>

3. sqlmap2.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
        PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
        "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
    <properties resource="com/mimul/dwr/app/resource/database.properties"/>
    <settings
            cacheModelsEnabled="true"
            enhancementEnabled="true"
            lazyLoadingEnabled="true"
            maxRequests="40"
            maxSessions="20"
            maxTransactions="5"
            useStatementNamespaces="false"
            />
    <transactionManager type="JDBC">
        <dataSource type="DBCP">
            <property name="driverClassName" value="${driver}"/>
            <property name="url" value="${jdbc.url2}"/>
            <property name="username" value="${username2}"/>
            <property name="password" value="${password2}"/>

            <!-- OPTIONAL PROPERTIES BELOW -->
            <property name="initialSize" value="5"/>
            <property name="maxActive" value="30"/>
            <property name="maxIdle" value="20"/>
            <property name="maxWait" value="60000"/>
            <property name="poolPreparedStatements" value="true"/>
            <property name="validationQuery" value="select 0 from dual"/>
            <property name="testOnBorrow" value="true"/>
            <property name="maximumActiveConnections" value="10"/>
            <property name="maximumIdleConnections" value="5"/>
            <property name="maximumWait" value="60000"/>
            <property name="logAbandoned" value="false"/>
            <property name="removeAbandoned" value="false"/>
            <property name="removeAbandonedTimeout" value="50000"/>
        </dataSource>
    </transactionManager>
    <sqlMap resource="com/mimul/dwr/app/sql/Pepsi.xml"/>
</sqlMapConfig>

4. SqlCondig.java

import java.io.File;
import java.io.Reader;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import com.jaeminara.common.log.LogPool;

public class SqlConfig {
    private static SqlMapClient sqlMap1 = null;
    private static SqlMapClient sqlMap2 = null;
    private static SqlConfig instance_ = null;
   
    private SqlConfig() throws Exception {
        Reader reader = null;
        String resource = null;
        try {
            if (sqlMap == null) {
                resource = "sqlmap1.xml";
              reader = Resources.getResourceAsReader(resource);
              sqlMap1 = SqlMapClientBuilder.buildSqlMapClient(reader);
                resource = "sqlmap2.xml";
              reader = Resources.getResourceAsReader(resource);
              sqlMap2 = SqlMapClientBuilder.buildSqlMapClient(reader);
              reader.close();
            }
        } catch (Exception e) {
            System.out.println(e);
            throw e;
        } finally {
            if (reader != null)
                reader.close();
            reader = null;
            rsc = null;
        }
    }
   
    public static SqlConfig instance() {
        try {
            if (instance_ == null) {
                synchronized (SqlConfig.class) {
                    if (instance_ == null)
                        instance_ = new SqlConfig();
                }
            }
        } catch (Exception e) {
            System.out.println(e);
        }
        return instance_;
    }

    /**
     * Return SqlMapClient for SDP schema
     *
     * @return
     */
    public static SqlMapClient getSqlMap1Instance() {
        return sqlMap1;
    }

    /**
     * Return SqlMapClient for SDP schema
     *
     * @return
     */
    public static SqlMapClient getSqlMap2Instance() {
        return sqlMap2;
    }
}

이 내용은 http://mimul.com/pebble/default/2008/02/24/1203779580000.html 에서 발췌를 하였습니다.
에고...
IBatis에서 MSSQL2000 인스턴스의 카탈로그에 접속하기 위해서 한참을 헤메서 겨우 찾았네요.. ^^;;

아래는 해결책입니다.. ^^;;

해결책은 인스턴스의 실제 TCP 포트로 접속하면 됩니다.. ^^;;
넘 간단한가?? ㅋㅋ
Apache iBatis에서 MSSQL DB에 Insert시에 리턴값을 받아오는 형태입니다.

1. 코드
int key = (int)sqlMap.Insert("InsertOrganization", organization);

2. xml 내용

<insert id="InsertOrganization" parameterClass="Organization" resultClass="int">  
    <selectKey property="Id" type="post" resultClass="int">  
        SELECT @@IDENTITY AS value  
    </selectKey>              
    INSERT INTO Organizations  
        (Org_Code, Org_Name)   
    VALUES   
        (#Code#, #Name#)  
</insert>  

내용의 출처는 http://www.mimul.com/pebble/default/2007/12/09/1197199680000.html 입니다.

프로젝트 개발을 하다보면 light한 환경을 요하는 경우가 있습니다. 이럴 경우 spring framework를 대신하여 dbcp + ibatis를 가지고 개발을 진행하는 경우도 발생할 것입니다. 이럴 경우 유용하리라 생각되어 설치과정을 공유합니다.
일단 Tomcat 환경에서 설치 과정을 설명하겠습니다.

1. DBCP 설치
 - 실치 과정은 여기에 가시면 설치과정을 설명해 놓았습니다.
 
2. iBatis 설치
 - 여기에 가서 다운로드
 - ${ProjectWebRoot}/WEB-INF/lib에 ibatis-2.3.0.677.jar 카피

3. sqlmap.xml 정의
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
        PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
        "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
    <properties resource="com/mimul/dwr/app/resource/database.properties"/>
    <settings
            cacheModelsEnabled="true"
            enhancementEnabled="true"
            lazyLoadingEnabled="true"
            maxRequests="40"
            maxSessions="20"
            maxTransactions="5"
            useStatementNamespaces="false"
            />
    <transactionManager type="JDBC">
        <dataSource type="DBCP">
            <property name="driverClassName" value="${driver}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${username}"/>
            <property name="password" value="${password}"/>

            <!-- OPTIONAL PROPERTIES BELOW -->
                <property name="initialSize" value="5"/>
                <property name="maxActive" value="30"/>
                <property name="maxIdle" value="20"/>
                <property name="maxWait" value="60000"/>
                <property name="poolPreparedStatements" value="true"/>
                <property name="validationQuery" value="select 0 from dual"/>
                <property name="testOnBorrow" value="true"/>
                <property name="maximumActiveConnections" value="10"/>
                <property name="maximumIdleConnections" value="5"/>
                <property name="maximumWait" value="60000"/>
                <property name="logAbandoned" value="false"/>
                <property name="removeAbandoned" value="false"/>
                <property name="removeAbandonedTimeout" value="50000"/>
        </dataSource>
    </transactionManager>
    <sqlMap resource="com/mimul/dwr/app/sql/Mimul.xml"/>
</sqlMapConfig>
4. com/mimul/dwr/app/resource/database.properties 정의
driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@mimuluserdb:1521:mimuluser
username=mimuluser
password=mimuluser
5. com/mimul/dwr/app/sql/Mimul.xml 정의
 - DDL2iBatis.exe를 활용하여 자동 생성하게 하는 것이 개발 속도가 올라갑니다.
<?xml version='1.0'?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
    "http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="Mimul">
    <cacheModel id="mimul-cache" type="MEMORY">
        <flushInterval hours="24"/>
        <flushOnExecute statement="insertMimul"/>
        <flushOnExecute statement="updateMimul"/>
        <flushOnExecute statement="deleteMimul"/>
        <property name="reference-type" value="WEAK" />
    </cacheModel>
    <resultMap class="com.mimul.dwr.model.Mimul" id="mimul-result" >
        <result property="lseq" column="lseq" />
        <result property="sseq" column="sseq" />
        <result property="assetid" column="assetid" />
        <result property="title" column="title" />
        <result property="imgurl" column="imgurl" />
        <result property="vodurl" column="vodurl" />
        <result property="use" column="use" />
        <result property="chgdate" column="chgdate" />
    </resultMap>
    <select id="getMimul" resultClass="com.mimul.dwr.model.Mimul"
parameterClass="Integer" >
        <![CDATA[
            SELECT lseq, sseq, assetid, title, imgurl, vodurl, use, chgdate
            FROM   mimul
            WHERE  lseq = #lseq#
        ]]>
    </select>
    <update id="updateMimul" parameterClass="com.mimul.dwr.model.Mimul" >
        <![CDATA[
            UPDATE mimul
            SET    sseq = #sseq#,  assetid = #assetid#,  title = #title#, 
imgurl = #imgurl#,  vodurl = #vodurl#,  use = #use#, 
chgdate = #chgdate#
            WHERE  lseq = #lseq#
        ]]>
    </update>
    <insert id="insertMimul" parameterClass="com.mimul.dwr.model.Mimul" >
        <selectKey resultClass="int"  keyProperty="lseq" >
            SELECT mimul_lseq_seq.nextval as lseq FROM dual
        </selectKey>
        INSERT INTO mimul (lseq, sseq, assetid, title, imgurl, vodurl,
use, chgdate)
        VALUES (#lseq#, #sseq#, #assetid#, #title#, #imgurl#, #vodurl#,
#use#, #chgdate#)
    </insert>
    <delete id="deleteMimul" parameterClass="com.mimul.dwr.model.Mimul" >
        <![CDATA[
            DELETE FROM mimul
            WHERE  lseq = #lseq#
        ]]>
    </delete>
</sqlMap>
6.  DAO에서 사용하기 위한 SqlConfig 객체 정의(dbcp+ibatis연결 정보 정의)
import java.io.File;
import java.io.Reader;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import com.jaeminara.common.log.LogPool;

public class SqlConfig {
    private static SqlMapClient sqlMap = null;
    private static SqlConfig instance_ = null;
  
    private SqlConfig() throws Exception
    {
        Reader reader = null;
        StringBuffer rsc = null;
        try {
            if (sqlMap == null) {
                rsc = new StringBuffer(200);
                rsc.append("com").append(File.separator);
                rsc.append("jaeminara").append(File.separator);
                rsc.append("dwr").append(File.separator);
                rsc.append("app").append(File.separator);
                rsc.append("sql").append(File.separator).append("sqlmap.xml");
             reader = Resources.getResourceAsReader(rsc.toString());
             sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
             reader.close();
            }
        } catch (Exception e) {
            System.out.println(e);
            throw e;
        } finally {
            if (reader != null)
                reader.close();
            reader = null;
            rsc = null;
        }
    }
  
    public static SqlConfig instance()
    {
        try {
            if (instance_ == null) {
                synchronized (SqlConfig.class) {
                    if (instance_ == null)
                        instance_ = new SqlConfig();
                }
            }
        } catch (Exception e) {
            System.out.println(e);
        }
        return instance_;
    }

    /**
    * Return SqlMapClient for SDP schema
     *
     * @return
     */
    public static SqlMapClient getSqlMapInstance()
    {
        return sqlMap;
    }
}

7. DAO 클래스 정의
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ibatis.sqlmap.client.SqlMapClient;
import com.mimul.common.log.LogPool;
import com.mimul.dwr.model.getMimulByLSEQ;

public class MimulDao
{
    private SqlMapClient smc =
SqlConfig.instance().getSqlMapInstance();
  
    public void MimulDao() {}
  
    public Mimul getMimulByLSEQ(int lseq) throws Exception
    {
        Mimul mimul = null;

        try {
            if (lseq == 0) {
                LogPool.instance("DAO").debug("getMimulByLSEQ() : Parameter is null!");
                return null;
            }
        mimul = (Mimul) smc.queryForObject("getMimul", lseq);
        } catch (Exception e) {
            LogPool.instance("DAO").error(e);
            throw e;
        }
        return mimul;
    }
    // 기타 필요한 함수 정의
}
크게 어려운 점은 없습니다. 그리고 transaction 무결성을 보장하기 위해서는 executor.startBatch();와 executor.executeBatch(); transaction 처리 로직을 넣으시면 됩니다.
나머진 자동으로 iBatis에서 트랜젝션 자원의 할당 및 해지의 라이프사이클을 관리해 줍니다.