Zalecanym sposobem jest użycie executora wsadowego, ale musisz to zrobić poprawnie.
Zauważyłem dwa problemy.
- Ważne jest ustawienie odpowiedniej wielkości partii. odpowiedź połączona wysyła wszystkie dane na końcu, co nie jest zbyt wydajne.
- Korzystanie z
${}
to reference parameters sprawia, że każda instrukcja jest unikatowa i uniemożliwia sterownikowi ponowne użycie instrukcji (w zasadzie korzyść z wykonywania wsadowego jest tracona). Zobacz to najczęściej zadawane pytania dla różnicy między#{}
i${}
.
Oto typowa operacja wsadowa przy użyciu MyBatis.
Jako najlepszy batchSize
zależy od różnych czynników, powinieneś zmierzyć wydajność przy użyciu rzeczywistych danych.
int batchSize = 1000;
try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
YourMapper mapper = sqlSession.getMapper(YourMapper.class);
int size = list.size();
for (int i = 0; i < size;) {
mapper.update(list.get(i));
i++;
if (i % batchSize == 0 || i == size) {
sqlSession.flushStatements();
sqlSession.clearCache();
}
}
sqlSession.commit();
}
A oto wydajna wersja oświadczenia o aktualizacji.
<update id="update">
UPDATE <include refid="tableName" />
SET
item_price = #{item.price},
update_time = #{item.updateTime}
WHERE id = #{item.id}
</update>