001package org.itsallcode.jdbc.batch;
002
003import java.sql.PreparedStatement;
004import java.util.Objects;
005
006import org.itsallcode.jdbc.*;
007
008/**
009 * Direct batch insert using {@link PreparedStatement}. Create a new instance
010 * using {@link SimpleConnection#preparedStatementBatch()}.
011 */
012public class PreparedStatementBatch implements AutoCloseable {
013    private final Batch batch;
014    private final SimplePreparedStatement statement;
015
016    PreparedStatementBatch(final SimplePreparedStatement statement, final int maxBatchSize) {
017        this.statement = Objects.requireNonNull(statement, "statement");
018        this.batch = new Batch(maxBatchSize, statement, statement::executeBatch);
019    }
020
021    /**
022     * Add a new row to the batch.
023     * <p>
024     * <em>Important:</em> This method automatically calls
025     * {@link PreparedStatement#addBatch()}. No need to call it separately.
026     * 
027     * @param preparedStatementSetter prepared statement setter that is used for
028     *                                setting row values of the
029     *                                {@link PreparedStatement}.
030     */
031    public void add(final PreparedStatementSetter preparedStatementSetter) {
032        statement.setValues(preparedStatementSetter);
033        addBatch();
034    }
035
036    /**
037     * Get the {@link PreparedStatement} that is used for the batch insert. Use this
038     * to set values on the {@link PreparedStatement} before calling
039     * {@link #addBatch()}.
040     * <p>
041     * Use this method if you want to set values on the {@link PreparedStatement}
042     * directly and you need more control. Prefer using
043     * {@link #add(PreparedStatementSetter)} if possible.
044     * 
045     * @return the {@link PreparedStatement} used for the batch insert
046     */
047    public PreparedStatement getStatement() {
048        return statement.getStatement();
049    }
050
051    /**
052     * Add a new row to the batch. Only call this method if you have set all values
053     * on the {@link PreparedStatement} retrieved from {@link #statement}.
054     * <p>
055     * Don't call this if you use {@link #add(PreparedStatementSetter)}.
056     */
057    public void addBatch() {
058        statement.addBatch();
059        batch.addBatch();
060    }
061
062    @Override
063    public void close() {
064        batch.close();
065    }
066}