web-dev-qa-db-ja.com

MyBatisを使用したOracleストアドプロシージャの呼び出し

データベースをSQLServer 2008からOracleに移行中ですが、MyBatisを機能させることができません。

次の例を考えます。

serMapper.xml(例)

<resultMap type="User" id="UserResult">
    <id property="userId" column="userId"/>
    <result property="firstName" column="firstName"/>
    <result property="lastName" column="lastName"/>
</resultMap>

<select id="getUsers" statementType="CALLABLE" resultMap="UserResult">
    {CALL GetUsers()}
</select>

serDAO.Java

public interface UserDAO {
    public List<User> getUsers();
}

SQL Serverプロシージャ

CREATE PROCEDURE [dbo].[GetUsers]
AS
BEGIN
    SET NOCOUNT ON;
    SELECT userId, firstName, lastName
    FROM Users
END

... SQL Server 2008で動作します。UserMapper.xmlからOracleプロシージャ(上記のSQL Serverプロシージャと同じ名前と列)を呼び出して、UserクラスにOracleカーソルを入力する方法を教えてください。 ?

これは私が試したものです:

<resultMap type="User" id="UserResult">
    <id property="userId" column="userId"/>
    <result property="firstName" column="firstName"/>
    <result property="lastName" column="lastName"/>
</resultMap>

<select id="getUsers" statementType="CALLABLE" resultMap="UserResult">
    {CALL GetUsers(#{resultSet,mode=OUT,jdbcType=CURSOR,resultMap=UserResult})}
</select>

そして私はこのエラーを受け取ります:

Caused by: org.Apache.ibatis.reflection.ReflectionException: 
Could not set property 'resultSet' of 'class Java.lang.Class'
with value 'Oracle.jdbc.driver.OracleResultSetImpl@476d05dc' 
Cause: org.Apache.ibatis.reflection.ReflectionException: 
There is no setter for property named 'resultSet' in 'class Java.lang.Class'
6
snoozy

結果マップは次のようになります。

<resultMap id="UserResult" type="User">
    <id property="userId" column="userId"/>
    <result property="firstName" column="firstName"/>
    <result property="lastName" column="lastName"/>     
</resultMap>

Selectステートメントで、パラメーターのタイプをJava.util.Mapに変更します。

<select id="getUsers" statementType="CALLABLE" parameterType="Java.util.Map"> 
    {call GetUsers(#{users, jdbcType=CURSOR, javaType=Java.sql.ResultSet, mode=OUT, resultMap=UserResult})} 
</select>

マッパーインターフェイスは次のようになります。現在、これをDAOと呼んでいるようです。私が過去にそれを行った方法は、DAOに注入されるマッパーインターフェイスを作成することであり、DAOはマッパーのメソッドを呼び出すものです。マッパーインターフェイスの例を次に示します。

public interface UserMapper {
    public Object getUsers(Map<String, Object> params);
}

次に、そのマッパークラスはDAOクラスに挿入され、次のように呼び出しを行います。

public List<User> getUsers() {
    Map<String, Object> params = new HashMap<String, Object>(); 
    ResultSet rs = null;
    params.put("users", rs);
    userMapper.getUsers(params);
    return ((ArrayList<User>)params.get("users"));
}
9
clav

MyBatis/iBATIS3を使用してOracle11から結果セットを取得することは、実際の奇妙なプロセスです。それは私には意味がありませんが、うまくいきました。私の例は異なりますが、次のようなアイデアが得られます。

create or replace 
PROCEDURE SP_GET_ALL_STORED_PROC (l_cursor out SYS_REFCURSOR) IS
BEGIN
open l_cursor for select account_id, totalLegs, born, weight, mammal, animal from copybittest;
END SP_GET_ALL_STORED_PROC;

Map map = new HashMap();
session.selectList("ibatis_3_test.selectProductAllOracleStoredProc", map); 
List productList = (List) map.get("key");

<resultMap id="productResultMap" type="test.Product">
</resultMap>

<select id="selectProductAllOracleStoredProc" parameterType="Java.util.Map" statementType="CALLABLE">
    {call SP_GET_ALL_STORED_PROC(#{key, jdbcType=CURSOR, mode=OUT, javaType=Java.sql.ResultSet,resultMap=productResultMap})}
</select>
1
Lund Wolfe

クラブのコメントSnoozyに加えて、resultSetをから削除する必要があります

<select id="getUsers" statementType="CALLABLE" resultMap="UserResult">
    {CALL GetUsers(#    {resultSet,mode=OUT,jdbcType=CURSOR,resultMap=UserResult})}

次のように「キー」に変更します。

<select id="getUsers" statementType="CALLABLE" resultMap="UserResult">
    {CALL GetUsers(#{key,mode=OUT,jdbcType=CURSOR,resultMap=UserResult})}
</select>

お役に立てば幸いです。

1
Rahul Mishra

私も同じエラーが発生しました。

原因:org.Apache.ibatis.reflection.ReflectionException:「クラスJava.lang.Class」に「columnNames」という名前のプロパティのセッターがありません

mapper.JavaでgetSearchResult(searchCriteriaVO vo)

mapper.xmlで

  #{userId, mode=IN, jdbcType=VARCHAR},
    #{resultList, mode=OUT, jdbcType=CURSOR, javaType=ResultSet,  resultMap=inquiryResult},

ここで、inquiryResultは次のように定義されています

<resultMap type="Java.util.LinkedHashMap" id="inquiryResult">
<result property="name" jdbcType="VARCHAR" javaType="String" column="name"/>

1日苦労しましたが、デバッグしたとき、それは私が犯した単純な間違いです。値オブジェクトがマッパークラスにnullとして渡されていました。 mybatisが値をnullとして渡すため、VOがnullであってもクエリが実行されていました。しかし、mybatisが結果を私のVOに設定しようとしたとき、それはnullであるため、上記のエラーをスローしていました。

これが役立つ情報であることを願っています

0
Christopher