2015-11-05 5 views
3

Возможно ли сопоставить вложенный java.sql.ResultSet в myBatis resultMap?Сопоставление вложенного Oracle CURSOR (ResultSet) с myBatis

Например. Скажем, что у меня есть сопоставление процедур, определенное так:

<select id="selectBlog" statementType="CALLABLE"> 
     {call getCarsByYear(
      #{year,jdbcType=INTEGER,mode=IN}, 
      #{results, jdbcType=CURSOR, mode=OUT, javaType=java.sql.ResultSet, jdbcType=CURSOR, resultMap=cars} 
     )} 
    </select> 

И мой картограф. которая возвращает список объектов автомобиля, но и список дилеров (вложенная CURSOR):

<resultMap id="cars" type="some.package.Car"> 
    <result property="name" column="car_name"> 
    <!-- here is my problem --> 
    <collection property="dealerships" column="dealerships_rf" ofType="some.package.Dealership"> 
     <result property="model" column="model" /> 
     <result property="year" column="year" /> 
</resultMap> 

<!-- dealership resultMap of type some.package.Dealership --> 

Проблема здесь в том, когда я осмотреть полученный объект Java dealerships является пустой список.

Я написал простой простой java.sql код JDBC, и он отлично работал. Кани кто-нибудь посадил меня на правильный путь? Я полностью потерял это.

Заранее спасибо.

Вот ожидаемый результат SQL:

Car 
|name |dealerships| 
|nissan|ref_cursor| 

Dealership 
|location  |established|.... 
|....   |1974  |... 

Автомобили Модель:

public class Car { 

private String name; 
private List<Dealership> dealerships; 

// getters & setters ... 

} 

public class Dealership { 

    private String model; 
    private Integer year; 

    // getters & setters ... 
} 
+0

обновлено описание, чтобы получить немного больше информации по этой проблеме. @diziaq – JohnStrong

+0

Пожалуйста, добавьте код процедуры PL/SQL 'getCarsByYear'. – diziaq

ответ

7

Я привел пример, чтобы показать, как это работает.

модели пакет содержит два класса:

public class Result { 
    public int start_from;  
    public List<Model> models; 
} 

public class Model { 
    public int a; 
    public String b; 
} 

хранимую процедуру

CREATE OR REPLACE PROCEDURE get_data(p_start IN NUMBER 
            , p_cur OUT SYS_REFCURSOR) 
IS 
BEGIN 

    OPEN p_cur FOR 
    SELECT p_start a,'abc' b FROM dual 
      UNION ALL 
    SELECT p_start + 1,'cde' FROM dual 
      UNION ALL 
    SELECT p_start + 2,'xyz' FROM dual; 

END; 

mybatis-config.xml (вы должны предоставить URL для базы данных)

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> 
<configuration> 
    <environments default="development"> 
    <environment id="development"> 
     <transactionManager type="JDBC"/> 
     <dataSource type="POOLED"> 
     <property name="driver" value="oracle.jdbc.OracleDriver"/> 
     <property name="url" value="${set_the_url}"/> 
     </dataSource> 
    </environment> 
    </environments> 

    <mappers> 
    <mapper resource="mybatis-mapper.xml"/> 
    </mappers> 
</configuration> 

mybatis-mapper.xml

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 

    <resultMap id="map_res_4" type="models.Model"> 
    <result property="a" column="a"/> 
    <result property="b" column="b"/> 
    </resultMap> 

    <parameterMap id="map_par_4" type="models.Result"> 
    <parameter property="start_from" jdbcType="INTEGER" mode="IN" /> 
    <parameter property="models" jdbcType="CURSOR" mode="OUT" resultMap="map_res_4" /> 
    </parameterMap> 

    <select id="select_4" parameterMap="map_par_4" statementType="CALLABLE"> 
    {CALL get_data(?, ?)} 
    </select> 

</mapper> 

И образец вызова процедуры get_data с mybatis:

Вы должны заметить, что метод selectOne возвращает нуль, поскольку мы выполняем вызываемое заявление.Все взаимодействие с вызовом процедуры идет с использованием второго параметра: мы проходим start_from и получаем models в качестве полей объекта Result (MyBatis может получить и установить их через отражение). Таким образом, объект Result является таким же до и после вызова метода: вы даже можете сделать поля частными (здесь я оставил их общедоступными, чтобы сократить код).

import models.Result; 
import org.apache.ibatis.io.Resources; 
import org.apache.ibatis.session.SqlSession; 
import org.apache.ibatis.session.SqlSessionFactory; 
import org.apache.ibatis.session.SqlSessionFactoryBuilder; 

