Mybatis收集呼叫程序与params

时间:2017-03-01 12:37:14

标签: collections mybatis

我想用Mybatis创建这个复杂的对象。

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

    public List<Device> deviceList;
}

前两个字段返回一个程序:

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>

特别感兴趣的问题:如何收集选择结果到达最终对象?如何建立这个对象链接?

现在结果是前两个字段成功返回。但是deviceList是空的。

1 个答案:

答案 0 :(得分:1)

设备列表为空,因为它实际上从未分配过。实际上,存储过程调用不是返回结果的选择,结果绑定到输出变量,您已经很好地理解并将其应用于'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。