简体   繁体   English

如何在MyBatis中使用结果集填充参数映射

[英]How can I populate parameters map with result set in MyBatis

I'm reading a book "MyBatis in Practice" and can not figure why the code at page 67-68 doesn't work. 我正在读一本书“MyBatis in Practice”,但无法理解为什么第67-68页的代码不起作用。 Here is the problem. 这是问题所在。 It's about calling stored procedures and it works but the real problem is that I can not figure out how to populate input map with result set. 它是关于调用存储过程并且它可以工作,但真正的问题是我无法弄清楚如何使用结果集填充输入映射。 So here is the code from the main class: 所以这是主类的代码:

public void callReadAllPets() throws Exception {
    HashMap<String, List<PetDVO>> inputMap = new HashMap<String, List<PetDVO>>();
    List<PetDVO> petList = new ArrayList<PetDVO>();
    inputMap.put("petData", petList);
    //
    getSqlSession().selectList("callReadAllPets", inputMap);
    List<PetDVO> outputData = inputMap.get("petData");
    printResultList(outputData, "read_all_pets");
}

private void printResultList(List<PetDVO> list) {
    for (PetDVO item : list) {
        System.out.println("     owner: " + item.getOwner());
        System.out.println("   species: " + item.getSpecies());
        System.out.println("       sex: " + item.getSex());
    }
}

PetDVO is just a Java POJO. PetDVO只是Java POJO。 Here is the code from mapper.xml 这是mapper.xml中的代码

<select id="callReadAllPets" resultType="PetDVO" statementType="CALLABLE">
 CALL read_all_pets('SELECT name, owner, species, sex, birth, death FROM pet')

After running previous code, the outputData list is empty, ie unpopulated with results. 运行之前的代码后,outputData列表为空,即未填充结果。 This is the way suggested in the book but it doesn't work for me? 这是本书中建议的方式,但它对我不起作用? How can I solve this? 我怎么解决这个问题? ps I'm using MyBatis 3.2.3 ps我正在使用MyBatis 3.2.3

Ok, if you want to populate an input parameter with the OUT parameters of a stored procedure, you would do it like this... 好吧,如果你想用存储过程的OUT参数填充输入参数,你会这样做......

<mapper namespace="com.example.SomeMapper">    
    <select id="doSomething" statementType="CALLABLE" parameterType="com.example.SomeRequest">
    { call someProcedure (
        #{someParameter,javaType=Long,jdbcType=NUMERIC,mode=IN},
        #{out,javaType=Long,jdbcType=NUMERIC,mode=OUT})
    }
    </select >
</mapper>

Your com.example.SomeRequest class would look like this... 你的com.example.SomeRequest类看起来像这样......

class SomeRequest {

    private Long someParameter;
    private Long out;

    // add Getters & Setters

}

This should allow you to retrieve the (Long) result from the SomeRequest.out variable. 这应该允许您从SomeRequest.out变量中检索(长)结果。 To map more complex result, you would need to define them as ResultSet and supply the ResultMap, for example... 要映射更复杂的结果,您需要将它们定义为ResultSet并提供ResultMap,例如...

#{out,javaType=java.sql.ResultSet,jdbcType=CURSOR,resultMap=someResultMap,mode=OUT}

At least, that's how we do it with an Oracle database and package functions. 至少,这就是我们使用Oracle数据库和包函数的方式。 Hopefully, it also works with MySql stored procedures the same way... 希望它也能以同样的方式与MySql存储过程一起工作......

Thanks for your answer, but I'm using H2. 谢谢你的回答,但我正在使用H2。 There are no stored procedures in H2, only stored functions which are in fact ordinary java methods. H2中没有存储过程,只有存储函数实际上是普通的Java方法。 In this case, stored function returns ResultSet and calling this function directly with the query 'SELECT name, owner, species, sex, birth, death FROM pet' produces the correct result. 在这种情况下,存储的函数将返回ResultSet并直接使用查询'SELECT name, owner, species, sex, birth, death FROM pet'的查询直接调用此函数会产生正确的结果。 So, I believe that MyBatis is aware of a generated ResultSet but is not capable to put it back in the inputMap. 因此,我相信MyBatis知道生成的ResultSet但无法将其放回inputMap中。 To clarify this problem, I'll do two things. 为了澄清这个问题,我会做两件事。 First, I'm gonna check if resultMap="petData" will work instead of resultType="PetDVO" , as petData is already a parameter of the inputMap. 首先,我要检查resultMap="petData" will work instead of resultType="PetDVO" ,因为petData已经是inputMap的一个参数。 If that doesn't work, I'll assure myself that MyBatis is receiving the result set by using afore mentioned approach List<PetDVO> outputData = getSqlSession().selectList("callReadAllPets", inputMap) . 如果这不起作用,我将向自己保证MyBatis正在使用前面提到的方法List<PetDVO> outputData = getSqlSession().selectList("callReadAllPets", inputMap)接收结果集。 Unfortunately, I'll be able to try it a few hours later. 不幸的是,几小时后我就可以试试了。 Thanks again @Florian Schaetz. 再次感谢@Florian Schaetz。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM