S_a_k_Uの日記みたいなDB

~サクゥーと呼ばないで~

ストアドプロシージャの結果をカーソルで受け取る

jdbcTypeってのでORACLECURSORってのを指定すれば、戻り値としてカーソルを受け取れるのか。
jdbcTypeってDBMSで扱う型のことで、DBMS(JDBCドライバ)に依存することになるんじゃろうな。
複数のカーソルも受け取れるってことで、複数の集合の抽出もOKってことになる訳か。グフ♪
ただ、DBMSに依存し過ぎな感じじゃな。


で、複数の戻り値は、JDBC上でのResultSet?の扱いはどうなりょんじゃ???
と思ったら、ストアドプロシージャの場合は、CallableStatementインターフェースで、registerOutParameterメソッドで戻り値の順番と型を定義するっぽいな。
そことiBATISのjdbcTypeが繋がるらしい。
で、戻り値として定義する型はDBMS(JDBCドライバ)に依存しますよと。


んでもって、参考サイトのコードいろいろ状況が違うせい?なんか動作せんので、こんなコードにしてみた。
Java 1.5.0_12
iBATIS 2.3.0.677
Oracle 9i
JDBC Driver ojdbc14.jar

【sqlMap.xml】

<?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>

    <resultMap class="xxx.yyy.zzz.Employee" id="resultEmployee">
        <result property="id" column="EMP_ID"/>
        <result property="name" column="EMP_NAME"/>		
    </resultMap>	
	 
    <parameterMap id="paramSelectEmployeeList" class="java.util.Map" >
        <parameter property="empList" jdbcType="ORACLECURSOR" javaType="java.sql.ResultSet" mode="OUT"  resultMap="resultEmployee" />        
    </parameterMap>
    
    <procedure  id="procSelectEmployeeList" parameterMap="paramSelectEmployeeList" >
        { call SELECT_EMP_LIST(?) }
    </procedure>
   	
</sqlMap>

parameterMapのparameterの属性に、javaType="java.sql.ResultSet"を指定しないと、出力パラメータのempListがResultSetになってしまう(resultMapによりEmployeeオブジェクトを生成してくれない)。
んでも、javaTypeを指定することにより、empListはListオブジェクトとなり、要素はEmployeeオブジェクトとなった。メデタシメデタシ。

【EmployeeDao.java】

public class EmployeeDao extends SqlMapClientDaoSupport {

    public EmployeeDao () {
        super();
    }

    public List getEmployeeList() {

        List ret = new ArrayList();
		
        try {
			
            Map paramMap = new HashMap();

            getSqlMapClientTemplate().queryForObject("procSelectEmployeeList", paramMap);
			
            Object obj = resMap.get("empList");

            if ((obj != null) && (obj instanceof List)) {
                List list = (List) obj;
                for ( int i = 0 ; i < list.size() ; i++ ) {
                    Employee emp = (Employee) list.get(i);
                    ret.add(emp);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return ret;

    }

}

SqlMapClientDaoSupportを使ってると、サンプルに倣ってgetSqlMapClient().queryForObject(…)で実行するとぬるぽになる。
なので、いつも通りのgetSqlMapClientTemplate().queryForObject(…)としてみた。



■参考サイト

Dashboard > iBATIS DataMapper > Oracle REF CURSOR Solutions
http://opensource.atlassian.com/confluence/oss/display/IBATIS/Oracle+REF+CURSOR+Solutions


PostgreSQLならこんな感じになるんか???
Mailing list archives > Refcursor and postgresql how to make it work ?
http://mail-archives.apache.org/mod_mbox/ibatis-user-java/200609.mbox/%3C4508A11B.7030204@siunik.com%3E


PostgreSQLならこんな解決策もあるんか。
報われないプログラマ > PostgreSQLJavaストアド(PL/PgJava)
http://kane.ti-da.net/e1683949.html
少しAOPっぽくできそう???