如何从 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
我正在开发一个 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