6

我正在将我们的数据库从 SQL Server 2008 迁移到 Oracle,但无法让 MyBatis 工作。

给定以下示例:

UserMapper.xml(示例)

<resultMap type="User" id="UserResult">
    <id property="userId" column="userId"/>
    <result property="firstName" column="firstName"/>
    <result property="lastName" column="lastName"/>
</resultMap>

<select id="getUsers" statementType="CALLABLE" resultMap="UserResult">
    {CALL GetUsers()}
</select>

用户DAO.java

public interface UserDAO {
    public List<User> getUsers();
}

SQL Server 过程

CREATE PROCEDURE [dbo].[GetUsers]
AS
BEGIN
    SET NOCOUNT ON;
    SELECT userId, firstName, lastName
    FROM Users
END

...在 SQL Server 2008 中工作。有人可以向我解释如何从 UserMapper.xml 调用 Oracle 过程(与上面的 SQL Server 过程具有相同的名称和列)并使用 Oracle 游标填充我的 User 类?

这是我尝试过的:

<resultMap type="User" id="UserResult">
    <id property="userId" column="userId"/>
    <result property="firstName" column="firstName"/>
    <result property="lastName" column="lastName"/>
</resultMap>

<select id="getUsers" statementType="CALLABLE" resultMap="UserResult">
    {CALL GetUsers(#{resultSet,mode=OUT,jdbcType=CURSOR,resultMap=UserResult})}
</select>

我得到这个错误:

Caused by: org.apache.ibatis.reflection.ReflectionException: 
Could not set property 'resultSet' of 'class java.lang.Class'
with value 'oracle.jdbc.driver.OracleResultSetImpl@476d05dc' 
Cause: org.apache.ibatis.reflection.ReflectionException: 
There is no setter for property named 'resultSet' in 'class java.lang.Class'
4

4 回答 4

9

结果映射如下所示:

<resultMap id="UserResult" type="User">
    <id property="userId" column="userId"/>
    <result property="firstName" column="firstName"/>
    <result property="lastName" column="lastName"/>     
</resultMap>

在您的 select 语句中,将参数类型更改为 java.util.Map。

<select id="getUsers" statementType="CALLABLE" parameterType="java.util.Map"> 
    {call GetUsers(#{users, jdbcType=CURSOR, javaType=java.sql.ResultSet, mode=OUT, resultMap=UserResult})} 
</select>

您的映射器界面看起来像这样,看起来您当前正在将其称为 DAO。我过去的做法是制作一个映射器接口,该接口被注入到 DAO 中,而 DAO 就是调用映射器上的方法。这是一个示例映射器接口:

public interface UserMapper {
    public Object getUsers(Map<String, Object> params);
}

然后,该映射器类将被注入 DAO 类并进行如下调用:

public List<User> getUsers() {
    Map<String, Object> params = new HashMap<String, Object>(); 
    ResultSet rs = null;
    params.put("users", rs);
    userMapper.getUsers(params);
    return ((ArrayList<User>)params.get("users"));
}
于 2013-03-27T18:54:07.447 回答
1

使用 MyBatis/iBATIS 3 从 Oracle 11 获取结果集是一个非常奇怪的过程。这对我来说毫无意义,但它奏效了。我的例子是不同的,但你会明白的:

create or replace 
PROCEDURE SP_GET_ALL_STORED_PROC (l_cursor out SYS_REFCURSOR) IS
BEGIN
open l_cursor for select account_id, totalLegs, born, weight, mammal, animal from copybittest;
END SP_GET_ALL_STORED_PROC;

Map map = new HashMap();
session.selectList("ibatis_3_test.selectProductAllOracleStoredProc", map); 
List productList = (List) map.get("key");

<resultMap id="productResultMap" type="test.Product">
</resultMap>

<select id="selectProductAllOracleStoredProc" parameterType="java.util.Map" statementType="CALLABLE">
    {call SP_GET_ALL_STORED_PROC(#{key, jdbcType=CURSOR, mode=OUT, javaType=java.sql.ResultSet,resultMap=productResultMap})}
</select>
于 2013-06-06T10:59:10.547 回答
1

只是对 clav 注释的补充,Snoozy,您需要从中删除 resultSet

<select id="getUsers" statementType="CALLABLE" resultMap="UserResult">
    {CALL GetUsers(#    {resultSet,mode=OUT,jdbcType=CURSOR,resultMap=UserResult})}

并将其更改为“key”,如下所示:

<select id="getUsers" statementType="CALLABLE" resultMap="UserResult">
    {CALL GetUsers(#{key,mode=OUT,jdbcType=CURSOR,resultMap=UserResult})}
</select>

我希望这会有所帮助。

于 2017-01-13T19:37:18.190 回答
0

我也遇到了同样的错误。

原因:org.apache.ibatis.reflection.ReflectionException:“class java.lang.Class”中没有名为“columnNames”的属性的设置器

在 mapper.java 中 getSearchResult(searchCriteriaVO vo)

在 mapper.xml 中

  #{userId, mode=IN, jdbcType=VARCHAR},
    #{resultList, mode=OUT, jdbcType=CURSOR, javaType=ResultSet,  resultMap=inquiryResult},

其中inquiryResult 定义为

<resultMap type="java.util.LinkedHashMap" id="inquiryResult">
<result property="name" jdbcType="VARCHAR" javaType="String" column="name"/>

挣扎了一天 但是我调试的时候,是我犯了一个简单的错误。我的值对象作为 null 传递给我的映射器类。即使我的 VO 为空,查询也会被执行,因为 mybatis 将值传递为空。但是当 mybatis 尝试将结果设置为我的 VO 时,由于它为 null,因此抛出了上述错误。

希望这是有用的信息

于 2016-05-02T07:58:16.517 回答