Stored procedures MyBatis将ResultSet上的获取大小设置为过程的out参数

Stored procedures MyBatis将ResultSet上的获取大小设置为过程的out参数,stored-procedures,resultset,mybatis,multipleoutputs,Stored Procedures,Resultset,Mybatis,Multipleoutputs,我有一个需要使用MyBatis调用的存储过程。无论如何,我设法调用了这个存储过程。过程有多个输出参数。其中一个out参数是oracle cursor。我需要在Oracle游标上迭代,但是当我在没有使用fetchSize属性对jdbc驱动程序进行任何微调的情况下执行此操作时,它会逐行进行,并且此解决方案非常缓慢。 我可以设置过程调用fethcSize属性: <select id="getEvents" statementType="CALLABLE" parameterMap="eventI

我有一个需要使用MyBatis调用的存储过程。无论如何,我设法调用了这个存储过程。过程有多个输出参数。其中一个out参数是oracle cursor。我需要在Oracle游标上迭代,但是当我在没有使用fetchSize属性对jdbc驱动程序进行任何微调的情况下执行此操作时,它会逐行进行,并且此解决方案非常缓慢。 我可以设置过程调用fethcSize属性:

<select id="getEvents" statementType="CALLABLE" parameterMap="eventInputMap" fetchSize="1000">
    {call myProc(?, ?, ?, ?, ?)}
</select>

{调用myProc(?,,,,?,?)}
但这一点都没有帮助。我认为这不起作用,因为有多个out参数,所以程序不知道该取数大小应该应用于哪个out参数。有没有办法在ResultSet(Oracle游标)上设置获取大小?就像使用java.sql包中的CallableStatemens一样,我可以设置ResultSet获取大小

以下是来自程序的映射文件和过程调用:

  <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
    PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
          "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

<mapper namespace="mypackage.EventDao">

    <resultMap id="eventResult" type="Event">
        <result property="id" column="event_id" />
        <result property="name" column="event_name" />
    </resultMap>

    <parameterMap id="eventInputMap" type="map" >
        <parameter property="pnNetworkId" jdbcType="NUMERIC" javaType="java.lang.Integer" mode="IN"/>
        <parameter property="pvUserIdentityId" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN"/>
        <parameter property="result" resultMap="eventResult" jdbcType="CURSOR" javaType="java.sql.ResultSet" mode="OUT" />
        <parameter property="success" jdbcType="INTEGER" javaType="java.lang.Integer" mode="OUT"/>
        <parameter property="message" jdbcType="VARCHAR" javaType="java.lang.String" mode="OUT"/>
    </parameterMap>



    <select id="getEvents" statementType="CALLABLE" parameterMap="eventInputMap" fetchSize="1000">
        {call myProc(?, ?, ?, ?, ?)}
    </select>
   </mapper>    
SqlSession session = sqlSessionFactory.openSession();
    Map<String, Object> eventInputMap = new HashMap<String, Object>();
        try {       
            EventDao ed = session.getMapper(EventDao.class);            
            eventInputMap.put("pnNetworkId", networkId);
            eventInputMap.put("pvUserIdentityId", identityId);          
            eventInputMap.put("success", 0);
            eventInputMap.put("message", null);         
            ed.getEvents(eventInputMap);
            session.selectList("EventDao.getEvents", eventInputMap);    
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            session.close();
        }

{调用myProc(?,,,,?,?)}
并从程序中调用:

  <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
    PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
          "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

