对mybatis 添加 GBase 8s Ref cursor的支持

gbase 8s 目前支持游标变量类型,但与 mybatis 或 mybatis-plus 未添加对应类型枚举。

因此,简单添加对应枚举判断后,即支持游标变量。

mybatis 3.2.2 为例,修改位置如下:

添加 IFX_TYPE_CURSOR 类型

org.apache.ibatis.type.JdbcType

    NCLOB(Types.NCLOB), // JDK6
    STRUCT(Types.STRUCT),
    IFX_TYPE_CURSOR(2100);

加入IFX_TYPE_CURSOR条件 if (JdbcType.CURSOR.equals(jdbcType)|| JdbcType.IFX_TYPE_CURSOR.equals(jdbcType))

org.apache.ibatis.builder.MapperBuilderAssistant

    private Class<?> resolveParameterJavaType(Class<?> resultType, String property, Class<?> javaType, JdbcType jdbcType) {
        if (javaType == null) {
            if (JdbcType.CURSOR.equals(jdbcType)|| JdbcType.IFX_TYPE_CURSOR.equals(jdbcType)) {
                javaType = java.sql.ResultSet.class;
            } else if (Map.class.isAssignableFrom(resultType)) {
                javaType = Object.class;
            } else {
                MetaClass metaResultType = MetaClass.forClass(resultType, configuration.getReflectorFactory());
                javaType = metaResultType.getGetterType(property);
            }
        }
        if (javaType == null) {
            javaType = Object.class;
        }
        return javaType;
    }

加入IFX_TYPE_CURSOR条件 else if (JdbcType.CURSOR.name().equals(propertiesMap.get("jdbcType")) || JdbcType.IFX_TYPE_CURSOR.name().equals(propertiesMap.get("jdbcType")) )

org.apache.ibatis.builder.SqlSourceBuilder

        private ParameterMapping buildParameterMapping(String content) {
            Map<String, String> propertiesMap = this.parseParameterMapping(content);
            String property = (String)propertiesMap.get("property");
            Class propertyType;
            if (this.metaParameters.hasGetter(property)) {
                propertyType = this.metaParameters.getGetterType(property);
            } else if (this.typeHandlerRegistry.hasTypeHandler(this.parameterType)) {
                propertyType = this.parameterType;
            } else if (JdbcType.CURSOR.name().equals(propertiesMap.get("jdbcType")) || JdbcType.IFX_TYPE_CURSOR.name().equals(propertiesMap.get("jdbcType")) ) {
                propertyType = ResultSet.class;
            } else if (property != null) {
                MetaClass metaClass = MetaClass.forClass(this.parameterType);
                if (metaClass.hasGetter(property)) {
                    propertyType = metaClass.getGetterType(property);
                } else {
                    propertyType = Object.class;
                }
            } else {
                propertyType = Object.class;
            }

org.apache.ibatis.executor.resultset.FastResultSetHandler

    public List<Object> handleResultSets(Statement stmt) throws SQLException {
        final List<Object> multipleResults = new ArrayList<Object>();
        final List<ResultMap> resultMaps = mappedStatement.getResultMaps();
        int resultMapCount = resultMaps.size();
        int resultSetCount = 0;
        ResultSet rs = null;
        try {
            rs = stmt.getResultSet();

            while (rs == null) {
                // move forward to get the first resultset in case the driver
                // doesn't return the resultset as the first result (HSQLDB 2.1)
                if (stmt.getMoreResults()) {
                    rs = stmt.getResultSet();
                } else {
                    if (stmt.getUpdateCount() == -1) {
                        // no more results.  Must be no resultset
                        break;
                    }
                }
            }
        }catch (Exception e){

        }finally {
            validateResultMapsCount(rs, resultMapCount);
            while (rs != null && resultMapCount > resultSetCount) {
                final ResultMap resultMap = resultMaps.get(resultSetCount);
                ResultColumnCache resultColumnCache = new ResultColumnCache(rs.getMetaData(), configuration);
                handleResultSet(rs, resultMap, multipleResults, resultColumnCache);
                rs = getNextResultSet(stmt);
                cleanUpAfterHandlingResultSet();
                resultSetCount++;
            }
            return collapseSingleResultList(multipleResults);
        }
    }

修改完成,打包或编译后替换Class即可。网盘链接为修改过jar包。

链接:https://pan.baidu.com/s/1OGybFRIAFAtT_IMI9Xuz-Q
提取码:3mt2

测试存储过程:

create or replace procedure get_data(start_from INTEGER,models OUT sys_refcursor) 
AS
BEGIN
open models for '
select * from (select 1 a,''test'' b from dual union all select 2,''test2'' from dual)
';
end;
/

省略搭建 mybatis 项目步骤;

实体类 model

package com.gbasedbt.mybatis3demo.models;

public class Model {
    public int a;
    public String b;
}

mapper.xml 添加

    <resultMap id="map_res_4" type="com.gbasedbt.mybatis3demo.models.Model">
        <result property="a" column="A" jdbcType="INTEGER"/>
        <result property="b" column="B" jdbcType="VARCHAR"/>
    </resultMap>
    <select id="select_1" parameterType="java.util.HashMap" statementType="CALLABLE">
         {CALL get_data(#{start_from, jdbcType=INTEGER ,mode=IN},
                        #{models, jdbcType=IFX_TYPE_CURSOR ,resultMap=map_res_4 , mode=OUT})}
    </select>

Mapper 添加

 public void  select_1(HashMap result);

测试:

    @Test
    public void test2()  throws IOException {
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sf = new SqlSessionFactoryBuilder().build(inputStream);
        StudentMapper studentMapper = sf.openSession().getMapper(StudentMapper.class);

        HashMap map = new HashMap() ;
        map.put("start_from",1);
        
        studentMapper.select_1(map);
        
        List<Model> models2 = (List<Model>) map.get("models");
        
        System.out.println( models2.get(0).a+ models2.get(0).b);
        System.out.println( models2.get(1).a+ models2.get(1).b);
    }

结果:

Opening JDBC Connection
Setting autocommit to false on JDBC Connection [com.gbasedbt.jdbc.IfxSqliConnect@58c1670b]
ooo Using Connection [com.gbasedbt.jdbc.IfxSqliConnect@58c1670b]
==>  Preparing: {CALL get_data(?, ?)} 
==> Parameters: 1(Integer)
1test 
2test2
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值