引数がStructのストアドプロシージャ
続いて、引数がStructのストアドプロシージャの扱い方を考える。
PERSON型を渡して、PERSON.NAMEを返すようなプロシージャを定義する。
CREATE OR REPLACE FUNCTION "PERSON_NAME" ( USER in PERSON ) return VARCHAR2 is begin return USER.NAME; end; /
これに対応したJavaのソースは、以下の通り。
package examples.dao; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.Struct; import java.sql.Types; import org.seasar.extension.dbcp.ConnectionPool; import org.seasar.framework.container.S2Container; import org.seasar.framework.container.factory.S2ContainerFactory; public class StoredTypeArgClient { private static final String PATH = "j2ee.dicon"; public static void main(String[] args) throws Exception { S2Container container = S2ContainerFactory.create(PATH); container.init(); ConnectionPool pool = (ConnectionPool) container .getComponent(ConnectionPool.class); Connection conn = pool.checkOut(); Person person = new Person(); person.setId(Integer.valueOf(100)); person.setName("USER1"); CallableStatement stmt = conn.prepareCall("{? = call PERSON_NAME(?)}"); stmt.registerOutParameter(1, Types.VARCHAR); stmt.setObject(2, person, Types.STRUCT); stmt.execute(); Object o = stmt.getObject(1); System.out.println(o); } }
さて、ここでPerson型をどう扱うべきか。
選択肢としては、
- ORADataの実装 (toDatumメソッドを実装する)
- SQLDataの実装 (getSQLTypeName, readSQL, writeSQLを実装する)
の2種類があるんだけど、ここでは簡単なORADataを選択する。
真面目にSQLDataを実装すれば、
OracleのJDBCドライバに依存しなくて済むかも知れないんだけど
どうせ、Arrayを扱う時に、Oracleドライバに依存する事になるので。
package examples.dao; import java.sql.Connection; import java.sql.SQLException; import oracle.sql.Datum; import oracle.sql.ORAData; import oracle.sql.STRUCT; import oracle.sql.StructDescriptor; public class Person implements ORAData { Integer id; String name; public Datum toDatum(Connection conn) throws SQLException { StructDescriptor sd = new StructDescriptor("PERSON", conn); STRUCT struct = new STRUCT(sd, conn, new Object[] { this.id, this.name }); return struct; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
はい、これで、引数が正常に渡せて、戻り値も正しく取れました。