抢先一步
VMware 提供培训和认证,助你快速提升。
了解更多这是一篇来自 Simon BASLÉ (@simonbasle) 的交叉发布博客,他来自 Couchbase。你可以在 twitter (
@simonbasle) 或 github 上找到他。如需了解更多关于 Couchbase 和 Couchbase Java SDK 的信息,请访问开发者门户。再次感谢 Simon 和你的团队的杰出工作!-Josh
Spring Data Couchbase 2.0 是对原有 Spring Data Couchbase 1.4.x 连接器的重写。它基于 Couchbase Java 2.2 SDK,并大量使用了新的查询语言 N1QL(在 Couchbase Server 4.0 中引入),为 Spring Data 用户提供更多功能。
第一个里程碑版本已于去年八月发布,随后是候选发布版本,自那以后又实现了更多功能(和错误修复),现在 GA 版本可以向公众发布了。
让我们快速浏览一下有哪些变化(使用 ⭐ 到 ⭐⭐⭐ 表示我们认为每个功能有多棒和多重要?)
Spring Data Couchbase 的 1.x 版本与 2.x 版本之间的主要区别在于
CouchbaseTemplate 实例!)当然,你仍然可以使用 CouchbaseTemplate 而非 CouchbaseRepository 接口来访问较低级别的 API,你甚至可以直接从 SDK 访问底层的 Bucket。
⭐⭐⭐
Couchbase 4.0 的重大新功能是 N1QL,它是一个工作在 JSON 文档上的 SQL 扩展(因此它为 SQL 添加了与 JSON 相关的特定性)。
这对于 Spring Data 中的 Repository 模式和查询派生尤其有利,因为绝大多数查询派生关键字都可以轻松转换为 N1QL。
N1QL 现在是存储库方法的默认后备 Couchbase 功能。如果你想明确指定执行的查询,也可以选择使用 @Query 接口。
public interface UserRepository extends Repository<User, String> {
User findByUsernameEquals(String username);
List<User> findByUsernameContains(String contains);
@Query //optional for N1QL query derivation but more explicit
List<User> findByAgeBetween(int minAge, int maxAge);
}
⭐⭐
此版本的一个重大变化是,现在基于视图的存储库查询(即自定义存储库方法)更符合 Spring Data 的理念。它们也必须显式使用 @View(viewName="something") 进行注解。
这意味着不应有任何 Couchbase 特定的东西泄露到你的存储库接口中。相反,你可以对大多数查询使用查询派生机制。
查询派生在一定程度上也是可能的,一些关键字可以在视图支持的方法中被接受。
public interface UserRepository extends Repository<User, String> {
@Override
@View(designDocument = "user", viewName = "customFindAllView")
Iterable<User> findAll();
@View(viewName = "customFindByNameView")
User findByUsernameIs(String lowKey);
@View(viewName = "customFindByNameView")
List<User> findByUsernameBetween(String lowKey, String highKey);
}
⭐
另一个以前不支持的新功能是执行 reduce 函数(如果存在)。现在,为了执行它,你只需在 @View 注解中将 reduce 标志设置为 true。
如果对你有意义(即你实际使用了“count”reduce 函数),你也可以将方法前缀改为“count”而不是“find”。
请注意,Couchbase 中的 reduce 函数可以不同于预先存在的 _count 函数,它甚至可以返回除了 long 之外的其他类型,比如 JsonObject,就像内置的 _stats 那样。
类似地,在方法名中添加“topX”或“firstX”变体将导致对请求设置额外的限制(例如,findFirst5ByLastName 将把结果列表限制为 5 个)。
⭐⭐⭐
在使用视图和 GSI(支持 N1QL 的新二级索引引擎)等异步填充的二级索引时,经常出现的一个问题是需要立即读取先前写操作所做的修改。
这意味着只要数据仍在索引过程中,视图/N1QL就不应返回结果,因此这将牺牲一些性能以换取一致性。
相反正好相反(以及 Spring Data Couchbase 当前的默认行为)是优先考虑性能,接受返回陈旧数据。
我们通过提供围绕 Consistency 概念的小抽象,增加了全局语义来配置框架通过查询派生构建的所有查询(基于视图或基于 N1QL 的)。
这可以通过覆盖 AbstractCouchbaseConfiguration 的 getDefaultConsistency() 方法来完成。Consistency 是一个枚举,允许你在 READ_YOUR_OWN_WRITES、STRONGLY_CONSISTENT、UPDATE_AFTER 和 EVENTUALLY_CONSISTENT 之间进行选择。有关它们具体如何工作以及在查询时的影响,请参阅官方文档。
你也可以在 XML 中通过使用 <couchbase:template> 标签上的 consistency 属性来完成。
自 GA 版本以来,存储库中的 CRUD 方法现在也考虑了默认配置的一致性。
⭐
一些用户报告了 Spring Data 和 Couchbase Mobile 方面的问题,Sync Gateway 会拒绝包含以下划线为前缀的字段的文档。
这对 Spring Data 来说是个问题,因为它默认将类型信息存储在 _class 字段中 :(
解决方案是通过配置允许修改该类型信息字段的名称。你可以通过覆盖 AbstractCouchbaseConfiguration 中的 typeKey() 方法来实现。例如,你可以使用常量 MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE(其值为 "javaClass")。
这个字段是生成的 N1QL 查询用来过滤只对应于存储库实体的文档的字段。
Pageable/PageRequest⭐⭐
使用 N1QL,对于通过查询派生生成的查询,现在支持 Pageable 和 Sort 参数。
PagingAndSortingRepository 支持。findAll 方法,它们依赖 N1QL 进行分页和/或排序。使用默认配置的一致性。⭐⭐⭐
使用坐标查询 Couchbase!如果你的实体有 Point(或 x 和 y)位置信息,你可以通过以下方式查找:
findByLocationWithin(Box area)findByLocationWithin(Circle area), findByLocationWithin(Point center, Distance radius)。findByLocationWithin(Polygon area), findByLocationWithin(Point[] polygon)。findByLocationNear(Point near, Distance maxDistance)。圆形和多边形之类的查询在服务器端会作为边界框近似快速执行,然后框架会在呈现结果之前消除误报。
你可以利用 Couchbase 空间视图的多维特性,为你的查询添加额外维度(例如,查询城市中深夜仍开放的商店等)。
public interface DimensionalPartyRepository extends CrudRepository<Party, String> {
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocation")
List<Party> findByLocationNear(Point p, Distance d);
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocation")
List<Party> findByLocationWithin(Box boundingBox);
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocation")
List<Party> findByLocationWithin(Polygon zone);
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocationAndAttendees", dimensions = 3)
List<Party> findByLocationWithinAndAttendeesGreaterThan(Polygon zone, double minAttendees);
}
注意:如果你想重用注解,你也可以这样做(对 @View 和 @Query 也有效)
public interface DimensionalPartyRepository extends CrudRepository<Party, String> {
//define your own meta-annotation
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocation", dimensions = 2)
@Retention(RetentionPolicy.RUNTIME)
@interface IndexedByLocation { }
//use it :)
@IndexedByLocation
List<Party> findByLocationNear(Point p, Distance d);
@IndexedByLocation
List<Party> findByLocationWithin(Box boundingBox);
@IndexedByLocation
List<Party> findByLocationWithin(Polygon zone);
//here we use a variation with 3 dimensions, so we need to revert to @Dimensional
@Dimensional(designDocument = "partyGeo", spatialViewName = "byLocationAndAttendees", dimensions = 3)
List<Party> findByLocationWithinAndAttendeesGreaterThan(Polygon zone, double minAttendees);
}
N1QL @Query 现在支持 SpEL⭐⭐⭐
内联查询可以使用 SpEL 表达式来:
#{#n1ql.selectEntity} 生成 SELECT ... FROM ... 子句,并在 WHERE 子句中使用 #{#n1ql.filter} 将查询限制到正确的实体。⭐⭐
⚠️ 重要:这被认为是开发/测试期间的辅助手段,不建议在生产环境中使用
为了确保给定存储库中实体的 N1QL 索引在开发或预生产环境中被激活,可以使用 @N1qlPrimaryIndexed 注解(启用桶范围内的自由查询)和 @N1qlSecondaryIndexed 注解(仅索引对应于实体类型的文档,类似于 SpEL #{#n1ql.filter} 生成的 WHERE 子句)。
此外,CRUD 操作的后备视图可以通过在存储库上使用 @ViewIndexed 注解来自动创建(你需要提供设计文档名称,该名称应与实体的简单类名相对应,首字母小写)。
此功能必须通过在 AbstractCouchbaseConfiguration 中重新定义 indexManager bean 来额外启用。
String)⭐⭐
这尤其适用于带有聚合函数(如 COUNT(*)、AVG(field) 等)的内联 N1QL 查询... 查询必须返回单行且只有单个投影。
⭐⭐
使用命名参数或位置参数,但不能同时使用两者。命名参数的语法是 $paramName,要求每个方法参数都用 @Param("paramName") 注解。
⭐
其他功能包括
couchbase" 前缀,以避免与其他存储发生冲突。CouchbaseTemplate 中的 find 方法中排除。@Document 上设置,格式为 long + timeUnit还实现了一些相对于 RC1 的错误修复和改进。
⭐⭐⭐
文档也得到了改进,增加了面向 Couchbase 的示例,如如何向存储库添加自定义方法的实现、如何更改所有存储库的基类、如何在内联查询中处理 SpEL 等。
Spring Cache 支持已从 Spring Data 存储库中移出。它仍然存在,我们计划对其进行改进。目前你可以在 github 上的 Couchbase 存储库中找到它,但它很快会重新整合到官方 Spring 项目家族中。
你可以在项目的 pom.xml 中添加以下内容以获取此 GA 版本(在 dependencies 部分)
<!--<dependencies>-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-couchbase</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<!--</dependencies>-->
我们希望你喜欢此版本及其带来的所有新功能。下一步将是重新加入 Hopper 发布列车,预计在夏季前发布 2.1 版本。