原题目:Spring认证中国教育管理中心-Spring Data Couchbase教程九(Spring中国教育管理中心)
Spring Data Couchbase教程九
5.3.2.主动索引治理
默认状况下,预计用户会为其查问创立和治理最佳索引。尤其是在开发初期,主动创立索引能够疾速上手。
对于 N1QL,提供了以下正文,这些正文须要附加到实体(在类或字段上):
@QueryIndexed: 搁置在一个字段上,示意该字段应该是索引的一部分
@CompositeQueryIndex:搁置在类上,示意应该在多个字段(复合)上创立索引。
@CompositeQueryIndexes:如果CompositeQueryIndex应该创立多个,则此正文将采纳它们的列表。
例如,这是您在实体上定义复合索引的形式:
示例 79. 两个字段的复合索引具备排序
@Document
@CompositeQueryIndex(fields = {"id", "name desc"})
public class Airline {
@Id
String id;
@QueryIndexedString name;@PersistenceConstructorpublic Airline(String id, String name) { this.id = id;}public String getId() { return id;}public String getName() { return name;}
}
Spring Data Couchbase教程九
默认状况下,索引创立被禁用。如果要启用它,则须要在配置中笼罩它:
示例 80.启用主动索引创立
@Override
protected boolean autoIndexCreation() {
return true;
}
5.3.3.查问一致性
默认状况下,应用 N1QL 的存储库查问应用NOT_BOUNDED扫描一致性。这意味着后果会疾速返回,但来自索引的数据可能还不蕴含来自先前写入操作的数据(称为最终一致性)。如果您须要查问的“筹备好本人的写入”语义,则须要应用@ScanConsistency正文。这是一个例子:
示例 81. 应用不同的扫描一致性
@Repository
public interface AirportRepository extends PagingAndSortingRepository<Airport, String> {
@Override@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)Iterable<Airport> findAll();
}
5.3.4.DTO 预测
Spring Data Repositories 通常在应用查询方法时返回域模型。然而,有时,您可能出于各种起因须要更改该模型的视图。在本节中,您将学习如何定义投影以提供简化和简化的资源视图。
看上面的域模型:
@Entity
public class Person {
@Id @GeneratedValue
private Long id;
private String firstName, lastName;
@OneToOne
private Address address;
…
}
@Entity
public class Address {
@Id @GeneratedValue
private Long id;
private String street, state, country;
…
}
这Person有几个属性:
id 是主键
firstName并且lastName是数据属性
address 是指向另一个域对象的链接
当初假如咱们创立一个相应的存储库,如下所示:
interface PersonRepository extends CrudRepository<Person, Long> {
Person findPersonByFirstName(String firstName);
}
Spring Data 将返回蕴含其所有属性的域对象。有两个选项能够检索address属性。一种抉择是为这样的Address对象定义一个存储库:
interface AddressRepository extends CrudRepository<Address, Long> {}
在这种状况下,usingPersonRepository依然会返回整个Person对象。应用AddressRepository将只返回Address.
然而,如果您基本不想裸露address细节怎么办?您能够通过定义一个或多个投影来为您的存储库服务的使用者提供一种代替计划。
示例 82. 简略投影
interface NoAddresses {
String getFirstName();
String getLastName();
}
此投影具备以下详细信息:
一个一般的 Java 接口,使其具备申明性。
导出firstName.
导出lastName.
该NoAddresses投影仅领有干将firstName和lastName这意味着它不会成为的任何地址信息。在这种状况下,查询方法定义返回NoAdresses而不是Person.
interface PersonRepository extends CrudRepository<Person, Long> {
NoAddresses findByFirstName(String firstName);
}
投影申明了根底类型和与公开属性相干的办法签名之间的契约。因而须要依据底层类型的属性名称来命名 getter 办法。如果根底属性是 named firstName,那么 getter 办法必须被命名,getFirstName否则 Spring Data 无奈查找源属性。
- 反应式 Couchbase 存储库
6.1。介绍
本章形容了对 couchbase 的响应式存储库反对。这建设在Couchbase 存储库中解释的外围存储库反对之上。因而,请确保您对那里解释的基本概念有充沛的了解。
6.2.反应式组合库
Couchbase Java SDK 3.x 从 RxJava 迁徙到 Reactor,因而它与响应式 Spring 生态系统完满交融。
Reactive Couchbase 存储库提供我的项目 Reactor 包装器类型,并且能够通过简略地从特定于库的存储库接口之一扩大来应用:
ReactiveCrud 存储库
反应式排序存储库
6.3.用法
让咱们创立一个简略的实体开始:
示例 83. 示例 Person 实体
public class Person {
@Id
private String id;
private String firstname;
private String lastname;
private Address address;
// … getters and setters omitted
}
相应的存储库实现可能如下所示:
示例 84. 长久化 Person 实体的根本存储库接口
public interface ReactivePersonRepository extends ReactiveSortingRepository<Person, Long> {
Flux<Person> findByFirstname(String firstname);
Flux<Person> findByFirstname(Publisher<String> firstname);
Flux<Person> findByFirstnameOrderByLastname(String firstname, Pageable pageable);
Mono<Person> findByFirstnameAndLastname(String firstname, String lastname);
}
对于 JavaConfig,请应用@
EnableReactiveCouchbaseRepositories注解。正文带有与命名空间元素雷同的属性。如果没有配置根本包,基础设施将扫描带正文的配置类的包。
另请留神,如果您在 Spring Boot 设置中应用它,您可能能够省略正文,因为它是为您主动配置的。
示例 85. 存储库的 JavaConfig
@Configuration
@EnableReactiveCouchbaseRepositories
class ApplicationConfig extends AbstractCouchbaseConfiguration {
// ... (see configuration for details)
}
随着咱们的域存储库的扩大,ReactiveSortingRepository它为您提供了 CRUD 操作以及对实体进行排序拜访的办法。应用存储库实例只是将依赖项注入客户端的问题。
示例 86. 对 Person 实体的排序拜访
public class PersonRepositoryTests {
@AutowiredReactivePersonRepository repository;@Testpublic void sortsElementsCorrectly() { Flux<Person> persons = repository.findAll(Sort.by(new Order(ASC, "lastname"))); assertNotNull(perons);}
}
6.4.存储库和查问
Spring Data 的 Reactive Couchbase 带有阻塞存储库和查问曾经提供的残缺查问反对
- 模板&间接操作
该模板提供了对底层数据库的较低级别的拜访,并且还用作存储库的根底。每当存储库对您的须要来说太高级时,模板将为您提供良好服务的机会很大。请留神,您始终能够通过在
AbstractCouchbaseConfiguration.
7.1。反对的操作
模板能够通过couchbaseTemplate和
reactiveCouchbaseTemplatebean拜访您的上下文。一旦取得了对它的援用,就能够对它运行各种操作。除了通过存储库之外,您还须要在模板中始终指定要转换的指标实体类型。
模板应用流式 API,容许您依据须要链接可选运算符。例如,以下是您存储用户而后通过其 ID 再次找到它的形式:
示例 87. 晦涩的模板拜访
// Create an Entity
User user = new User(UUID.randomUUID().toString(), "firstname", "lastname");
// Upsert it
couchbaseTemplate.upsertById(User.class).one(user);
// Retrieve it again
User found = couchbaseTemplate.findById(User.class).one(user.getId());
如果您想对操作应用自定义持久性要求,upsert您能够将其链接到:
示例 88. 具备持久性的 Upsert
User modified = couchbaseTemplate
.upsertById(User.class)
.withDurability(DurabilityLevel.MAJORITY)
.one(user);
以相似的形式,您能够执行 N1QL 操作:
示例 89. 模板上的 N1QL 查问
final List<User> foundUsers = couchbaseTemplate
.findByQuery(User.class)
.consistentWith(QueryScanConsistency.REQUEST_PLUS)
.all();
8.交易反对
Couchbase 反对分布式事务。本节介绍如何将它与 Spring Data Couchbase 一起应用。
8.1。要求
Couchbase 服务器 6.5 或更高版本。
Couchbase Java 客户端 3.0.0 或更高版本。倡议遵循 maven 交易库的传递依赖。
应该配置 NTP,以便 Couchbase 集群的节点与工夫同步。工夫不同步不会导致错误行为,但会影响元数据清理。
8.2.入门和配置
如果正在应用 maven(或等效项),则couchbase-transactions须要将工件蕴含在您的文件中pom.xml。
个人: com.couchbase.client
神器: couchbase-transactions
版本:最新版本,即 1.0.0
一旦它被蕴含在您的我的项目中,您须要创立一个Transactions对象。不便的是,它能够成为您的 spring data
couchbaseAbstractCouchbaseConfiguration实现的一部分:
例 90. 事务配置
@Configuration
static class Config extends AbstractCouchbaseConfiguration {
// Usual Setup@Override public String getConnectionString() { /* ... */ }@Override public String getUserName() { /* ... */ }@Override public String getPassword() { /* ... */ }@Override public String getBucketName() { /* ... */ }@Beanpublic Transactions transactions(final Cluster couchbaseCluster) { return Transactions.create(couchbaseCluster, TransactionConfigBuilder.create() // The configuration can be altered here, but in most cases the defaults are fine. .build());}
}
一旦@Bean配置,你能够从你的服务(或任何其余类),主动拆卸它来应用它。请参阅参考文档 理解如何应用Transactions该类。因为您还须要拜访电流Collection,咱们建议您也主动CouchbaseClientFactory连贯并从那里拜访它:
示例 91. 事务拜访
@Autowired
Transactions transactions;
@Autowired
CouchbaseClientFactory couchbaseClientFactory;
public void doSomething() {
transactions.run(ctx -> {
ctx.insert(couchbaseClientFactory.getDefaultCollection(), "id", "content");
ctx.commit();
});
}
8.3.对象转换
因为事务库自身不理解您的 spring 数据实体类型,因而您须要在读/写时来回转换能力正确交互。侥幸的是,您须要做的就是主动拆卸MappingCouchbaseConverter并应用它:
示例 92. 写入时的事务转换
@Autowired
MappingCouchbaseConverter mappingCouchbaseConverter;
public void doSomething() {
transactions.run(ctx -> {
Airline airline = new Airline("demo-airline", "at");
CouchbaseDocument target = new CouchbaseDocument();
mappingCouchbaseConverter.write(airline, target);
ctx.insert(couchbaseClientFactory.getDefaultCollection(), target.getId(), target.getContent());
ctx.commit();
});
}
读取时能够应用雷同的办法:
示例 93. 读取时的事务转换
TransactionGetResult getResult = ctx.get(couchbaseClientFactory.getDefaultCollection(), "doc-id");
CouchbaseDocument source = new CouchbaseDocument(getResult.id());
source.setContent(getResult.contentAsObject());
Airline read = mappingCouchbaseConverter.read(Airline.class, source);
咱们还在钻研将事务库更严密地集成到 Spring 数据库生态系统中。:leveloffset: -1