7. 使用 spring data repository

7.1 核心概念

  • Repository是抽象出来的核心接口,需要传入领域类(domain class)和ID的类型
  • CrudRepository继承Repository,提供了复杂的CRUD方法
  • PagingAndSortingRepository继承CrudRepository,提供了易于分页查询的方法
  • 查询语句衍生(query derivation),可以在查询、删除方法中直接使用实体的字段(然而用户并未定义该方法),比如findByLastname、deleteByLastname

7.2 查询方法

使用Spring Data的四个步骤

  1. 自定义接口并继承Repository或其子接口
  2. 在自定义接口中声明查询方法
  3. 通过JavaConfig或XML Configuration来配置代理实例(proxy instance)
    • 注意JavaConfig没有显式配置package,默认使用@Repository注解的repository
  4. 将自定义的repository的接口实例注入到需要使用的类中,调用方法

如果自定义接口中声明的查询方法没有默认实现,则需要创建实现接口的实现类并实现其中方法

7.3 定义Repository接口

7.3.1 微调Repository定义

  • 自定义Repository接口继承Spring Data提供的接口(如CrudRepository)会将相应的接口中的方法暴露给实体,如果更倾向于选择性地使用一些方法,从相应的接口中(如CrudRepository)复制方法到自己的通用基础Repository中即可,不需要实现该方法,因为Spring Data已提供了对应的基础接口简单实现类SimpleMongod
  • 定义通用基础Repository接口时,要加@NoRepositoryBean的注解避免Spring Data自动扫描到并创建对应实例
  • @RepositoryDefinition注解 等价于 直接继承Repository接口

7.3.2 Repository方法的Null处理(本节内容忽略,Optional有待深入研究)

  • 返回Java8的Optional类型值来表示该值可能为null(也可以使用Optional包装类如Guava)
  • 有点看不懂,大概意思就是可以用@Nullable等注解来防止报错?

7.3.3 使用Repositories时,用了多个Spring Data模块(JPA、MongoDB)

当使用Repository时,用了多个Spring Data模块(JPA、MongoDB),Repository的定义必须区别其所使用的持久层技术(是JPA还是MongoDB)

  • Repository继承了特定模块的Repository接口(比如继承了MongoRepository就明确使用Mongo作为持久层)
  • 领域类(domain class)加了特定模块的注解(比如JPA使用@Entity,而MongoDB使用@Document)
  • 领域类不能混合注解特定模块(同时使用@Entity和@Document),Spring Data不支持
  • 通过启用特定模块的注解(如@EnableJpaRepositories),并设置相应的basePackages目录来指定模块

7.4 定义查询方法(本节内容暂时忽略,因为逻辑删的特性,方法都需要自定义)

Repository代理有两种方式通过方法名来获得特定存储对象的查询语句

  • 直接通过方法名获得查询语句
  • 自定义查询语句(使用@Query注解自定义查询语句)

7.5 创建Repository实例

  • XML Configuration:
  • JavaConfig: 启用特定模块的注解(如@EnableJpaRepositories),并设置相应的basePackages目录来指定模块
  • 独立使用: 通过代码创建

7.6 Spring Data Repositories的自定义实现

Repository定制化及如何用碎片建立复合的Repository

7.6.1 定制独有的Repository

  • 定义碎片接口并实现该接口,该接口的实现类要以’Impl’为后缀与该接口关联(Spring Data会按照规则自动扫描)
  • 用Repository接口继承先前定义并实现的零散接口来使用定制化的方法
  • 自定义实现比Spring Data提供的基础实现有更高的优先级,根据继承接口实现的顺序来覆盖方法,消除二义性(可以覆盖基础实现,但是是否按顺序覆盖未测试过)
  • 多个Repository接口可以使用同一个碎片接口(使用泛型)
  • 可以自定义接口实现类的后缀(默认是’Impl’)】
  • 可以通过注释指定Repository接口实现类 Repository接口:@Component(“specialCustom”);接口实现类:@Component(“specialCustomImpl”)

7.6.2 定制基础Repository

  • 创建一个接口实现继承持久层特定技术的接口(SimpleMongoRepository)作为Repository代理的自定义基础类,需要重写父类的构造函数。
  • 为使Spring Data发现自定义的基础类,需要指定”repositoryBaseClass”
    • JavaConfig: @Enable${store}Repositories(“repositoryBaseClass=…”)
    • XML Configuration:

7.7 用Aggregate Roots派发事件(有待研究)

7.8 Spring Data扩展

本部分内容记载了如何在各种上下文中使用Spring Data

7.8.1 Querydsl扩展

Querydsl是一种框架可以通过它流畅的API启用静态类型有如SQL一般的查询语句,Repository接口通过继承QuerydslPredicateExecutor来使用Querydsl提供的API

7.8.2 Web支持(本节省略)

顾名思义,就是对Controller层的支持

7.8.3 Repository Populators(本节省略)

使用XML和JSON定义数据结构(然并卵)

9 MongoDB支持

MongoDB支持包含了各式各样的特性,总结如下:

  • Spring配置支持使用JavaConfig配置Mongo驱动实例和副本集
  • MongoTemplate通过实现了通用的Mongo操作提高生产效率,包含映射Documents和POJO来整合对象
  • 将异常转换为Spring的可移植数据访问异常层次结构
  • 基于注解映射元数据,但扩展支持其他元数据格式
  • 持久层和映射生命周期事件
  • 基于Java的Query, Criteria, Update DSLs
  • Repository接口的自动实现,包含支持自定义查询方法
  • QueryDSL集成来支持类型安全的查询语句
  • 地球空间信息集成

本章节讲述的关键内容:

  • mongo对应spring-data-mongodb的API
  • 聚合(Aggregation)操作

11 MongoDB Repositories

这个章节会指出支持MongoDB的Repository的特殊的地方

  • @Id的类型可以使用String, ObjectId, BigInteger
  • Query Method 衍生 对应的mongo查询语句
  • 地理位置的Repository查询语句(Query Method 衍生)
  • 基于JSON的查询语句