MyBatis Batch Insert / Update per Oracle

Recentemente ho iniziato a imparare a usare myBatis. Ora sto affrontando un tale scenario, ho bisogno di recuperare costantemente un nuovo elenco di oggetti tramite WebService, quindi per questo elenco, ho bisogno di inserire / aggiornare ogni object nella tabella Oracle Oracle attraverso myBatis.

La parte difficile è che non posso semplicemente inserire ogni volta un batch, perché alcuni oggetti potrebbero già esistere nel DB, per questi record, ho bisogno di aggiornare i campi di essi invece di un nuovo inserimento.

La mia soluzione attuale potrebbe essere molto stupida, usare Java, compilare l’elenco di Object dal webservice, effettuare il ciclo di ciascuna di esse, selezionare myBatis, se non è un null (già presente nel db), quindi eseguire un aggiornamento myBatis; altrimenti, inserisci myBatis per questo nuovo object.

La funzione è stata raggiunta. Ma il mio responsabile tecnico dice che è molto poco efficiente, dal momento che fare un ciclo for utilizzando Java e inserire / aggiornare uno ad uno consumerà molte risorse di sistema. Mi ha consigliato di inserire in batch usando myBatis passando un elenco di oggetti in.

L’inserimento di batch in myBatis è semplice, tuttavia, poiché non sto semplicemente inserendo (per i record esistenti devo eseguire l’aggiornamento), non penso che l’inserimento batch sia appropriato qui. Ho cercato su Google un po ‘per questo, e ho realizzato che forse avrò bisogno di usare “unire” invece di “inserire” (per Oracle).

Gli esempi che ho cercato di unire in myBatis sono solo per un object, non in un batch. Quindi voglio scoprire se gli esperti potrebbero offrirmi alcuni esempi su come eseguire un batch-merge in MyBatis (il modo corretto di scrivere un Mapper)?

Anche nel mio caso c’è lo stesso scenario. Ho usato per il ciclo per verificare se questo record esiste in database o meno e quindi in base a ciò ho aggiunto questo object a due arraylist per l’inserimento o l’aggiornamento. E poi usato batch per inserire e aggiornare dopo ciclo per quello da elencare.

ecco l’ex. per l’aggiornamento in base alla diversa condizione

1] questo è per l’aggiornamento

 UPDATE parties SET attending_user_count = #{model.attending_count} WHERE fb_party_id = #{model.eid}  

2] questo è per l’inserto

  INSERT INTO accountability_users ( accountability_user_id, accountability_id, to_username, record_status, created_by, created_at, updated_by, updated_at ) VALUES  ( #{model.accountabilityUserId}, #{model.accountabilityId}, #{model.toUsername}, 'A', #{model.createdBy}, #{model.createdAt}, #{model.updatedBy}, #{model.updatedAt} )   

Nel metodo dao dichiarare come

 void insertAccountabilityUsers(@Param("usersList") List usersList); 

Aggiornare

Ecco il mio codice di sessione batch

 public static synchronized SqlSession getSqlBatchSession() { ConnectionBuilderAction connection = new ConnectionBuilderAction(); sf = connection.getConnection(); SqlSession session = sf.openSession(ExecutorType.BATCH); return session; } SqlSession session = ConnectionBuilderAction.getSqlSession(); 

In realtà ho già dato un esempio completo qui per questa domanda

La risposta accettata non è il metodo consigliato per gestire le operazioni batch. Non mostra le istruzioni batch reali poiché la modalità di esecuzione batch deve essere utilizzata durante l’apertura di una sessione. Vedere questo post in cui un contributore di codice ha raccomandato che il modo corretto per aggiornare (o inserire) batch sia quello di aprire una sessione in modalità batch e chiamare ripetutamente l’aggiornamento (o l’inserimento) per un singolo record.

Ecco cosa funziona per me:

 public void updateRecords(final List 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(); } } 

Non utilizzare foreach nell’aggiornamento / inserimento e assicurarsi che aggiorni / inserisca solo un singolo record. Stavo incorrendo in errori oracle irrisolvibili eseguendolo in base alla risposta accettata (carattere non valido, istruzione non conclusa, ecc.). Come indica il post collegato, l’aggiornamento (o l’inserimento) mostrato nella risposta accettata è in realtà solo una gigantesca istruzione sql.