簡體   English   中英

MyBatis 批量插入/更新 Oracle

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM