Spring Data
Tips
- Spring Data 示例
- Spring Data Commons 文档
- 实现将 PathVariable 从主键转为实体的转换器为 DomainClassConverter
- 主要使用: Repositories, RepositoryInformation, RepositoryInvoker 进行操作
Note
-
RepositoryMetadata
-
RepositoryInformation
-
RepositoryQuery
- 抽象接口, 用于执行所有数据仓库操作
-
PartTree
- 用于将方法名转换为查询方法
^(find|read|get|query|stream|count|exists|delete|remove)((\p{Lu}.*?))??By
-
PersistenceExceptionTranslationInterceptor
- 处理数据仓库调用过程中的异常
-
查询方法处理链
SurroundingTransactionDetectorMethodInterceptor
- 事务设置
ExposeInvocationInterceptor
DefaultMethodInvokingMethodInterceptor
- 处理
default
方法
- 处理
RepositoryFactorySupport$QueryExecutorMethodInterceptor
映射 - org.springframework.data.mapping
- 处理不同 SpringData 持久化的中间层映射
PersistentEntity<T, P extends PersistentProperty<P>> extends Iterable<P>
- 一个持久化对象
PersistentProperty
- 一个持久化对象的属性
Association
- 表示属性之间的关联
- 主要实现
JpaPersistentPropertyImpl
- JPA 持久化对象的属性
MutablePersistentEntity<T, P extends PersistentProperty<P>> extends PersistentEntity<T, P>
- 包含了修改方法
IdentifierAccessor
PersistentPropertyAccessor
MappingContext
- 映射上下文
- 记录了所有已知的实体类型
PersistentPropertyPath
- 表示一个持久属性的路径
MongoDB
// SpringData 查询日志
logging.level.org.springframework.data.mongodb.core.MongoTemplate: DEBUG
// MongoDB 的日志工具类 com.mongodb.diagnostics.logging.Loggers
// 前缀 org.mongodb.driver 例如 操作 operation
logging.level.org.mongodb.driver.operation: INFO
// 或者打开全量的
// 注意, 依然是看不到发送的查询
logging.level.org.mongodb.driver: INFO
- MongoDB 的 Repository 实现
org.springframework.data.mongodb.repository.support.SimpleMongoRepository
org.springframework.data.mongodb.repository.support.QueryDslMongoRepository
MongoQueryMethod
- 解析 Mongo 的 Query 注解
PartTreeMongoQuery
- 通过方法解析后的 Query 实例
org.springframework.data.mongodb.core.query.Query
- 实际查询
org.springframework.data.mongodb.repository.support.SpringDataMongodbQuery
- QueryDSL Mongo 的查询对象
interface MyRepo{
// 只返回 tags 字段
// 注意: QueryDSL 的 Predicate 不会被使用
@Query(fields = "{'tags':1}")
List<PageDocument> findTagsBy(Predicate predicate);
// 建议基于 QueryDslMongoRepository 将查询对象上的 Path 参数暴露出来, 例如
List<T> findAll(Predicate predicate, Path<?>... paths);
}
Entity Versions
- spring-projects/spring-data-envers
- JPA 扩展, 基于 hibernate envers
Spring Data 查询关键字
逻辑关键词 | 关键词表达式 |
---|---|
AND | And |
OR | Or |
AFTER | After, IsAfter |
BEFORE | Before, IsBefore |
CONTAINING | Containing, IsContaining, Contains |
BETWEEN | Between, IsBetween |
ENDING_WITH | EndingWith, IsEndingWith, EndsWith |
EXISTS | Exists |
FALSE | False, IsFalse |
GREATER_THAN | GreaterThan, IsGreaterThan |
GREATER_THAN_EQUALS | GreaterThanEqual, IsGreaterThanEqual |
IN | In, IsIn |
IS | Is, Equals, (or no keyword) |
IS_NOT_NULL | NotNull, IsNotNull |
IS_NULL | Null, IsNull |
LESS_THAN | LessThan, IsLessThan |
LESS_THAN_EQUAL | LessThanEqual, IsLessThanEqual |
LIKE | Like, IsLike |
NEAR | Near, IsNear |
NOT | Not, IsNot |
NOT_IN | NotIn, IsNotIn |
NOT_LIKE | NotLike, IsNotLike |
REGEX | Regex, MatchesRegex, Matches |
STARTING_WITH | StartingWith, IsStartingWith, StartsWith |
TRUE | True, IsTrue |
WITHIN | Within, IsWithin |
Spring Data 返回结果类型
返回类型 | 描述 |
---|---|
void | 不返回值 |
原子类型 | Java 原子类型值 |
包装类型 | Java 包装类型值 |
T | An unique entity. Expects the query method to return one result at most. In case no result is found null is returned. More than one result will trigger an IncorrectResultSizeDataAccessException. |
Iterator<T> | An Iterator. |
Collection<T> | A Collection. |
List<T> | A List. |
Optional<T> | A Java 8 or Guava Optional. Expects the query method to return one result at most. In case no result is found Optional.empty()/Optional.absent() is returned. More than one result will trigger an IncorrectResultSizeDataAccessException. |
Stream<T> | A Java 8 Stream. |
Future<T> | A Future. Expects method to be annotated with @Async and requires Spring’s asynchronous method execution capability enabled. |
CompletableFuture<T> | A Java 8 CompletableFuture. Expects method to be annotated with @Async and requires Spring’s asynchronous method execution capability enabled. |
ListenableFuture | A org.springframework.util.concurrent.ListenableFuture. Expects method to be annotated with @Async and requires Spring’s asynchronous method execution capability enabled. |
Slice | A sized chunk of data with information whether there is more data available. Requires a Pageable method parameter. |
Page<T> | A Slice with additional information, e.g. the total number of results. Requires a Pageable method parameter. |
GeoResult<T> | A result entry with additional information, e.g. distance to a reference location. |
GeoResults<T> | A list of GeoResult<T> with additional information, e.g. average distance to a reference location. |
空间坐标类型(GeoResult, GeoResults, GeoPage)只有在存储类型支持空间类型时返回
JPA Repository 方法语法
Keyword | Sample | JPQL snippet |
---|---|---|
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | findByFirstname,findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age ⇐ ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull | findByAgeIsNull | … where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection<Age> ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection<Age> age) | … where x.age not in ?1 |
True | findByActiveTrue() | … where x.active = true |
False | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
// Enables the distinct flag for the query
List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);
// 使用 Top 和 First
User findFirstByOrderByLastnameAsc();
User findTopByOrderByAgeDesc();
Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);
Slice<User> findTop3ByLastname(String lastname, Pageable pageable);
List<User> findFirst10ByLastname(String lastname, Sort sort);
List<User> findTop10ByLastname(String lastname, Pageable pageable);
// 返回结果流
@Query("select u from User u")
Stream<User> findAllByCustomQueryAndStream();
// 只返回结果片段
Slice<User> findTop3ByLastname(String lastname, Pageable pageable);
// 选择单个返回,可返回 Optional
User findFirstByOrderByLastnameAsc();
Optional<User> findTopByOrderByAgeDesc();
// 异步操作
@Async
Future<User> findByFirstname(String firstname);
@Async
CompletableFuture<User> findOneByFirstname(String firstname);
@Async
ListenableFuture<User> findOneByLastname(String lastname);
Long countByLastname(String lastname);
Long deleteByLastname(String lastname);
List<User> removeByLastname(String lastname);