Skip to content

Commit

Permalink
introduce batch insert
Browse files Browse the repository at this point in the history
  • Loading branch information
yaroslav authored and yaroslav committed Nov 29, 2024
1 parent 4fa7989 commit 13e59d8
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 6 deletions.
19 changes: 17 additions & 2 deletions src/main/java/com/jcabi/jdbc/JdbcSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.util.Collection;
import java.util.LinkedList;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import javax.sql.DataSource;
import lombok.EqualsAndHashCode;
Expand Down Expand Up @@ -158,6 +159,8 @@ public final class JdbcSession {
*/
private final transient Collection<Object> args;

private final transient AtomicInteger batchSize;

/**
* Arguments.
*
Expand Down Expand Up @@ -196,11 +199,12 @@ public final class JdbcSession {
@SuppressWarnings("PMD.ConstructorOnlyInitializesOrCallOtherConstructors")
public JdbcSession(final DataSource src) {
this.args = new LinkedList<>();
this.batchSize = new AtomicInteger(0);
this.preparations = new LinkedList<>();
this.connection = new AtomicReference<>();
this.auto = true;
this.source = src;
this.preparations.add(new PrepareArgs(this.args));
this.preparations.add(new PrepareArgs(this.args, this.batchSize));
}

/**
Expand Down Expand Up @@ -288,7 +292,8 @@ public JdbcSession clear() {
synchronized (this.args) {
this.args.clear();
this.preparations.clear();
this.preparations.add(new PrepareArgs(this.args));
this.batchSize.set(0);
this.preparations.add(new PrepareArgs(this.args, this.batchSize));
}
return this;
}
Expand Down Expand Up @@ -368,6 +373,16 @@ public <T> T update(final Outcome<T> outcome)
);
}

public <T> T batchInsert(final Outcome<T> outcome, int batchSize)
throws SQLException {
this.batchSize.set(batchSize);
return this.run(
outcome,
new Connect.WithKeys(this.query),
Request.EXECUTE_BATCH_UPDATE
);
}

/**
* Call an SQL stored procedure.
*
Expand Down
19 changes: 16 additions & 3 deletions src/main/java/com/jcabi/jdbc/PrepareArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import java.sql.Types;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicInteger;

/**
* Prepare arguments.
Expand All @@ -48,12 +49,15 @@ final class PrepareArgs implements Preparation {
*/
private final transient Collection<Object> args;

private final AtomicInteger updateBatchSize;

/**
* Ctor.
* @param arguments Arguments
*/
PrepareArgs(final Collection<Object> arguments) {
PrepareArgs(final Collection<Object> arguments, final AtomicInteger updateBatchSize) {
this.args = Collections.unmodifiableCollection(arguments);
this.updateBatchSize = updateBatchSize;
}

@Override
Expand All @@ -64,8 +68,14 @@ final class PrepareArgs implements Preparation {
}
)
public void prepare(final PreparedStatement stmt) throws SQLException {
int pos = 1;
int argNumber = 1;
for (final Object arg : this.args) {
int pos;
if (this.updateBatchSize.get() != 0) {
pos = (argNumber - 1) % this.updateBatchSize.get() + 1;
} else {
pos = argNumber;
}
if (arg == null) {
stmt.setNull(pos, Types.NULL);
} else if (arg instanceof Long) {
Expand All @@ -85,7 +95,10 @@ public void prepare(final PreparedStatement stmt) throws SQLException {
} else {
stmt.setObject(pos, arg);
}
++pos;
if (this.updateBatchSize.get() != 0 && argNumber % this.updateBatchSize.get() == 0) {
stmt.addBatch();
}
++argNumber;
}
}
}
12 changes: 12 additions & 0 deletions src/main/java/com/jcabi/jdbc/Request.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ public ResultSet fetch(final PreparedStatement stmt)
}
};

/**
* Execute update.
*/
Request EXECUTE_BATCH_UPDATE = new Request() {
@Override
public ResultSet fetch(final PreparedStatement stmt)
throws SQLException {
stmt.executeBatch();
return stmt.getGeneratedKeys();
}
};

/**
* Execute query.
*/
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/jcabi/jdbc/UpdateBatch.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.jcabi.jdbc;

public interface UpdateBatch {
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
* @since 0.1
*/
@Testcontainers(disabledWithoutDocker = true)
final class JdbcSessionITCase {
final class JdbcSessionITTest {

/**
* The database container.
Expand All @@ -60,6 +60,32 @@ final class JdbcSessionITCase {
private final JdbcDatabaseContainer<?> container =
new PostgreSQLContainer<>("postgres:9.6.12");

@Test
void batchInsert() throws Exception {
final DataSource source = this.source();
new JdbcSession(source)
.sql("CREATE TABLE IF NOT EXISTS transactions (type VARCHAR(4), amount INTEGER)")
.execute()
.sql("INSERT INTO transactions (type, amount) VALUES (?, ?)")
.set("buy").set(42)
.set("sell").set(5)
.set("sell").set(12)
.set("sell").set(345)
.set("buy").set(1)
.set("sell").set(324)
.set("buy").set(42)
.set("buy").set(8)
.batchInsert(Outcome.NOT_EMPTY, 2);
MatcherAssert.assertThat(
new JdbcSession(source)
.sql("SELECT SUM(amount) FROM transactions")
.select(new SingleOutcome<>(Long.class)),
Matchers.equalTo(
42L + 5 + 12 + 345 + 1 + 324 + 42 + 8
)
);
}

/**
* JdbcSession can do PostgreSQL manipulations.
*
Expand Down

0 comments on commit 13e59d8

Please sign in to comment.