[英]MyBatis Batch Insert/Update For Oracle
最近開始學習使用myBatis,現在面臨這樣的場景,需要不斷的通過WebService獲取一個新的Object列表,然后對於這個列表,我需要通過插入/更新每個對象到oracle DB表我的Batis。
棘手的部分是,我不能每次都簡單地進行批量插入,因為某些對象可能已經存在於 DB 中,對於這些記錄,我需要更新它們的字段而不是新的插入。
我目前的解決方案可能很愚蠢,使用Java,從webservice 構建Object 列表,循環遍歷每個對象,做一個myBatis select,如果它不是null(已經存在於db 中),然后做一個myBatis 更新; 否則,為這個新對象做一個 myBatis 插入。
功能實現了。 但是我的技術負責人說它非常低效率,因為使用Java進行for循環並逐個插入/更新會消耗大量系統資源。 他建議我通過傳入對象列表來使用 myBatis 進行批量插入。
myBatis 中的批量插入很簡單,但是,由於我不是純粹的插入(對於我需要更新的現有記錄),我認為這里不適合批量插入。 我為此搜索了一段時間,並意識到我可能需要使用“合並”而不是“插入”(對於 Oracle)。
我在 myBatis 中搜索合並的示例僅適用於一個對象,而不是批處理。 因此我想知道專家是否可以提供一些關於如何在 MyBatis 中進行批量合並的示例(編寫 Mapper 的正確方法)?
接受的答案不是處理批處理操作的推薦方式。 它不顯示真正的批處理語句,因為在打開會話時應使用批處理執行程序模式。 請參閱此帖子,其中代碼貢獻者建議批量更新(或插入)的正確方法是以批處理模式打開會話並重復調用單個記錄的更新(或插入)。
以下是對我有用的內容:
public void updateRecords(final List<GisObject> objectsToUpdate) {
final SqlSession sqlSession = MyBatisUtils.getSqlSessionFactory().openSession(ExecutorType.BATCH);
try {
final GisObjectMapper mapper = sqlSession.getMapper(GisObjectMapper.class);
for (final GisObject gisObject : objectsToUpdate) {
mapper.updateRecord(gisObject);
}
sqlSession.commit();
} finally {
sqlSession.close();
}
}
不要在更新/插入中使用 foreach 並確保它只更新/插入一條記錄。 根據接受的答案(無效字符、語句未結束等)執行此操作,我遇到了無法解決的 oracle 錯誤。 正如鏈接的帖子所示,已接受的答案中顯示的更新(或插入)實際上只是一個巨大的 sql 語句。
就我而言,也有相同的情況。 我使用 for 循環來檢查此記錄是否存在於數據庫中,然后根據我將此對象添加到兩個數組列表中以進行插入或更新。 然后在 for 循環后使用批處理進行插入和更新,以便列出。
這是前。 根據不同的where條件進行更新
1]這是為了更新
<foreach collection="attendingUsrList" item="model" separator=";">
UPDATE parties SET attending_user_count = #{model.attending_count}
WHERE fb_party_id = #{model.eid}
</foreach>
2]這是用於插入
<insert id="insertAccountabilityUsers" parameterType="AccountabilityUsersModel" useGeneratedKeys="false">
INSERT INTO accountability_users
(
accountability_user_id, accountability_id, to_username,
record_status, created_by, created_at, updated_by, updated_at
)
VALUES
<foreach collection="usersList" item="model" separator=",">
(
#{model.accountabilityUserId}, #{model.accountabilityId}, #{model.toUsername},
'A', #{model.createdBy}, #{model.createdAt}, #{model.updatedBy}, #{model.updatedAt}
)
</foreach>
</insert>
在 dao 方法中聲明為
void insertAccountabilityUsers(@Param("usersList") List<AccountabilityUsersModel> usersList);
更新
這是我的批處理會話代碼
public static synchronized SqlSession getSqlBatchSession() {
ConnectionBuilderAction connection = new ConnectionBuilderAction();
sf = connection.getConnection();
SqlSession session = sf.openSession(ExecutorType.BATCH);
return session;
}
SqlSession session = ConnectionBuilderAction.getSqlSession();
在 oracle 中,如果您想一次執行多個語句,則必須將語句括在“begin”和“end”塊中。 因此,嘗試為 foreach 添加屬性,如下所示。 這肯定會奏效。
<foreach collection="customerList" item="object" open="begin" close=";end;" separator=";">
UPDATE customer SET isActive = #{object.isactive}
WHERE customerId= #{object.customerId}
</foreach>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.