Spring Data JDBC是一个持久性框架,不像Spring Data JPA那么复杂。它不提供缓存,延迟加载,写后或JPA的许多其他功能。尽管如此,它有自己的ORM,并提供了我们与Spring数据JPA一起使用的大多数功能,例如映射实体,存储库,查询注释和JdbcTemplate。
要记住的一件重要事情是,春季数据JDBC不提供模式生成。因此,我们负责显式创建架构。
Spring Data JDBC可用于具有 JDBC 依赖项启动器的Spring Boot应用程序。 但是,此依赖关系启动器不会引入数据库驱动程序。该决定必须由开发人员做出。让我们为Spring Data JDBC添加依赖关系启动器:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jdbcartifactId>
dependency>
在此示例中,我们使用 H2 数据库。正如我们前面提到的,Spring Data JDBC不提供模式生成。在这种情况下,我们可以创建自定义schema.sql文件,该文件将具有用于创建架构对象的 SQL DDL 命令。Spring Boot会自动选取此文件并使用它来创建数据库对象。
与其他Spring Data项目一样,我们使用注释将POJO映射到数据库表。在Spring Data JDBC中,实体需要具有@Id。 Spring Data JDBC使用@Id注释来标识实体。
与Spring Data JPA 类似,默认情况下,Spring Data JDBC使用命名策略,将 Java 实体映射到关系数据库表,并将属性映射到列名。默认情况下,实体和属性的 Camel 事例名称分别映射到表和列的蛇形事例名称。例如,名为“AddressBook ”的 Java 实体映射到名为 address_book 的数据库表。
此外,我们可以通过使用@Table和@Column注释,将实体和属性与表和列显式映射。例如,下面我们定义了将在此示例中使用的实体:
public class Person {
@Id
private long id;
private String firstName;
private String lastName;
// constructors, getters, setters
}
我们不需要在 Person 类中使用注释@Table或@Column。Spring Data JDBC的默认命名策略会隐式地执行实体和表之间的所有映射。
Spring Data JDBC使用类似于Spring Data JPA 的语法。我们可以通过扩展Repository、CrudRepository或PagingAndSortingRepository 接口来创建 Spring Data JDBC存储库。通过实现 CrudRepository,我们可以实现最常用的方法,如save、delete和findById 等。
让我们创建一个 JDBC 存储库,我们将在示例中使用该存储库:
@Repository
public interface PersonRepository extends CrudRepository {
}
如果我们需要具有分页和排序功能,最好的选择是扩展PagingAndSortingRepository 接口。
尽管 CrudRepository具有内置方法,但我们需要为特定情况创建方法。
现在,让我们使用非修改查询和修改查询来自定义我们的PersonRepository :
@Repository
public interface PersonRepository extends CrudRepository {
List findByFirstName(String firstName);
@Modifying
@Query("UPDATE person SET first_name = :name WHERE id = :id")
boolean updateByFirstName(@Param("id") Long id, @Param("name") String name);
}
从 2.0 版本开始,弹簧数据 JDBC 支持查询方法。也就是说,如果我们命名包含关键字的查询方法,例如,findByFirstName,则Spring Data JDBC将自动生成查询对象。
但是,对于修改查询,我们使用@Modifying注释来批注修改实体的查询方法。此外,我们还使用@Query注释对其进行装饰。
在@Query注释中,我们添加了 SQL 命令。在Spring Data JDBC中,我们用普通SQL编写查询。我们不使用任何更高级别的查询语言,如 JPQL。因此,应用程序与数据库供应商紧密耦合。
因此,更改为其他数据库也变得更加困难。
我们需要记住的一件事是,Spring Data JDBC不支持引用带有索引号的参数。我们只能按名称引用参数。
最后,我们需要用数据填充数据库,这些数据将用于测试我们上面创建的Spring数据JDBC存储库。因此,我们将创建一个数据库播种器,它将插入虚拟数据。让我们为此示例添加数据库播种机的实现:
@Component
public class DatabaseSeeder {
@Autowired
private JdbcTemplate jdbcTemplate;
public void insertData() {
jdbcTemplate.execute("INSERT INTO Person(first_name,last_name) VALUES('Victor', 'Hugo')");
jdbcTemplate.execute("INSERT INTO Person(first_name,last_name) VALUES('Dante', 'Alighieri')");
jdbcTemplate.execute("INSERT INTO Person(first_name,last_name) VALUES('Stefan', 'Zweig')");
jdbcTemplate.execute("INSERT INTO Person(first_name,last_name) VALUES('Oscar', 'Wilde')");
}
}
如上所示,我们使用春季 JDBC 来执行 INSERT 语句。特别是,弹簧 JDBC 处理与数据库的连接,并允许我们使用 JdbcTemplates 执行 SQL 命令。此解决方案非常灵活,因为我们可以完全控制已执行的查询。
总而言之,Spring Data JDBC提供了一个像使用Spring JDBC一样简单的解决方案-它背后没有魔力。尽管如此,它还提供了我们习惯于使用Spring Data JPA的大多数功能。
与Spring Data JPA相比,Spring Data JDBC的最大优势之一是访问数据库时的性能有所提高。这是由于Spring Data JDBC直接与数据库通信。查询数据库时,Spring Data JDBC不包含大部分Spring Data魔术。
使用Spring Data JDBC时最大的缺点之一是对数据库供应商的依赖性。如果我们决定将数据库从MySQL更改为Oracle,我们可能不得不处理由具有不同方言的数据库引起的问题。
这个Spring Data JDBC教程的实现可以在GitHub上找到。