2016-04-04 1 views
1

Я читаю книгу «MyBatis in Practice» и не могу понять, почему код на странице 67-68 не работает. Вот проблема. Речь идет о вызове хранимых процедур, и это работает, но реальной проблемой является то, что я не могу понять, как заполнить карту ввода с помощью набора результатов. Итак, вот код из основного класса:Как я могу заполнить карту параметров с помощью набора результатов в MyBatis

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 - это просто ПОЖАРОЧКА Java. Вот код из mapper.xml

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

После выполнения предыдущего кода, список outputData пуст, т.е. безлюдный с результатами. Это способ, предложенный в книге, но это не работает для меня? Как я могу это решить? стр. Я использую MyBatis 3.2.3

+0

У вашего оператора вызова нет какого-либо параметра с именем «petData»? –

+0

Хм ... @Florian Schaetz, это звучит разумно, но я не могу проверить его прямо сейчас, поскольку у меня нет книги со мной. Это похоже на lapsus calami в книге, так как кажется, что правильным ответом может быть resultMap = "petData" вместо resultType = "PetDVO", но я не помню, что отображение petData происходит в любом месте файла mapper? Я проверю его позже. Благодарю. –

+0

Я все равно смущен, так как вы делаете resultType, что означает, что вы ожидаете, что callReadAllPets вернет значение, но вы не получите возвращаемое значение из 'getSqlSession(). SelectList ('. Вместо этого вы, похоже, ожидаете его в объекте параметра без фактического наличия параметра OUT ... –

ответ

0

Хорошо, если вы хотите, чтобы заполнить входной параметр с параметрами из хранимой процедуры, вы могли бы сделать это так ...

<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> 

Ваш com.example.SomeRequest класс будет выглядеть следующим образом ...

class SomeRequest { 

    private Long someParameter; 
    private Long out; 

    // add Getters & Setters 

} 

Это позволит вам извлечь (Long) результат с переменной SomeRequest.out. Чтобы отобразить более сложный результат, вам нужно будет определить их как ResultSet и поставить ResultMap, например ...

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

По крайней мере, это то, как мы делаем это с функциями базы данных и пакетов Oracle. Надеюсь, он также работает с хранимыми процедурами MySql таким же образом ...

0

Спасибо за ваш ответ, но я использую H2. В H2 нет хранимых процедур, только хранимые функции, которые на самом деле являются обычными java-методами. В этом случае сохраненная функция возвращает ResultSet и вызывает эту функцию напрямую с запросом 'SELECT name, owner, species, sex, birth, death FROM pet', который дает правильный результат. Итак, я считаю, что MyBatis знает о сгенерированном ResultSet, но не может вернуть его в inputMap. Чтобы прояснить эту проблему, я сделаю две вещи. Во-первых, я собираюсь проверить, есть ли resultMap="petData" will work instead of resultType="PetDVO", поскольку petData уже является параметром inputMap. Если это не сработает, я заверяю себя, что MyBatis получает результирующий набор, используя вышеупомянутый подход List<PetDVO> outputData = getSqlSession().selectList("callReadAllPets", inputMap). К сожалению, я смогу попробовать это через несколько часов. Еще раз спасибо @Florian Schaetz.

+0

Нет, 'resultMap =" petData "' не работает. Я буду придерживаться «List outputData = getSqlSession(). SelectList (« callReadAllPets », inputMap)», поскольку это работает безупречно. –