L'utilizzo di batch executor è il metodo consigliato, ma è necessario farlo correttamente.
Due problemi che ho notato.
- L'impostazione di una dimensione batch corretta è importante. La risposta collegata invia tutti i dati alla fine che non è molto efficiente.
- Utilizzo di
${}
fare riferimento ai parametri rende ogni istruzione univoca e impedisce al driver di riutilizzare l'istruzione (il vantaggio dell'esecutore batch viene sostanzialmente perso). Vedi questa FAQ per la differenza tra#{}
e${}
.
Ecco una tipica operazione batch che utilizza MyBatis.
Come il miglior batchSize
dipende da vari fattori, dovresti misurare le prestazioni utilizzando i dati effettivi.
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();
}
Ed ecco una versione efficiente della dichiarazione di aggiornamento.
<update id="update">
UPDATE <include refid="tableName" />
SET
item_price = #{item.price},
update_time = #{item.updateTime}
WHERE id = #{item.id}
</update>