2017-02-10 206 views
1

批量插入並獲取生成的密鑰時,出現錯誤。 批量插入工作正常。MyBatis useGeneratedKeys用於批量插入中的嵌套對象

對象結構:

對象1:

Long id, String name, Obj2 obj 

對象2:(OBJ2)

Long id, String value 

這兩個對象被存儲在不同的表中。

object1

id | name | object2_id (Foreign Key) 

對象2

id | value 

現在我有對象1列表插入。

的過程中會插入對象2獲得ID,並插入對象1對象2ID」(如外鍵)。

雖然插入Object2的,在Mapper.xml

插塊

情況1:

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj1s.obj2.id"> 
<!-- obj1s is name of the list --> 
    insert into object2 (value) values 
     <foreach collection="obj1s" item="obj1" separator=","> 
      (#{obj1.obj2.id}) 
     </foreach> 
</insert> 

ERROR: Error getting generated key or setting result to parameter object.

情況2:

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj1.obj2.id"> 
<!-- obj1 so as to access the object of foreach loop --> 
    insert into object2 (value) values 
     <foreach collection="obj1s" item="obj1" separator=","> 
      (#{obj1.obj2.id}) 
     </foreach> 
</insert> 

ERROR: Error getting generated key or setting result to parameter object. Cause: org.apache.ibatis.binding.BindingException: Parameter 'obj1' not found. Available parameters are [obj1s, param1]

案例3:

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj2.id"> 
<!-- obj2 is the object with variable id to store generated key --> 
    insert into object2 (value) values 
     <foreach collection="obj1s" item="obj1" separator=","> 
      (#{obj1.obj2.id}) 
     </foreach> 
</insert> 

ERROR: Error getting generated key or setting result to parameter object. Cause: org.apache.ibatis.binding.BindingException: Parameter 'obj2' not found. Available parameters are [obj1s, param1]

反正有沒有做到這一點? 也許使用selectKey,但selectkey用於不支持自動生成密鑰的DB。

使用MyBatis 3.3.1和Mysql。

+0

請澄清映射類/屬性<=>表/列 – blackwizard

+0

@blackwizard映射可以通過列名和屬性名稱計算出來。 – Shuddh

回答

6

所以,我想通了。 MyBatis有多行插入和使用生成密鑰的問題。 Bug是列表變量名稱必須是「列表」,當執行批量插入並獲取生成的密鑰時。然後相應地訪問該對象。因此,對於上述emxample代碼將是這樣的:

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj2.id"> 
<!-- obj2 is the object with variable id to store generated key --> 
insert into object2 (value) values 
    <foreach collection="list" item="obj1" separator=","> 
     (#{obj1.obj2.id}) 
    </foreach> 

和mapper.java方法的聲明看起來是這樣:

public Integer batchInsert(@Param("list")List<Obj1> obj1); 

變量的名稱必須是列表 。沒有其他的。

謝謝@blackwizard,我必須重新檢查並檢查錯誤信息,從而使我得到這個答案。

+0

你有一個鏈接到該錯誤? –

+0

看來他們是這樣設計的。我可能不得不搜索鏈接。一年前與開發者討論。 – Shuddh

0

您必須進入obj.idOBJ是屬性名,OBJ2是類型名稱。

此外,檢索生成的關鍵作品/僅適用於單個插入。 事實上:你想要插入N條記錄,但是你的代碼會生成並執行一條(巨型)語句。這不是批次。

在Java中迭代你的列表,在循環中調用簡單的插入語句(沒有更多foreach),那麼每個生成的鍵都可以綁定到匹配對象。 使用ExecutorType.REUSE打開SqlSession,以便語句只准備一次,每次迭代只發送一次參數。

我已經回答了this kind of question

+0

我只通過屬性名稱訪問。當我使用單一(巨型)語句時,我可以獲取所有行的生成鍵,但不能獲取列表的嵌套對象。 – Shuddh

+0

您說得對,我剛剛查看了文檔,使用多行插入時檢索自動生成的鍵確實是可行的。 – blackwizard

+0

我的意思是,根據你的mybatis片段,你可以訪問一個名爲_obj2_的屬性,而類定義中的屬性名是_obj_:Obj2 obj,只是一個可以解釋BindingException的錯字。 – blackwizard