前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Spring认证中国教育管理中心-Spring Data Couchbase教程九

Spring认证中国教育管理中心-Spring Data Couchbase教程九

原创
作者头像
IT胶囊
发布2022-01-13 15:07:44
发布2022-01-13 15:07:44
1.3K00
代码可运行
举报
文章被收录于专栏:IT技能应用IT技能应用
运行总次数:0
代码可运行

原标题:Spring认证中国教育管理中心-Spring Data Couchbase教程九(Spring中国教育管理中心)

5.3.2.自动索引管理

默认情况下,预计用户会为其查询创建和管理最佳索引。尤其是在开发初期,自动创建索引可以快速上手。

对于 N1QL,提供了以下注释,这些注释需要附加到实体(在类或字段上):

  • @QueryIndexed: 放置在一个字段上,表示该字段应该是索引的一部分
  • @CompositeQueryIndex:放置在类上,表示应该在多个字段(复合)上创建索引。
  • @CompositeQueryIndexes:如果CompositeQueryIndex应该创建多个,则此注释将采用它们的列表。

例如,这是您在实体上定义复合索引的方式:

示例 79. 两个字段的复合索引具有排序

代码语言:javascript
代码运行次数:0
复制
@Document
@CompositeQueryIndex(fields = {"id", "name desc"})
public class Airline {
   @Id
   String id;

	@QueryIndexed
	String name;

	@PersistenceConstructor
	public Airline(String id, String name) {
		this.id = id;
	}

	public String getId() {
		return id;
	}

	public String getName() {
		return name;
	}

}

默认情况下,索引创建被禁用。如果要启用它,则需要在配置中覆盖它:

示例 80.启用自动索引创建

代码语言:javascript
代码运行次数:0
复制
@Override
protected boolean autoIndexCreation() {
 return true;
}

5.3.3.查询一致性

默认情况下,使用 N1QL 的存储库查询使用NOT_BOUNDED扫描一致性。这意味着结果会快速返回,但来自索引的数据可能还不包含来自先前写入操作的数据(称为最终一致性)。如果您需要查询的“准备好自己的写入”语义,则需要使用@ScanConsistency注释。这是一个例子:

示例 81. 使用不同的扫描一致性

代码语言:javascript
代码运行次数:0
复制
@Repository
public interface AirportRepository extends PagingAndSortingRepository<Airport, String> {

	@Override
	@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
	Iterable<Airport> findAll();

}

5.3.4.DTO 预测

Spring Data Repositories 通常在使用查询方法时返回域模型。但是,有时,您可能出于各种原因需要更改该模型的视图。在本节中,您将学习如何定义投影以提供简化和简化的资源视图。

看下面的域模型:

代码语言:javascript
代码运行次数:0
复制
@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 是指向另一个域对象的链接

现在假设我们创建一个相应的存储库,如下所示:

代码语言:javascript
代码运行次数:0
复制
interface PersonRepository extends CrudRepository<Person, Long> {

  Person findPersonByFirstName(String firstName);
}

Spring Data 将返回包含其所有属性的域对象。有两个选项可以检索address属性。一种选择是为这样的Address对象定义一个存储库:

代码语言:javascript
代码运行次数:0
复制
interface AddressRepository extends CrudRepository<Address, Long> {}

在这种情况下,usingPersonRepository仍然会返回整个Person对象。使用AddressRepository将只返回Address.

但是,如果您根本不想暴露address细节怎么办?您可以通过定义一个或多个投影来为您的存储库服务的使用者提供一种替代方案。

示例 82. 简单投影

代码语言:javascript
代码运行次数:0
复制
interface NoAddresses {  

  String getFirstName(); 

  String getLastName();  
}

此投影具有以下详细信息:

一个普通的 Java 接口,使其具有声明性。

导出firstName.

导出lastName.

该NoAddresses投影仅拥有干将firstName和lastName这意味着它不会成为的任何地址信息。在这种情况下,查询方法定义返回NoAdresses而不是Person.

代码语言:javascript
代码运行次数:0
复制
interface PersonRepository extends CrudRepository<Person, Long> {

  NoAddresses findByFirstName(String firstName);
}

投影声明了基础类型和与公开属性相关的方法签名之间的契约。因此需要根据底层类型的属性名称来命名 getter 方法。如果基础属性是 named firstName,那么 getter 方法必须被命名,getFirstName否则 Spring Data 无法查找源属性。

