MyBatis (iBatis) 2.3.5 でストアドプロシージャを実行する

MyBatis 2.3.5 を使って Oracle Database のストアドプロシージャを実行するサンプルを書いてみたので、メモしておきます。

※ 名前は MyBatis ですが、2 系に関しては iBatis と同じな認識でいいはず・・・

実行するストアドプロシージャは

■ 以下のエントリーの select_t1_1
・「Oracle」ストアドプロシージャを作成してみる - プログラム日記
http://a4dosanddos.hatenablog.com/entry/2015/05/08/010524

■ 以下のエントリーの select_t1_cursor
・「Oracle」ストアドプロシージャのカーソルを使ってみる - プログラム日記
http://a4dosanddos.hatenablog.com/entry/2015/05/08/012356

にしております。

1. ドメインクラスと対応する sqlMap ファイルを作成する


まず、T1 テーブルのドメインクラス ( こっちはストアドプロシージャの出力パラメータとかによっては必須ではないかもです )、対応する sqlMap ファイルを作成します。

■ T1.java

package mybatis.test;

public class T1 {
	private int id;
	private String name;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

■ t1.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap>
    <select id="getT1Name" resultClass="mybatis.test.T1">
        select id, name from t1 where id = #value#
    </select>
    
    <parameterMap id="selectT1Param" class="map" >
        <parameter property="aa" jdbcType="INTEGER" javaType="java.lang.Integer" mode="IN"/>
        <parameter property="bb" jdbcType="INTEGER" javaType="java.lang.Integer" mode="OUT"/>
        <parameter property="cc" jdbcType="VARCHAR" javaType="java.lang.String" mode="OUT"/>
    </parameterMap>
    <procedure id="selectT1" parameterMap="selectT1Param" >
	{call select_t1_1(?,?,?)}
    </procedure>
	
    <resultMap class="mybatis.test.T1" id="selectT1CursorResult">
      <result property="id" column="id"/>
      <result property="name" column="name"/>
    </resultMap>
    <parameterMap id="selectT1CursorParam" class="map" >
      <parameter property="aa" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN"/>
      <parameter property="bb" jdbcType="ORACLECURSOR" javaType="java.sql.ResultSet" mode="OUT" resultMap="selectT1CursorResult"/>
    </parameterMap>
    <procedure id="selectT1Cursor" parameterMap="selectT1CursorParam" >
	{call bbb.select_t1_cursor(?,?)}
    </procedure>
</sqlMap>

select は本エントリーの主旨とはずれますが、おまけにつけてます。


2. sqlMapConfig ファイルを作成する


■ SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
    <transactionManager type="JDBC">
        <dataSource type="SIMPLE">
            <property name="JDBC.Driver" value="oracle.jdbc.driver.OracleDriver"/>
            <property name="JDBC.ConnectionURL" value="jdbc:oracle:thin:@***.***.***.***:1521:orcl"/>
            <property name="JDBC.Username" value="test"/>
            <property name="JDBC.Password" value="test"/>
        </dataSource>
    </transactionManager>

    <sqlMap resource="t1.xml"/>
</sqlMapConfig>


3. メインクラスを作成する


■ ProcedureCallTest.java

package mybatis.test;

import java.io.IOException;
import java.io.Reader;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

public class ProcedureCallTest {
	public static void main(String[] args) {
		SqlMapClient smc = getSqlMapClient();
		test1(smc);
		test2(smc);
		test3(smc);
	}

	private static void test1(SqlMapClient smc) {
		try {
			T1 t1 = (T1) smc.queryForObject("getT1Name", 1);
			System.out.println(t1.getId() + ":" + t1.getName());
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	private static void test2(SqlMapClient smc) {
		try {
			Map param = new HashMap();
			param.put("aa", 1);
			smc.queryForObject("selectT1", param);
			System.out.println(param.get("bb") + ":" + param.get("cc"));
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	private static void test3(SqlMapClient smc) {
		try {
			Map param = new HashMap();
			param.put("aa", "aaa");
			smc.queryForObject("selectT1Cursor", param);
			List<T1> list = (List<T1>) param.get("bb");
			for (T1 t1 : list) {
				System.out.println(t1.getId() + ":" + t1.getName());
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	private static SqlMapClient getSqlMapClient() {
		SqlMapClient smc = null;
		try {
			Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
			smc = SqlMapClientBuilder.buildSqlMapClient(reader);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return smc;
	}
}

とりあえず、上記で実行できるかと思います。

かなりサボリ気味な内容になっちゃてますが、以上です。

[ 環境情報 ]
Windows 7 SP1
Java SE 8 Update 25
MyBatis 2.3.5
Oracle JDBC Driver 12.1.0.2 ( ojdbc7.jar )

CentOS 5.5
Oracle Database 11g Release 2 ( 11.2.0.1.0 )