2013-03-27 169 views
4

我正在將我們的數據庫從SQL Server 2008遷移到Oracle,但無法讓MyBatis工作。用MyBatis調用Oracle存儲過程

鑑於下面的例子:

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> 

UserDAO.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遊標的用戶類?

這是我的嘗試:

<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 '[email protected]' 
Cause: org.apache.ibatis.reflection.ReflectionException: 
There is no setter for property named 'resultSet' in 'class java.lang.Class' 

回答

7

結果地圖看起來是這樣的:

<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")); 
} 
+0

謝謝clav。我嘗試了你的例子,並得到了與上面第2行相同的錯誤:「無法設置'class java.lang.Class'的屬性'resultSet'。」有任何想法嗎? – snoozy 2013-03-27 20:37:58

+0

我不記得確切的語法。我感覺你對這件事感到痛苦,因爲我大約一年前經歷過這件事。我追蹤了一些我保留的示例代碼,並更新了我的答案,試試看。 – clav 2013-03-29 14:17:02

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

我也有同樣的錯誤。

Caused by: org.apache.ibatis.reflection.ReflectionException: There is no setter for property named 'columnNames' in 'class java.lang.Class'

in mapper.java getSearchResult(searchCriteriaVO vo)

in 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時,由於它爲空,所以拋出了上述錯誤。

希望這是有用的信息

1

只是一個除了CLAV的評論,Snoozy,你需要從

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

刪除ResultSet和修改成 「關鍵」 爲:

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

我希望這很有幫助。