<mapper namespace="mypackage.EventDao">

    <resultMap id="eventResult" type="Event">
        <result property="id" column="event_id" />
        <result property="name" column="event_name" />
    </resultMap>

    <parameterMap id="eventInputMap" type="map" >
        <parameter property="pnNetworkId" jdbcType="NUMERIC" javaType="java.lang.Integer" mode="IN"/>
        <parameter property="pvUserIdentityId" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN"/>
        <parameter property="result" resultMap="eventResult" jdbcType="CURSOR" javaType="java.sql.ResultSet" mode="OUT" />
        <parameter property="success" jdbcType="INTEGER" javaType="java.lang.Integer" mode="OUT"/>
        <parameter property="message" jdbcType="VARCHAR" javaType="java.lang.String" mode="OUT"/>
    </parameterMap>



    <select id="getEvents" statementType="CALLABLE" parameterMap="eventInputMap" fetchSize="1000">
        {call myProc(?, ?, ?, ?, ?)}
    </select>
   </mapper>    
SqlSession session = sqlSessionFactory.openSession();
    Map<String, Object> eventInputMap = new HashMap<String, Object>();
        try {       
            EventDao ed = session.getMapper(EventDao.class);            
            eventInputMap.put("pnNetworkId", networkId);
            eventInputMap.put("pvUserIdentityId", identityId);          
            eventInputMap.put("success", 0);
            eventInputMap.put("message", null);         
            ed.getEvents(eventInputMap);
            session.selectList("EventDao.getEvents", eventInputMap);    
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            session.close();
        }
SqlSession session=sqlSessionFactory.openSession();
Map eventInputMap=新建HashMap();
试试{
EventDao-ed=session.getMapper(EventDao.class);
eventInputMap.put(“pnNetworkId”,networkId);
eventInputMap.put(“pvUserIdentityId”,identityId);
eventInputMap.put(“成功”,0);
eventInputMap.put(“消息”,null);
ed.getEvents(eventInputMap);
session.selectList(“EventDao.getEvents”,eventInputMap);
}捕获(例外e){
e、 printStackTrace();
}最后{
session.close();
}

提前谢谢

提供的代码有效。我甚至检查了3种编写方法:比如这里有parameterMap,没有parameterMap(直接在语句中映射),通过注释,一切都正常

我过去认为fetchSize设置不会从main语句传播到OUT param resultSet,直到最近我真正测试了它。 要了解是否使用了fetch大小以及它有多大影响,结果必须包含足够多的行。当然,最差的是从应用程序到数据库的延迟,更明显的是效果。 对于我的测试,过程使用的游标返回5400行120列(但最重要的是行计数)。 为了给出一个数量级,我测量了获取时间,即从存储过程return到语句return,结果列表中填充了从游标获取的数据。然后我记录映射的第一个对象的实例,这发生在全局获取的开始附近,可能在第一次获取之后:

public static boolean firstInstance = true;

public Item() {
    if (firstInstance) {
        LOGGER.debug("Item first instance");
        firstInstance=false;
    }
}
在会话结束后,我再次登录。selectList返回

这仅用于测试目的。不要让这是你的代码。找到一个干净的方法来做这件事。

以下是一些时间,具体取决于配置的提取大小:

- fetchSize=1    => 13000 ms
- fetchSize=10   =>  5300 ms
- fetchSize=100  =>  3800 ms
- fetchSize=300  =>  3700 ms
- fetchSize=500  =>  3650 ms
- fetchSize=1000 =>  3600 ms
Oracle JDBC驱动程序默认的fetchSize为10

使用fetchSize=1进行测试可以证明使用了提供的设置

这里是100,节省了30%。除此之外,增益可以忽略不计(使用此用例和环境)

无论如何,能够知道过程执行何时完成以及结果获取何时开始将是一件有趣的事情。 不幸的是,Mybatis日志很少。我认为自定义结果处理程序可能会有所帮助,但看看org.apache.ibatis.executor.resultset.DefaultResultSetHandler类的源代码,我注意到 与允许使用自定义结果处理程序的方法handleResultSet(用于简单select语句)不同,方法handleRefCursorOutputParameter(此处用于过程输出游标)不允许使用自定义结果处理程序。然后,无需尝试传递自定义结果处理程序:它将被忽略。 我对一个解决方案感兴趣,如果有人有。但似乎需要一个进化请求