import java.io.IOException; 
import java.io.Reader; 

/** 
* 
*/ 
public class Main { 
    private static SqlSessionFactory sessionFactory = null; 
    private static String CONFIGURATION_FILE = "mybatis-config.xml"; 

    static { 
     try { 
      Reader reader = Resources.getResourceAsReader(CONFIGURATION_FILE); 
      sessionFactory = new SqlSessionFactoryBuilder().build(reader); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String... args) { 

     SqlSession session = sessionFactory.openSession(); 

     Result res = new Result(); 

     res.start_from = 5; 

     Object obj = session.selectOne("select_4", res); 

     // `obj` must be NULL 
     // `res` contains all the results of Oracle procedure call 
    } 
} 
+0

Я пробовал решение, которое вы предлагали без везения. дилеры по-прежнему пустые – JohnStrong

+0

@JohnStrong, я обновил ответ с полным рабочим примером. – diziaq

+0

Благодарим вас за обновленный пример, но я знаком с типичным поведением 'parameterMap' и' resultMap's при использовании курсоров. Моя проблема связана с тем, когда у вас есть вложенный курсор внутри курсора, возвращаемого в качестве параметра OUT. например Процедура возвращает курсор столбцов модели, где один из возвращенных столбцов также является курсором. Таким образом, мы могли бы вернуть что-то вроде этого: (NUMBER, VARCHAR, CURSOR). Как заставить mybatis анализировать вложенный курсор? – JohnStrong

2

из примеров Ibatis:

<parameter property="result" javaType="java.sql.ResultSet" jdbcType="ORACLECURSOR" mode="OUT"/> 

разница от вас код:

- javaType was specified 
- jdbcType = ORACLECURSOR 

увидеть примеры из iBatis Oracle REF CURSOR

<sqlMap namespace="KOMUNIKA_REPORT"> 
    <resultMap id="BaseResultMap" class="javaapplication4.StockAreaAndWarehouse" > 
    <result column="PRODUCT_CODE" property="productCode" /> 
    <result column="PRODUCT_NAME" property="productName" /> 
    <result column="INCOMING" property="incoming" /> 
    <result column="UNIT_SOLD" property="unitSold" /> 
    <result column="TOTAL_STOCK" property="totalStock" /> 
    </resultMap> 
    <parameterMap id="resultMap" class="java.util.Map"> 
    <parameter property="result" javaType="java.sql.ResultSet" jdbcType="ORACLECURSOR" mode="OUT"/> 
    </parameterMap> 
    <procedure id="selectStockAreaAndWarehouse" 
    parameterMap="resultMap" 
    resultMap="BaseResultMap" 
    > 
    { call KOMUNIKA.LP_STOCK_AREA_WAREHOUSE(?) } 
    </procedure> 
    </sqlMap> 

example for ResultSet

<resultMap id="userDataResultMap" type="TestUserData"> 
<id property="userid" column="userid" /> 
<result property="firstName" column="firstName"/> 
<result property="lastName" column="lastName"/> 
<result property="zip" column="zip"/> 
<result property="summary" column="summary"/> 
<result property="specialities" column="specialities"/> 
<result property="isActive" column="isActive"/> 
<result property="country" column="country"/> 
<result property="platform" column="platforms"/> 
</resultMap> 
<select id="getFullPublicData" statementType="CALLABLE" parameterType="User" > 
{call p_user_public_data(#{userId} 
,#{userDataList,mode=OUT,jdbcType=CURSOR,javaType=java.sql.ResultSet, resultMap=com.test.data.UserPublicViewMapper.userDataResultMap} 
,#{noOfConnections,mode=OUT,jdbcType=NUMERIC,javaType=int} 
,#{noOfRecommendations,mode=OUT,jdbcType=NUMERIC,javaType=int})} 
</select> 
+0

этот пример для параметра parameterMap. Я ищу решение для вложенного курсора, возвращаемого в 'resultMap'. Я попытался установить jdbcType на 'CURSOR' и javaType на' java.sql.ResultSet', все равно не повезло. – JohnStrong

+0

можете ли вы добавить заголовок своей процедуры в описание? – are

+0

хорошо, для этого случая я не могу прочитать процедуру, но я знаю, что она возвращает имя 'ref_cursor' значений (' VARCHAR') и дилеров ('ref_cursor'). Дилеры могут возвращать N результатов (следовательно, почему я сопоставляю их с 'collection' в моем описании. – JohnStrong

Смежные вопросы