Spring Data JDBC简介

2023/05/18

1. 概述

Spring Data JDBC是一个持久化框架,不像Spring Data JPA那样复杂。它不提供缓存、延迟加载、后写或JPA的许多其他功能。尽管如此,它有自己的ORM并提供了我们在Spring Data JPA中使用的大部分功能,如映射实体、Repository、查询注解和JdbcTemplate

要记住的重要一点是Spring Data JDBC不提供模式(Schema)生成,因此,我们需要负责显式创建模式。

2. 在项目中添加Spring Data JDBC

Spring Data JDBC可用于具有JDBC依赖启动器的Spring Boot应用程序。不过,此依赖项启动器并不包含数据库驱动程序。该驱动程序必须由开发人员指定。让我们为Spring Data JPA添加启动器依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>

在这个例子中,我们使用的是H2数据库。正如我们前面提到的,Spring Data JDBC不提供模式生成。在这种情况下,我们可以创建一个自定义schema.sql文件,该文件将包含用于创建模式对象的SQL命令。Spring Boot会自动选择该文件并将其用于创建数据库对象。

3. 添加实体

与其他Spring Data项目一样,我们使用注解将POJO与数据库表映射。在Spring Data JDBC中,实体需要有一个@Id。Spring Data JDBC使用@Id注解来标识实体。

与Spring Data JPA类似,Spring Data JDBC默认使用一种命名策略,将Java实体映射到关系型数据库表,将属性映射到列名。默认情况下,实体和属性的驼峰大小写名称分别映射到表和列的蛇形名称。例如,名为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的默认命名策略隐式执行实体和表之间的所有映射。

4. 声明JDBC Repository

Spring Data JDBC使用类似于Spring Data JPA的语法。我们可以通过扩展Repository、CrudRepository或PagingAndSortingRepository接口来创建Spring Data JDBC Repository。通过扩展CrudRepository,我们获得了最常用方法的实现,如save、delete和findById等。

让我们创建一个我们将在示例中使用的JDBC Repository:

@Repository 
public interface PersonRepository extends CrudRepository<Person, Long> {
}

如果我们需要分页和排序功能,最好的选择是扩展PagingAndSortingRepository接口。

5. 自定义JDBC Repository

尽管CrudRepository有内置的方法,但我们需要为特定情况创建我们的方法。

下面,让我们使用非修改查询和修改查询自定义我们的PersonRepository:

@Repository
public interface PersonRepository extends CrudRepository<Person, Long> {

    List<Person> 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版本开始,Spring Data JDBC支持查询方法。也就是说,如果我们将查询方法命名为包含关键字,例如,findByFirstName,Spring Data JDBC将自动生成查询对象。

但是,对于修改查询,我们使用@Modifying注解来标注修改实体的查询方法。另外,我们还使用@Query注解来修饰它。

在@Query注解中,我们添加了SQL语句。在Spring Data JDBC中,我们用纯SQL语句编写查询。我们不使用任何高级查询语言(例如JPQL)。结果,应用程序变得与数据库供应商紧密耦合。

因此,更改为不同的数据库也变得更加困难。

我们需要记住的一件事是,Spring Data JDBC不支持使用索引编号引用参数,我们只能通过名称引用参数

6. 填充数据库

最后,我们需要用数据填充数据库,这些数据将用于测试我们在上面创建的Spring Data JDBC Repository。因此,我们将创建一个插入虚拟数据的DatabaseSeeder。让我们为此示例添加DatabaseSeeder的实现:

@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')");
    }
}

如上所示,我们使用Spring JDBC来执行INSERT语句。特别是,Spring JDBC处理与数据库的连接,并允许我们使用JdbcTemplate执行SQL命令。这个解决方案非常灵活,因为我们可以完全控制执行的查询。

7. 总结

总而言之,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,我们可能不得不处理由具有不同方言的数据库引起的问题

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章