Backend Development 7 min read

Master SpringBoot JDBC Batch Operations: Code Samples & Best Practices

This guide demonstrates how to set up a SpringBoot environment, create a MySQL table, define a JavaBean, and perform efficient batch inserts using JdbcTemplate, BatchPreparedStatementSetter, NamedParameterJdbcTemplate, SimpleJdbcInsert, and MappingSqlQuery, with complete code examples for each technique.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Master SpringBoot JDBC Batch Operations: Code Samples & Best Practices

Environment: SpringBoot 3.2.3

1. Prepare Environment

Create database table:

<code>CREATE TABLE `t_person` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `age` int(11) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;</code>

JavaBean object:

<code>public class Person {
  private Integer id;
  private Integer age;
  private String name;
  // getter, setter
}</code>

2. JDBC Batch Operations

Implement BatchPreparedStatementSetter and pass it to JdbcTemplate.batchUpdate:

<code>public int[] batchSave2(final List<Person> persons) {
  return this.jdbcTemplate.batchUpdate(
    "insert into t_person (age, name) values (?, ?)",
    new BatchPreparedStatementSetter() {
      public void setValues(PreparedStatement ps, int i) throws SQLException {
        Person p = persons.get(i);
        ps.setInt(1, p.getAge());
        ps.setString(2, p.getName());
      }
      public int getBatchSize() {
        return persons.size();
      }
    });
}</code>

Case 2: Using NamedParameterJdbcTemplate with SqlParameterSourceUtils.createBatch:

<code>public int[] batchSave(List<Person> persons) {
  NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(dataSource);
  return template.batchUpdate(
    "insert into t_person (age, name) values (:age, :name)",
    SqlParameterSourceUtils.createBatch(persons));
}</code>

Case 3: Splitting a large batch into smaller batches:

<code>public int[][] batchSave3(final Collection<Person> persons) {
  int[][] ret = jdbcTemplate.batchUpdate(
    "insert into t_person (age, name) values (?, ?)",
    persons,
    10,
    (PreparedStatement ps, Person p) -> {
      ps.setInt(1, p.getAge());
      ps.setString(2, p.getName());
    });
  return ret;
}</code>

3. SimpleJdbcInsert Batch Inserts

SimpleJdbcInsert simplifies configuration by using database metadata.

Case 1:

<code>public void saveSimpleJdbc(Person person) {
  SimpleJdbcInsert insertPerson = new SimpleJdbcInsert(dataSource)
    .withTableName("t_person");
  Map<String, Object> parameters = new HashMap<>(3);
  parameters.put("age", person.getAge());
  parameters.put("name", person.getName());
  insertPerson.execute(parameters);
}</code>

Case 2: Retrieve generated key:

<code>public Number saveSimpleJdbc2(Person person) {
  SimpleJdbcInsert insertPerson = new SimpleJdbcInsert(dataSource)
    .withTableName("t_person")
    .usingGeneratedKeyColumns("id");
  Map<String, Object> parameters = new HashMap<>(3);
  parameters.put("age", person.getAge());
  parameters.put("name", person.getName());
  Number key = insertPerson.executeAndReturnKey(parameters);
  return key;
}</code>

Case 3: Insert only specific columns:

<code>public Number saveSimpleJdbc3(Person person) {
  SimpleJdbcInsert insertPerson = new SimpleJdbcInsert(dataSource)
    .withTableName("t_person")
    .usingColumns("name")
    .usingGeneratedKeyColumns("id");
  Map<String, Object> parameters = new HashMap<>(3);
  parameters.put("name", person.getName());
  Number key = insertPerson.executeAndReturnKey(parameters);
  return key;
}</code>

Case 4: BeanPropertySqlParameterSource mapping:

<code>public Number saveSimpleJdbc4(Person person) {
  SimpleJdbcInsert insertPerson = new SimpleJdbcInsert(dataSource)
    .withTableName("t_person")
    .usingGeneratedKeyColumns("id");
  SqlParameterSource parameters = new BeanPropertySqlParameterSource(person);
  Number key = insertPerson.executeAndReturnKey(parameters);
  return key;
}</code>

Case 5: MapSqlParameterSource with explicit column mapping:

<code>public Number saveSimpleJdbc5(Person person) {
  SimpleJdbcInsert insertPerson = new SimpleJdbcInsert(dataSource)
    .withTableName("t_person")
    .usingGeneratedKeyColumns("id");
  SqlParameterSource parameters = new MapSqlParameterSource()
    .addValue("age_1", person.getAge())
    .addValue("name", person.getName());
  Number key = insertPerson.executeAndReturnKey(parameters);
  return key;
}</code>

4. Modeling JDBC Operations as Java Objects

MappingSqlQuery allows reusable queries; subclass must implement mapRow to convert each ResultSet row to an object.

<code>public class PersonMappingQuery extends MappingSqlQuery<Person> {
  public PersonMappingQuery(DataSource ds) {
    super(ds, "select * from t_person");
    compile();
  }

  @Override
  protected Person mapRow(ResultSet rs, int rowNumber) throws SQLException {
    Person person = new Person();
    person.setId(rs.getInt("id"));
    person.setAge(rs.getInt("age"));
    person.setName(rs.getString("name"));
    return person;
  }
}</code>

Usage:

<code>public void query() {
  PersonMappingQuery query = new PersonMappingQuery(dataSource);
  List<Person> persons = query.execute();
  System.out.println(persons);
}</code>

Conditional query example:

<code>public PersonMappingQuery(DataSource ds) {
  super(ds, "select * from t_person where id = ?");
  declareParameter(new SqlParameter("id", Types.INTEGER));
  compile();
}</code>
<code>public void query() {
  PersonMappingQuery query = new PersonMappingQuery(dataSource);
  System.out.println(query.findObject(2427));
}</code>

End of article.

JDBCSpringBootbatchmappingsqlquerysimplejdbcinsert
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.