是否可以在 myBatis resultMap 中映射一个嵌套的 java.sql.ResultSet

例如。假设我有一个这样定义的过程映射:

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

请您参考如下方法:

我做了一个例子来展示它是如何工作的。

包模型包含两个类:

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> 

以及mybatis调用get_data过程的例子:

您会注意到 selectOne 方法返回 null,因为我们执行了一个可调用语句。所有与过程调用的交互都使用第二个参数:我们传递 start_from 并接收 models 作为 Result 对象的字段(MyBatis 可以通过反射获取和设置它们)。所以 Result 对象在方法调用之前和之后是相同的:您甚至可以将这些字段设为私有(private)(这里我将它们设为公开以使代码更短)。

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


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!