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