概述
Spring 中有多种操作数据库的方式,通常来说我们优先选择的是 MyBatis,如果业务比较简单我们还会使用 JdbcTemplate,另外据说国外使用 spring-data-jpa 比较多?
最近发现了 Spring 中另一款操作关系型数据库的框架,相对 JdbcTemplate 来说使用上又简化了一些,它也是 Spring Data 大家族中的一员,即 spring-data-jdbc,分享给大家。
由于 Spring Data 内容较多,分为上下两篇介绍,本篇我们先介绍一些 Spring Data 的基础知识,下篇再介绍 spring-data-jdbc。
模块划分
Spring Data 大家族中有一些每个模块都要遵守的规范,这些规范定义在 spring-data-commons 模块中,理解这些规范后,切换到具体的实现模块能很快上手。这些模块之间的关系可以用下面的图来表示。
核心概念
Spring Data 的实现借鉴了领域驱动设计 DDD 的设计原则,规范中的核心概念是 Repository,它表示一个管理 Domain 的仓库,所有的数据库操作都要经过 Repository。
Domain 则表示数据库表在 Java 中的映射,每个 Domain 都必须有一个唯一的 ID 标识,可以通过 @Id
注解标识。例如,我们有一个关系型数据库表 user
,结构如下:
create table user
(
id bigint unsigned auto_increment
primary key,
username varchar(20) null,
password varchar(20) null
);
可以使用如下的类表示。
@Data
public class User {
@Id
private Long id;
private String username;
private String password;
}
Repository 作为一个接口,接收具体的 Domain 类型和 Domain 的 ID 类型作为泛型参数。接口定义如下。
public interface Repository<T, ID> {
}
自定义 Repository 接口
Repository
Repository
只是一个标记接口,对于开发者来说需要提供一个 Repository
的子接口,然后再定义一些操作数据库的方法。例如,针对上面的 Domain User
我们可以定义一个这样的 Repository
。
public interface UserRepository extends Repository<User, Long> {
Optional<User> findById(Long id);
}
Spring Data 实现模块会根据特定的语法规则将方法解析为具体的查询方式,例如对于 spring-data-jdbc
模块来说,上面的 findById
可以解析为如下 SQL。
select id,username,password from user where id = ?
如果多个 Domain 相同的操作比较多,我们还可以将方法定义到一个 BaseRepository
中,示例如下。
@NoRepositoryBean
public interface BaseRepository<T, ID> extends Repository<T, ID> {
Optional<T> findById(ID id);
}
public interface UserRepository extends BaseRepository<User, Long> {
}