一、问题描述
a) 目前调用读的存储过程的接口定义一般是:void ReadDatalogs(Map<String,Object> map);,入参和出参都在这个map里面,这样用起来就很麻烦,我希望的是可以定义成:list<TimeData> ReadDataLogs(int stationId, int deviceId, Date startTime, Date endTime);
二、已经尝试的方法
a) 改变入参的传递方式:
i. 改变入参的传递方式: void ReadDatalogs(int stationId, int deviceId, int dataId, Date startTime, Date endTime, List<TimeData> datas);
ii. 改变映射文件:
<select id="ReadDatalogs" statementType="CALLABLE" parameterType="java.lang.Object">
{call readdatalogs(#{0,mode=IN},#{1,mode=IN},#{2,mode=IN},#{3,mode=IN},#{4,mode=IN}, #{5, mode=OUT,jdbcType=OTHER,javaType=ResultSet, resultMap=LogTimeData})}
</select>
iii. 这种方式,通过Postgresql的调试跟踪,可以发现,入参是传递成功了,但是通过单元测试可以发现,结果集没有返回回来。
b) 调用存储过程的时候使用返回值,既然第一种方法已经可以正确传递入参了,那么剩下的就是如何获取返回值的问题了,通过文章(http://www.faceye.net/search/186828.html)的提醒,可以考虑使用如下方式来接收返回值:
i. 修改mapper接口如下:
List<TimeData> datas ReadDatalogs(int stationId, int deviceId, int dataId, Date startTime, Date endTime);
ii. 修改映射文件如下:
<select id="ReadDatalogs" statementType="CALLABLE" parameterType="java.lang.Object">
{ #{mm, mode=OUT,jdbcType=OTHER,javaType=ResultSet, resultMap=LogTimeData}=call readdatalogs(#{0,mode=IN},#{1,mode=IN},#{2,mode=IN},#{3,mode=IN},#{4,mode=IN})}
</select>
iii. 测试结果也是不行,程序没有报错,但是接收不到结果集。
c) 改用一个对象来作为入参:
i. 定义一个pojo类,如下:
public class DataLogQueryParam {
public DataLogQueryParam() {
// TODO Auto-generated constructor stub
}
public DataLogQueryParam(int stationId, int deviceId, int dataId, Date startTime, Date endTime) {
this.stationId = stationId;
this.deviceId = deviceId;
this.dataId = dataId;
this.startTime = startTime;
this.endTime = endTime;
list = new LinkedList<TimeData>();
}
int stationId;
int deviceId;
int dataId;
Date startTime;
Date endTime;
List<TimeData> list;
…
//geter, setter
}
ii. 修改map接口定义如下:void ReadDatalogs(DataLogQueryParam param);
iii. 修改映射文件如下:
<select id="ReadDatalogs" statementType="CALLABLE" parameterType="com.huajie.persistence.pojo.DataLogQueryParam">
{call readdatalogs(#{stationId,mode=IN},#{deviceId,mode=IN},#{dataId,mode=IN},#{startTime,mode=IN},#{endTime,mode=IN},#{list, mode=OUT,jdbcType=OTHER,javaType=ResultSet, resultMap=LogTimeData})}
</select>
iv. 这种方式可以调用成功,并且结果可以正确的存储到param.list成员中。
三、可能还可以尝试的方法
a) 由于实验的时候比较匆忙,难免出错,所以可以考虑把以上的第一种和第二种方法再尝试一遍。
b) 参考https://m.oschina.net/blog/267432 , https://github.com/miemiedev/mybatis-callable ,自己写一个mybatis的插件,当然,这里的前提是要看懂这个插件的实现
c) 结合mybatis的源码来进行调试,分析可能的问题原因,这个可以等周末有空了再来调整。
四、分析
起始在上面的方法中,我感觉第一种、第二种从语法上来说都应该行得通的,但是实验结果却是又不行。