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.
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.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.