salut!
Dans cet article, je parlerai briĂšvement du traitement par lots des instructions SQL (DML): INSERT, UPDATE, DELETE, comme l'un des moyens d'obtenir des performances accrues.

Avantages
Contrairement Ă l'exĂ©cution sĂ©quentielle de chaque requĂȘte SQL, le traitement par lots permet d'envoyer un ensemble complet de requĂȘtes (paquet) en un seul appel, rĂ©duisant ainsi le nombre de connexions rĂ©seau requises et permettant Ă la base de donnĂ©es d'exĂ©cuter un certain nombre de requĂȘtes en parallĂšle, ce qui peut augmenter considĂ©rablement la vitesse d'exĂ©cution. Faites immĂ©diatement une rĂ©servation afin de constater un effet notable lors de l'insertion, de la mise Ă jour ou de la suppression de grandes quantitĂ©s de donnĂ©es dans une table de base de donnĂ©es.
Table DB
Par exemple, nous utiliserons la table du livre avec les champs id et title.
1. JDBC - traitement par lots
Avant de passer aux exemples d'implémentation, il est nécessaire de souligner plusieurs points importants:
- JDBC , supportsBatchUpdates() DatabaseMetaData, , . true, .
- , setAutoCommit(false). , commit() rollback(). rollback() SQL .
- â , JDBC Statement, PreparedStatement CallableStatement, .
, Statement, PreparedStatement CallableStatement . , BATCH_SIZE. , . , , Hibernate 10 50.
, SQL INSERT. UPDATE, DELETE .
1.1. Statement
Statement book.
connection.setAutoCommit(false);
try (Statement stmt = connection.createStatement()) {
for (int i = 1; i <= SIZE; i++) {
stmt.addBatch("INSERT INTO book (title) VALUES ('" + "JDBC Insert Example: " + i + "')");
if (i % BATCH_SIZE == 0 || i == SIZE) {
try {
int[] result = stmt.executeBatch();
connection.commit();
} catch (BatchUpdateException ex) {
Log(ex);
connection.rollback();
}
}
}
}
:- C Statement;
- C void addBatch( String SQL );
- executeBatch(). executeBatch() .
Statement SQL INSERT, UPDATE, DELETE.
SQL , .
1.2. PreparedStatement
PreparedStatement book.
connection.setAutoCommit(false);
try (PreparedStatement pstmt = connection.prepareStatement("INSERT INTO book (title) VALUES (?)")) {
for (int i = 1; i <= SIZE; i++) {
pstmt.setString(1, "JDBC Insert Example: " + i);
pstmt.addBatch();
if (i % BATCH_SIZE == 0 || i == SIZE) {
try {
int[] result = pstmt.executeBatch();
connection.commit();
} catch (BatchUpdateException ex) {
Log(ex);
connection.rollback();
}
}
}
}
:- C PreparedStatement SQL ;
- , ;
- void addBatch();
- executeBatch().
3) 4) , Statement, â addBatch() .
SQL , , . , .
PreparedStatement SQL (INSERT, UPDATE, DELETE) Statement, - .
1.3. CallableStatement
CallableStatement .
, OUT INOUT.
CallableStatement book.
connection.setAutoCommit(false);
try (CallableStatement cstmt = connection.prepareCall("call insert_book(?)")) {
for (int i = 1; i <= SIZE; i++) {
cstmt.setString(1, "JDBC Insert Example: " + i);
cstmt.addBatch();
if (i % BATCH_SIZE == 0 || i == SIZE) {
try {
int[] result = cstmt.executeBatch();
connection.commit();
} catch (BatchUpdateException ex) {
Log(ex);
connection.rollback();
}
}
}
}
:- C CallableStatement ;
- , ;
- void addBatch();
- executeBatch().
, PreparedStatement.
, , .
- , .
CallableStatement , - .
1.4. BatchUpdateException
BatchUpdateException, . BatchUpdateException , SQL , - , ResultSet. BatchUpdateException ( getUpdateCounts()), , executeBatch. , SQL . , c (Statement.EXECUTE_FAILED) .
:
...
} catch (BatchUpdateException ex) {
int[] updateCount = ex.getUpdateCounts();
int count = 1;
for (int i : updateCount) {
if (i == Statement.EXECUTE_FAILED) {
System.out.println("Request " + count + ": Execute failed");
} else {
System.out.println("Request " + count + ": OK");
}
count++;
}
}
...
. , , , , . BatchUpdateException SQL , . .
2. Hibernate â
2.1.
, , hibernate.jdbc.batch_size Hibernate.cfg.xml . Hibernate SQL INSERT, UPDATE, DELETE JDBC . SQL JDBC hibernate.order_inserts, hibernate.order_updates true, Hibernate SQL . SQL , JDBC Hibernate addBatch() PreparedStatement, SQL .
Hibernate.cfg.xml
...
<property name="hibernate.jdbc.batch_size">50</property>
<property name="hibernate.order_inserts">true</property>
<property name="hibernate.order_updates">true</property>
...
2.2.
. , . , Hibernate , OutOfMemoryException. 2 :
- flush() clear() .
:
try (Session session = HibernateUtil.getSessionFactory().getCurrentSession()) {
Transaction transaction = session.getTransaction();
transaction.begin();
for (int i = 1; i <= SIZE; i++) {
session.persist(new Book("Hibernate Insert Example: " + i));
if (i % BATCH_SIZE == 0) {
session.flush();
session.clear();
}
}
transaction.commit();
}
- StatelessSession. StatelessSession . , , , (aliasing) . , Hibernate. Hibernate.
:
try (StatelessSession session = HibernateUtil.getSessionFactory().openStatelessSession()) {
Transaction transaction = session.getTransaction();
transaction.begin();
for (int i = 1; i <= SIZE; i++) {
session.persist(new Book("Hibernate Insert Example: " + i));
}
transaction.commit();
}
L'exĂ©cution par lots de requĂȘtes SQL est l'un des moyens bien connus d'amĂ©liorer les performances auquel vous devez prĂȘter attention. RĂ©duire le nombre de connexions rĂ©seau Ă la base de donnĂ©es et augmenter la vitesse d'exĂ©cution des requĂȘtes est un avantage significatif en faveur de l'utilisation du traitement par lots.
Des exemples de code peuvent ĂȘtre trouvĂ©s sur GitHub .