Search code examples
javamybatisibatis

Ibatis 2 to Mybatis 3 Conversion - Dao Files Returning Cursor Information


I am in the process of upgrading from iBatis 2 to myBatis 3.

The project contains a number of Dao files. I've noticed that some return data directly, where others return data loaded into an out parameter.

For instance,

theData = (List<SomeDataType>) getSqlMapClientTemplace().queryForList("getData", params);

vs.

getSqlMapClientTemplate().queryForList("getOtherData", params);
theData = (List<SomeOtherDataType>) params.get("out_cursor");

I think the difference is that there is no resultMap in the mapper for the one that returns data:

<parameter property="someData" 
           javaType="java.sql.ResultSet" 
           jdbcType="ORACLECURSOR" 
           mode="OUT" />

but there is one that returns it in a parameter:

<parameter property="otherData" 
           javaType="java.sql.ResultSet" 
           jdbcType="ORACLECURSOR" 
           mode="OUT"
           resultMap="getSomeOtherDataResult" />

The question is, does MyBatis3 allow for the first call type, or does everything need to be retrieved from the parameter like the second call?

In my converted Dao class, I am using my Mapper class as follows:

MyMapper mapperForSession = getSqlSession().getMapper(MyMapperClass.class);
mapperForSession.getOtherData(params);
return (List<SomeOtherDataType>) params.get("out_cursor");

Solution

  • You don't mention it but I understand the underlying SQL is actually stored procedure or stored function.

    1st statement will work for a function "select":

    SELECT * FROM theFunction(#{param1}, #{param2})
    

    And there is always a result map, it is just not mandatory to provide a custom one since Mybatis will map result set by default to a key-value map. That means mapping to a custom type will require specifying a custom result map that may be minimalist: just target type if columns names match properties, with mapUnderscoreToCamelCase setting if necessary.

    2nd way be used for procedure style calls:

    { #{outList, jdbcType=CURSOR, mode=OUT, javaType=java.sql.ResultSet, resultMap=someResultMapId} = call theFunction(#{param1}, #{param2}) }
    

    and for real procedure:

    { call theProcedure(#{inParam1}, #{inParam2}, #{outList, jdbcType=CURSOR, mode=OUT, javaType=java.sql.ResultSet, resultMap=someResultMapId}) }