2017-03-01 7 views
0

Mybatisでこの複雑なオブジェクトを作成します。Mybatisコレクションコールプロシージャ(アウトパラメータあり)

public class UserInfo { 
    public Integer clientId; 
    public String userName; 

    public List<Device> deviceList; 
} 

まず2つのフィールドのリターン1つの手順:

procedure getUserInfo(pClientId in number, pRes out sys_refcursor); 

第三分野(DEVICELIST)別の手順を返す:

procedure getDevices(pClientId in number, pRes out sys_refcursor); 

私のJavaコード:

SqlSession session = sqlSessionFactory.openSession(); 
mapper = session.getMapper(UserInfoMapper.class); 

Map<String, Object> params = new HashMap<String, Object>(); 
ResultSet rs = null; 
params.put("clientId", clientId); 
params.put("result", rs); 

mapper.getUserInfo(params); 

info = ((ArrayList<UserInfo>)params.get("result")).get(0); 

UserInfoMapper:

public interface UserInfoMapper { 
    void getUserInfo(Map<String, Object> params); 
} 

問題を解決するために、どのようにUserInfoMapper.xmlを記述する必要がありますか? は、今では次のようになります。

問題に特に興味を持って
<mapper namespace="UserInfoMapper"> 
    <resultMap id="UserInfoResult" type="UserInfo"> 
     <id property="clientId" column="clientId"/> 
     <result property="userName" column="userName"/> 
     <collection property="deviceList" ofType="Device" 
        column="clientId=clientId" select="getDeviceList"/> 
    </resultMap> 

    <resultMap id="DeviceListResult" type="Device"> 
     <result property="deviceName" column="DEVICE_NAME"/> 
    </resultMap> 

    <select id="getUserInfo" statementType="CALLABLE" parameterType="java.util.Map"> 
     CALL MESSAGE_SERVER.getUserInfo(
      #{clientId, mode=IN}, 
      #{result, jdbcType=CURSOR, javaType=java.sql.ResultSet, mode=OUT, resultMap=UserInfoResult}   
     ) 
    </select> 

    <select id="getDeviceList" statementType="CALLABLE" parameterType="java.util.Map" > 
     CALL MESSAGE_SERVER.getDevices(
      #{clientId, mode=IN}, 
      #{result, jdbcType=CURSOR, javaType=java.sql.ResultSet, mode=OUT, resultMap=DeviceListResult}   
     ) 
    </select> 

</mapper> 

:コレクションの選択結果にどのように最終的なオブジェクトになりますか?このオブジェクトのリンクを作成するには?

最初の2つのフィールドが正常に戻るようになりました。しかし、deviceListは空です。

+0

ResultSetの宣言を忘れてしまいました。これは実装の詳細です。単に 'params.put(" result "、null);'と 'result'キーが存在する必要はないかもしれません。 ArrayListの代わりにListを使う:宣言された変数は可能な限り抽象的でなければならない。 – blackwizard

答えて

1

デバイスリストは、実際には割り当てられていないため、nullです。実際には、ストアドプロシージャコールは結果を返すselectではなく、結果は出力変数にバインドされています。あなたはよく理解しており、 'getUserInfo'にそれを適用しています。ストアドプロシージャを使用する場合は、単一のマッパーコールでは実行できません。

マッパーを変更する方法は次のとおりです。これ以上のコレクション/ネストされた選択はありません。

deviceListの結果をUserInfoオブジェクトに直接バインドすることができます。これをパラメータとして使用する必要があります。

<mapper namespace="UserInfoMapper"> 
    <resultMap id="UserInfoResult" type="UserInfo"> 
     <id property="clientId" column="clientId"/> 
     <result property="userName" column="userName"/> 
    </resultMap> 

    <resultMap id="DeviceListResult" type="Device"> 
     <result property="deviceName" column="DEVICE_NAME"/> 
    </resultMap> 

    <select id="getUserInfo" statementType="CALLABLE" parameterType="java.util.Map"> 
     CALL MESSAGE_SERVER.getUserInfo(
      #{clientId, mode=IN}, 
      #{result, jdbcType=CURSOR, javaType=java.sql.ResultSet, mode=OUT, resultMap=UserInfoResult}   
     ) 
    </select> 

    <select id="loadDeviceList" statementType="CALLABLE" parameterType="UserInfo" > 
     CALL MESSAGE_SERVER.getDevices(
      #{clientId, mode=IN}, 
      #{deviceList, jdbcType=CURSOR, javaType=java.sql.ResultSet, mode=OUT, resultMap=DeviceListResult}   
     ) 
    </select> 
</mapper> 

とJavaの終わりに、追加します。

mapper.getDeviceList(info); 

を次にinfoがDEVICELISTで満たされます。

+0

ありがとうございました、最初は私がそうしました。私はちょうどこの問題が単一のマッパーコールで解決できると思った。 – Dimanof