JdbcTemplate: Difference between revisions
Line 83: | Line 83: | ||
===Writing Data using <tt>update()</tt>=== | ===Writing Data using <tt>update()</tt>=== | ||
This form performs the update and does not return anything. | |||
<syntaxhighlight lang='java'> | <syntaxhighlight lang='java'> | ||
Line 94: | Line 96: | ||
ingredient.getType().toString()); | ingredient.getType().toString()); | ||
return ingredient; | return ingredient; | ||
} | |||
</syntaxhighlight> | |||
There are situations, however, when inserting a row in the database triggers the generation of an ID by the database, and we may need to get a hold of that ID. For situations like these, use the update() version that accepts a <tt>PreparedStatementCreator</tt> and a <tt>KeyHolder</tt>: | |||
<syntaxhighlight lang='java'> | |||
jdbcTemplate.update( | |||
"INSERT INTO INGREDIENT (id, name, type) VALUES (?, ?, ?)", | |||
ingredient.getId(), | |||
ingredient.getName(), | |||
ingredient.getType().toString()); | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
===Writing Data using <tt>SimpleJdbcInsert</tt> Wrapper Class=== | ===Writing Data using <tt>SimpleJdbcInsert</tt> Wrapper Class=== |
Revision as of 22:43, 14 October 2018
Internal
Overview
Basic persistence with JDBC is supported by the Spring Framework with JdbcTemplate. JdbcTemplate provides the means by which developers can perform SQL operations against a relational database without the need to retort to verbose JDBC low-level API. With JdbcTemplate, the interaction with the database is reduced to specifying the query and how to map the result of the query to the domain model object.
Spring Persistence Concepts
Spring Boot Support
To add support for JdbcTemplate to a Spring Boot project, add the following starter dependency:
dependencies {
implementation('org.springframework.boot:spring-boot-starter-jdbc')
}
JdbcTemplate needs a database to work with. This is how to add H2 support:
dependencies {
runtimeOnly('com.h2database:h2')
}
JdbcTemplate-Based Repository
This is a JdbcTemplate-based concrete repository implementation that conceals from the application low-level data access details while exposing a domain model-typed API, represented by the example "IngredientRepository" interface.
@Repository
public class JdbcIngredientRepository implements IngredientRepository {
private JdbcTemplate jdbcTemplate;
@Autowired
public JdbcIngredientRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// Reading data ...
// Writing data ...
}
Reading Data
@Override
public Ingredient findOne(String id) {
return jdbcTemplate.queryForObject(
"SELECT id, name, type from INGREDIENT WHERE id=?",
this::mapRowToIngredient, id);
}
@Override
public Iterable<Ingredient> findAll() {
return jdbcTemplate.query(
"SELECT id, name, type from INGREDIENT",
this::mapRowToIngredient);
}
private Ingredient mapRowToIngredient(ResultSet rs, int rowNumber) throws SQLException {
return new Ingredient(
rs.getString("id"),
rs.getString("name"),
Ingredient.Type.valueOf(rs.getString("type")));
}
Writing Data
Writing Data using update()
This form performs the update and does not return anything.
@Override
public Ingredient save(Ingredient ingredient) {
jdbcTemplate.update(
"INSERT INTO INGREDIENT (id, name, type) VALUES (?, ?, ?)",
ingredient.getId(),
ingredient.getName(),
ingredient.getType().toString());
return ingredient;
}
There are situations, however, when inserting a row in the database triggers the generation of an ID by the database, and we may need to get a hold of that ID. For situations like these, use the update() version that accepts a PreparedStatementCreator and a KeyHolder:
jdbcTemplate.update(
"INSERT INTO INGREDIENT (id, name, type) VALUES (?, ?, ?)",
ingredient.getId(),
ingredient.getName(),
ingredient.getType().toString());
}