6. 反应式 Couchbase 存储库

6.1。介绍

本章描述了对 couchbase 的响应式存储库支持。这建立在Couchbase 存储库中解释的核心存储库支持之上。因此,请确保您对那里解释的基本概念有充分的理解。

6.2.反应式组合库

Couchbase Java SDK 3.x 从 RxJava 迁移到 Reactor,因此它与响应式 Spring 生态系统完美融合。

Reactive Couchbase 存储库提供项目 Reactor 包装器类型,并且可以通过简单地从特定于库的存储库接口之一扩展来使用:

  • ReactiveCrud 存储库
  • 反应式排序存储库

6.3.用法

让我们创建一个简单的实体开始:

示例 83. 示例 Person 实体

代码语言:javascript
代码运行次数:0
复制
public class Person {

  @Id
  private String id;
  private String firstname;
  private String lastname;
  private Address address;

  // … getters and setters omitted
}

相应的存储库实现可能如下所示:

示例 84. 持久化 Person 实体的基本存储库接口

代码语言:javascript
代码运行次数:0
复制
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

代码语言:javascript
代码运行次数:0
复制
@Configuration
@EnableReactiveCouchbaseRepositories
class ApplicationConfig extends AbstractCouchbaseConfiguration {
	// ... (see configuration for details)
}

随着我们的域存储库的扩展,ReactiveSortingRepository它为您提供了 CRUD 操作以及对实体进行排序访问的方法。使用存储库实例只是将依赖项注入客户端的问题。

示例 86. 对 Person 实体的排序访问

代码语言:javascript
代码运行次数:0
复制
public class PersonRepositoryTests {

    @Autowired
    ReactivePersonRepository repository;

    @Test
    public void sortsElementsCorrectly() {
      Flux<Person> persons = repository.findAll(Sort.by(new Order(ASC, "lastname")));
      assertNotNull(perons);
    }
}

6.4.存储库和查询

Spring Data 的 Reactive Couchbase 带有阻塞存储库和查询已经提供的完整查询支持

7. 模板&直接操作

该模板提供了对底层数据库的较低级别的访问,并且还用作存储库的基础。每当存储库对您的需要来说太高级时,模板将为您提供良好服务的机会很大。请注意,您始终可以通过在 AbstractCouchbaseConfiguration.

7.1。支持的操作

模板可以通过couchbaseTemplate和 reactiveCouchbaseTemplatebean访问您的上下文。一旦获得了对它的引用,就可以对它运行各种操作。除了通过存储库之外,您还需要在模板中始终指定要转换的目标实体类型。

模板使用流式 API,允许您根据需要链接可选运算符。例如,以下是您存储用户然后通过其 ID 再次找到它的方式:

示例 87. 流畅的模板访问

代码语言:javascript
代码运行次数:0
复制
// 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

代码语言:javascript
代码运行次数:0
复制
User modified = couchbaseTemplate
  .upsertById(User.class)
  .withDurability(DurabilityLevel.MAJORITY)
  .one(user);

以类似的方式,您可以执行 N1QL 操作:

示例 89. 模板上的 N1QL 查询

代码语言:javascript
代码运行次数:0
复制
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. 事务配置

代码语言:javascript
代码运行次数:0
复制
@Configuration
static class Config extends AbstractCouchbaseConfiguration {

    // Usual Setup
    @Override public String getConnectionString() { /* ... */ }
    @Override public String getUserName() { /* ... */ }
    @Override public String getPassword() { /* ... */ }
    @Override public String getBucketName() { /* ... */ }

	@Bean
	public 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. 事务访问

代码语言:javascript
代码运行次数:0
复制
@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. 写入时的事务转换

代码语言:javascript
代码运行次数:0
复制
@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. 读取时的事务转换

代码语言:javascript
代码运行次数:0
复制
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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 5.3.2.自动索引管理
  • 5.3.3.查询一致性
  • 5.3.4.DTO 预测
  • 6. 反应式 Couchbase 存储库
  • 6.1。介绍
  • 6.2.反应式组合库
  • 6.3.用法
  • 6.4.存储库和查询
  • 7. 模板&直接操作
  • 7.1。支持的操作
  • 8.交易支持
  • 8.1。要求
  • 8.2.入门和配置
  • 8.3.对象转换
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档