7. 使用 spring data repository
7.1 核心概念
- Repository是抽象出来的核心接口,需要传入领域类(domain class)和ID的类型
- CrudRepository继承Repository,提供了复杂的CRUD方法
- PagingAndSortingRepository继承CrudRepository,提供了易于分页查询的方法
- 查询语句衍生(query derivation),可以在查询、删除方法中直接使用实体的字段(然而用户并未定义该方法),比如findByLastname、deleteByLastname
7.2 查询方法
使用Spring Data的四个步骤
- 自定义接口并继承Repository或其子接口
- 在自定义接口中声明查询方法
- 通过JavaConfig或XML Configuration来配置代理实例(proxy instance)
- 注意JavaConfig没有显式配置package,默认使用@Repository注解的repository
- 将自定义的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的查询语句