Spring Boot 2.x实战57 - Spring Data 1 - DDD与Spring Data(Repository)

Spring Data 是一个伞型项目,包含主流的数据库的访问技术。这些不同的数据访问项目都使用相同的编程模型,他们都是基于Repository规范接口。我们在本章选关系型数据库的访问技术Spring Data JPA和NoSQL的访问Spring Data Elasticsearch。

1. Spring Data Repository

1.1 DDD与Spring Data

1.1.1 DDD

DDD是Domain-Driven Design的缩写,即领域驱动设计。它是解决复杂业务需求的一些列高级技术。

它的战术设计部分有几个重要概念和Spring Data有关系:

  • 实体(Entity):对一个实际的事物进行抽象建模,每一个实体都有唯一标识用来和其他的实体做为区别;实体是可变的,它会随着时间的推移而修改。
  • 值对象(Value Object):值对象等同于值,它对一个不变的概念的整体进行建模。它没有唯一标识,相等性通过比较值对象的属性来实现;值对象不能被修改只能被替换;它和值一样都是用来描述、量化或衡量实体的。
  • 聚合(Aggregate):聚合是一个或多个实体组合而成的,其中表示核心概念的实体叫做聚合根。在实际设计中有“设计小聚合的原则”,一般情况下一个聚合只包含一个实体类。
  • 领域事件(Domain Event):聚合之间的通讯通过发布领域事件来进行,事件由聚合根发布。
  • (Repository):Respository是用来存储聚合的,每一个聚合都有一个Respository,它们之间是一对一的关系。库中对聚合的存储操作类似于集合类,和Set一样保证数据的唯一性。

我们先举例说明上面的概念:

public class Person {
    private Long id;
    private String name;
    private Integer age;
    private Address address;
    private Collection<Child> children;
  	//...
}
  • Person是实体类,因为设计小聚合的原则,Person也是聚合与聚合根;

  • id属性是唯一标识;

  • nameage是值,用来描述实体Person

  • 同样addresschildren也是用来描述某个Person的,是对象形式的,所以它们是值对象。

1.1.2 Spring Data Repository

Spring Data Repository对访问不同的数据库提供统一的抽象,它极大的减少了数据访问层的样板代码。Spring Data Repository抽象的核心是org.springframework.data.repository.Repository<T, ID>T代表是它处理的实体的类型,ID代表实体的唯一标识。它的主要子接口有CrudRepository定义新增、查询、更新、删除功能接口。PagingAndSortingRepository又是CrudRepository的子接口,定义了分页和排序的功能接口。

public interface CrudRepository<T, ID> extends Repository<T, ID> {
   <S extends T> S save(S entity);  //保存一个实体
   <S extends T> Iterable<S> saveAll(Iterable<S> entities); //保存多个实体
   Optional<T> findById(ID id); // 按照id查询实体
   boolean existsById(ID id); // 按照id查询的实体是否存在
   Iterable<T> findAll(); 	//查出所有实体
   Iterable<T> findAllById(Iterable<ID> ids); //按照多个id查询多个实体
   long count(); //计数实体
   void deleteById(ID id); //按照id删除实体
   void delete(T entity); //删除实体
   void deleteAll(Iterable<? extends T> entities);//删除多个实体
   void deleteAll(); //删除所有实体
}
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
   Iterable<T> findAll(Sort sort); //根据排序参数查询出所有的实体
   Page<T> findAll(Pageable pageable); //根据分野参数查询出所有的实体
}

针对不同的数据库,也有特定的子接口抽象,如:JpaRepositoryElasticsearchRepository等。

我们可以通过继承上面的接口来定义实体的Repository,并通过相关的开启配置(@EnableJpaRepositories)的注解后,实体Repository会被Spring Data注册成为一个Bean,我们可以使用这个Bean进行数据访问操作了。

定义Repository:

public interface PersonRepository extends JpaRepository<Person, Long> {
}

使用Repository:

@RestController
@RequestMapping("/people")
public class PersonController {

    private PersonRepository personRepository;

    public PersonController(PersonRepository personRepository) {
        this.personRepository = personRepository;
    }

    @GetMapping("/findByName")
    public List<Person> findByName(@RequestParam String name){
        return personRepository.findByName(name);
    }
}

我们用相应注解将相应数据库的领域模型标识为实体,如:JPA使用的是@Entity,Elasticsearch使用的是@Document

JPA:

@Entity
public class Person {
    @Id
    private Long id;
    private String name;
    private Integer age;
    //...
}

Elasticsearch:

@Document(indexName = "person")
public class Person {}

1.2 查询方法

Spring Data支持根据方法名中的属性进行推导查询,关键词可以是find...Byread...Byget…ByBy之后是查询条件(where 之后的条件)

public interface PersonRepository extends JpaRepository<Person, Long> {
    List<Person> findByName(String name);
  	List<Person> findDistinctPersonByName(String name);
}

也可通过count...By进行推导计数查询:

public interface PersonRepository extends JpaRepository<Person, Long> {
    long countByName(String name);
}

也可通过delete...By进行推导删除查询:

public interface PersonRepository extends JpaRepository<Person, Long> {
    long deleteByName(String name);
    List<Person> removeByName(String name);
}

By之前还可以用通过firtsttop关键字来限制查询数量:

public interface PersonRepository extends JpaRepository<Person, Long> {
    List<Person> queryTop5ByName(String name);
    List<Person> getFirst10ByName(String name);
}

关于更多Spring Data的查询关键字我们会在后续的详细讲解。

新书推荐:

我的新书《从企业级开发到云原生微服务:Spring Boot 实战》已出版,内容涵盖了丰富Spring Boot开发的相关知识
购买地址:https://item.jd.com/12760084.html
在这里插入图片描述

主要包含目录有:

第一章 初识Spring Boot(快速领略Spring Boot的美丽)
第二章 开发必备工具(对常用开发工具进行介绍:包含IntelliJ IDEA、Gradle、Lombok、Docker等)
第三章 函数式编程
第四章 Spring 5.x基础(以Spring 5.2.x为基础)
第五章 深入Spring Boot(以Spring Boot 2.2.x为基础)
第六章 Spring Web MVC
第七章 数据访问(包含Spring Data JPA、Spring Data Elasticsearch和数据缓存)
第八章 安全控制(包含Spring Security和OAuth2)
第九章 响应式编程(包含Project Reactor、Spring WebFlux、Reactive NoSQL、R2DBC、Reactive Spring Security)
第十章 事件驱动(包含JMS、RabbitMQ、Kafka、Websocket、RSocket)
第11章 系统集成和屁股里(包含Spring Integration和Spring Batch)
第12章 Spring Cloud与微服务
第13章 Kubernetes与微服务(包含Kubernetes、Helm、Jenkins、Istio)
多谢大家支持。

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页