关于Spring Data JDBC的简介

539 阅读4分钟

简介

Spring Data JDBC是更大的Spring Data家族的一部分,它使实现基于JDBC的存储库变得容易。

它是一个持久化框架,不像Spring DataJPA那样复杂。它不提供缓存、懒惰加载、写后台或JPA的许多其他功能。然而,它有自己的ORM,并提供了我们在Spring Data JPA中使用的大部分功能**,如映射实体、存储库、查询注释和JdbcTemplate**。

需要记住的一件事是,Spring Data JDBC不提供模式生成。因此,我们要负责明确地创建模式。

将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数据库。正如我们早期提到的,它不提供模式生成。在这种情况下,我们可以创建一个自定义的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 Case名称会分别映射到表和列的snake Case名称。例如,一个名为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的默认命名策略在实体和表之间隐含地进行了所有的映射。

声明JDBC存储库

它使用的语法与Spring Data JPA相似。我们可以通过扩展RepositoryCrudRepository或PagingAndSortingRepository接口来创建Spring Data JDBC资源库。通过实现CrudRepository,我们可以得到最常用的方法的实现,比如保存删除findById等等。

让我们创建一个JDBC存储库,在我们的例子中使用。

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

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

自定义JDBC存储库

尽管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版本开始,它支持查询方法。也就是说,如果我们命名我们的查询方法,包括关键字,例如,*findByFirstName,*它将自动生成查询对象。

然而,对于修改性查询,我们使用*@Modifying注解来注解修改实体的查询方法。同时,我们用@Query*注解来装饰它。

在*@Query*注解中,我们添加我们的SQL命令。**在这里,我们用普通的SQL写查询。**我们不使用任何像JPQL这样的高级查询语言。因此,应用程序变得与数据库供应商紧密耦合。

由于这个原因,改变到一个不同的数据库也变得更加困难。

我们需要记住的一点是,它不支持用索引号来引用参数我们只能通过名称来引用参数

填充数据库

最后,我们需要用数据填充数据库,用于测试我们上面创建的资源库。所以,我们要创建一个数据库播种器,插入假数据。让我们为这个例子添加数据库播种器的实现。

@Component
public class DatabaseSeeder {

    @Autowired
    private JdbcTemplate jdbcTemplate;
    public void insertData() {
        jdbcTemplate.execute("INSERT INTO Person(first_name,last_name) VALUES('John', 'Depp')");
        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语句。特别是,它处理与数据库的连接,让我们使用JdbcTemplates执行SQL命令。这个解决方案非常灵活,因为我们可以完全控制执行的查询。

总结

在这篇文章中,Spring Data JDBC提供了一个和使用Spring JDBC一样简单的解决方案--它背后没有任何魔力。尽管如此,它也提供了我们使用Spring Data JPA所习惯的大部分功能。

与Spring Data JPA相比,使用它的最大优势之一是访问数据库时的性能提高。这是由于Spring Data JDBC直接与数据库进行通信在查询数据库时,Spring Data JDBC不包含大部分的Spring Data魔法