Spring Data JDBC persists objects in a relational database through repository interfaces. Instead of writing the JDBC operations that save an order, its tacos, and their ingredient references, you define repository interfaces; Spring Data creates their implementations at runtime. This is especially helpful for nested objects that take several inserts to save by hand. section 3.1.4 section 3.2
To use it in a Spring Boot application:
- Add the Spring Data JDBC starter to pom.xml. It replaces the JDBC starter used for JdbcTemplate, but you still need a database dependency such as H2. section 3.2.1
- Define repository interfaces for the objects you need to persist. An order controller can receive an OrderRepository through its constructor and call save() when an order is submitted. section 3.1.4 section 3.2
- Mark each domain object's identity property with @Id. Use @Table only when you need to specify a table name, and @Column when a property needs an explicit column name. section 3.2.3
Listing 3.12 Adding the Spring Data JDBC dependency to the build
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jdbc</artifactId> </dependency>
The Maven dependency that adds Spring Data JDBC to a Spring Boot application. section 3.2.1
Mapping an order
An @Id field identifies a TacoOrder. Without an explicit table name, TacoOrder maps to Taco_Order; deliveryName maps to delivery_name. @Table("Taco_Cloud_Order") changes the table name, while @Column("customer_name") changes the column used for deliveryName. IngredientRef needs no @Id because its table has no identity column. section 3.2.3
To preload ingredients, declare a CommandLineRunner bean that receives an IngredientRepository and calls save() for each ingredient. Its run() method executes after the application context and its beans are wired. A data.sql file remains another option for a relational database. section 3.2.4
@Bean
public CommandLineRunner dataLoader(IngredientRepository repo) {
return args -> {
repo.save(new Ingredient("FLTO", "Flour Tortilla", Type.WRAP));
repo.save(new Ingredient("COTO", "Corn Tortilla", Type.WRAP));
repo.save(new Ingredient("GRBF", "Ground Beef", Type.PROTEIN));
repo.save(new Ingredient("CARN", "Carnitas", Type.PROTEIN));
repo.save(new Ingredient("TMTO", "Diced Tomatoes", Type.VEGGIES));
repo.save(new Ingredient("LETC", "Lettuce", Type.VEGGIES));
repo.save(new Ingredient("CHED", "Cheddar", Type.CHEESE));
repo.save(new Ingredient("JACK", "Monterrey Jack", Type.CHEESE));
repo.save(new Ingredient("SLSA", "Salsa", Type.SAUCE));
repo.save(new Ingredient("SRCR", "Sour Cream", Type.SAUCE));
};
}
A complete CommandLineRunner example that saves taco ingredients through an injected repository at startup. section 3.2.4
For a custom query method, add @Query containing SQL. Unlike Spring Data JPA, Spring Data JDBC does not infer a custom query from the method name. section 3.3.4


