如何从 myBatis 实现 2 个结果集

How to implement 2 Result Sets from myBatis

我正在开发一个 springboot 应用程序,其中 mybatis 正在调用一个 DB2 存储过程,这个存储过程返回 2 个结果集: 我为每个结果集定义了一个模型(Fruit.java 和 Animal.java)

结果集#1

ID NAME QTY
1 Apple 2
2 Orange 3
3 banana 5

结果集#2

TYPE NUM LOC
monkey 2000 London
dog 3000 New York
cat 8000 LA

在 MyMapper.java 中,我的 resultType 应该是什么?

我试过:

@Select(Value = "{call ....}) 
@Options(StatementType =    StatementType.CALLABLE) 
@Results({   
  @Result(property="id",  column="ID",    
  @Result(property="name", column="NAME",      
  @Result(property="qty", column="QTY" })
List<Fruit> getFruits(Map<String, String> params); 

@Select(Value = "{call ....})
@Options(StatementType = StatementType.CALLABLE)
@Results({
  @Result(property="type", column="TYPE", 
  @Result(property="num", column="NUM", 
  @Result(property="loc", column="LOC"
})
List<Animal> getAnimals(Map<String, String> params); 

没用,我确实通过这种方式得到了结果集 #1 但没有得到结果集 #2(结果集 #2 中的所有字段都返回了 null) .

我也试过:

 @Select(Value = "{call ....})
 @Options(StatementType = StatementType.CALLABLE)
 List<?> getResultSets(Map<String, String> params); 

和:

  @Select(Value = "{call ....})
  @Options(StatementType = StatementType.CALLABLE)
  List<List<?>> getResultSets(Map<String, String> params); 

我都得到了“java.lang.UnsupportedOperationException”:

Caused by: java.lang.UnsupportedOperationException
    at org.apache.ibatis.reflection.wrapper.CollectionWrapper.findProperty(CollectionWrapper.java:42)
    at org.apache.ibatis.reflection.MetaObject.findProperty(MetaObject.java:76)
    at org.apache.ibatis.executor.resultset.FastResultSetHandler.applyAutomaticMappings(FastResultSetHandler.java:342)
    at org.apache.ibatis.executor.resultset.FastResultSetHandler.getRowValue(FastResultSetHandler.java:267)
    at org.apache.ibatis.executor.resultset.FastResultSetHandler.handleRowValues(FastResultSetHandler.java:216)
    at org.apache.ibatis.executor.resultset.FastResultSetHandler.handleResultSet(FastResultSetHandler.java:188)
    at org.apache.ibatis.executor.resultset.FastResultSetHandler.handleResultSets(FastResultSetHandler.java:154)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:57)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:70)
    at org.apache.ibatis.executor.ReuseExecutor.doQuery(ReuseExecutor.java:54)
    at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:259)
    at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:132)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:105)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:81)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:104)

Google 说这是因为我应该使用具体类型而不是泛型。 但是结果集是不同类型的:List of Fruit 和 List of Animal,怎么办?

我正在使用 所有注释 而没有 xml 用于 mybatis。 在 pom.xml 我正在使用 mybatis-spring-boot-starter 如果有帮助的话。

我一直坚持这个。谢谢。

我用以下程序对此进行了测试。
它需要两个 IN 参数,returns 首先是 fruit 的结果,然后是 animal.
如果您需要我做一些调整,请告诉我。

create or replace procedure test_proc (
  in p1 varchar(20),
  in p2 varchar(20)
)
dynamic result sets 2
begin
  declare c1 cursor with return to caller for
  select * from animal;
  declare c2 cursor with return to caller for
  select * from fruit;
  open c2;
  open c1;
end

Java 映射器方法如下所示。
当您收到两个结果集时,您需要在 @ResultMap.
中指定两个结果映射 请注意顺序很重要。

@Select("{call test_proc(#{p1,mode=IN,jdbcType=VARCHAR},#{p2,mode=IN,jdbcType=VARCHAR})}")
@Options(statementType = StatementType.CALLABLE)
@ResultMap("fruitResultMap,animalResultMap")
List<List<?>> execProc(Map<String, String> params);

返回的列表包含两个列表。第一个是 List<Fruit> 第二个是 List<Animal>.

现在,要在没有 XML 映射器的情况下定义那些结果映射,您需要声明额外的方法。

@Results(id = "fruitResultMap", value = {
  @Result(property = "id", column = "ID"),
  @Result(property = "name", column = "NAME"),
  @Result(property = "qty", column = "QTY")
})
@Select("select * from fruit")
List<Fruit> getFruits();

@Results(id = "animalResultMap", value = {
  @Result(property = "type", column = "TYPE"),
  @Result(property = "num", column = "NUM"),
  @Result(property = "loc", column = "LOC")
})
@Select("select * from animal")
List<Animal> getAnimals();

这是一个可执行的演示项目:
https://github.com/harawata/mybatis-issues/tree/master/so-69145531