Java 用myBatis映射嵌套的Oracle游标(ResultSet)
是否可以在myBatisJava 用myBatis映射嵌套的Oracle游标(ResultSet),java,xml,oracle,jdbc,mybatis,Java,Xml,Oracle,Jdbc,Mybatis,是否可以在myBatisresultMap中映射嵌套的java.sql.ResultSet 比如说。假设我有这样定义的过程映射: <select id="selectBlog" statementType="CALLABLE"> {call getCarsByYear( #{year,jdbcType=INTEGER,mode=IN}, #{results, jdbcType=CURSOR, mode=OUT, javaT
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>
汽车型号:
public class Car {
private String name;
private List<Dealership> dealerships;
// getters & setters ...
}
public class Dealership {
private String model;
private Integer year;
// getters & setters ...
}
公车{
私有字符串名称;
私人名单经销商;
//接球手和接球手。。。
}
公共级经销商{
私有字符串模型;
私人整数年;
//接球手和接球手。。。
}
来自ibatis示例:
<parameter property="result" javaType="java.sql.ResultSet" jdbcType="ORACLECURSOR" mode="OUT"/>
参见中的示例
{调用KOMUNIKA.LP_STOCK_AREA_WAREHOUSE(?)}
{调用p#u user_public_数据(#{userId}
,#{userDataList,mode=OUT,jdbcType=CURSOR,javaType=java.sql.ResultSet,resultMap=com.test.data.UserPublicViewMapper.userDataResultMap}
,#{noOfConnections,mode=OUT,jdbcType=NUMERIC,javaType=int}
,#{noofRecommensions,mode=OUT,jdbcType=NUMERIC,javaType=int}}
我举了一个例子来说明它是如何工作的
包装型号包含两类:
public class Result {
public int start_from;
public List<Model> models;
}
public class Model {
public int a;
public String b;
}
mybatis config.xml(您必须提供数据库的URL)
此示例适用于
parameterMap
。我正在寻找resultMap
中返回的嵌套游标的解决方案。我已经尝试将jdbcype设置为CURSOR
并将javaType设置为java.sql.ResultSet
,但仍然没有成功。您可以将过程的标题添加到描述中吗?在这种情况下,我无法阅读过程,但我知道它返回值名称(aVARCHAR
)和经销商的ref\u CURSOR
(aref\u cursor
)。经销商可以返回N个结果(因此我在描述中将其映射到collection
。它是函数还是过程?my\u proc(name out varchar,deralers out ref cursor)
或my proc(name out varchar)返回sys\u refcursor
?查看他们使用的链接statementType=“CALLABLE”
和#{userDataList,mode=OUT,jdbcType=CURSOR,javaType=ResultSet,resultMap=userDataResultMap}
更新了描述,以提供有关该问题的更多信息。@Diziaq请添加过程“GetCarsByear”的PL/SQL代码。我想您只是没有在XML文件中关闭标记。可能是这样吗?我尝试了您提供的解决方案,但没有成功。经销商仍然是empty@JohnStrong,我更新了完整的答案工作示例。感谢您提供更新的示例,但我熟悉使用游标时parameterMap
和resultMap
s的典型行为。我的问题与游标中的嵌套游标何时作为输出参数返回有关。例如,该过程返回模型列的游标,其中一个返回的lumns也是一个游标,所以我们可能会返回如下内容:(NUMBER,VARCHAR,cursor)。如何让mybatis解析嵌套游标?仅供参考:我可以通过在游标列中添加typeHandler
来解析嵌套游标。但是,这需要一些手动映射工作。我宁愿找到一个允许我使用纯xml的解决方案(如果可能的话)。我已经更新了我的描述,使之符合目前的程序。也许这会让我更深入地了解我的问题。
<parameter property="result" javaType="java.sql.ResultSet" jdbcType="ORACLECURSOR" mode="OUT"/>
- javaType was specified
- jdbcType = ORACLECURSOR
<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>
<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>
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;
<?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>
<?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>
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
}
}