共计 5903 个字符,预计需要花费 15 分钟才能阅读完成。
原题目:Spring 认证中国教育管理中心 -Spring Data Couchbase 教程一(Spring 中国教育管理中心)
Spring Data Couchbase 教程一
1.1 装置
所有用于生产的版本都散布在 Maven Central 和 Spring 公布存储库中。因而,能够像任何其余 maven 依赖项一样蕴含该库:
示例 1. 通过 maven 蕴含依赖
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-couchbase</artifactId>
<version>4.2.5</version>
</dependency>
这将引入几个依赖项,包含底层的 Couchbase Java SDK、常见的 Spring 依赖项以及 Jackson 作为 JSON 映射基础设施。
您还能够从 Spring 快照存储库(
https://repo.spring.io/libs-s…) 中获取快照,并从 Spring 里程碑存储库(https://repo.spring.io/libs-m…) 中获取里程碑版本。这是一个对于如何应用以后 SNAPSHOT 依赖项的示例:
示例 2. 应用快照版本
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-couchbase</artifactId>
<version>4.3.0-SNAPSHOT</version>
</dependency>
<repository>
<id>spring-libs-snapshot</id>
<name>Spring Snapshot Repository</name>
<url>https://repo.spring.io/libs-s…</url>
</repository>
一旦你在类门路上取得了所有须要的依赖项,你就能够开始配置它了。仅反对 Java 配置(XML 配置已在 4.0 中删除)。
1.2. 基于注解的配置(“JavaConfig”)
要开始,您须要做的就是子类化
AbstractCouchbaseConfiguration 并实现形象办法。
示例 3. 扩大
AbstractCouchbaseConfiguration
@Configuration
public class Config extends AbstractCouchbaseConfiguration {
@Override
public String getConnectionString() {return "couchbase://127.0.0.1";}
@Override
public String getUserName() {return "Administrator";}
@Override
public String getPassword() {return "password";}
@Override
public String getBucketName() {return "travel-sample";}
}
Spring Data Couchbase 教程一
连贯字符串由主机列表和可选计划 (couchbase://) 组成,如下面的代码所示。您须要提供的只是要疏导到的 Couchbase 节点列表(用 分隔,)。请留神,尽管在开发中一台主机就足够了,但倡议在此处增加 3 到 5 个疏导节点。Couchbase 将主动从集群中获取所有节点,但您提供的惟一节点可能会在您启动应用程序时遇到问题。
该 userName 和 password 在你的 Couchbase Server 群集通过 RBAC(基于角色的访问控制)配置。在 bucketName 反映您要应用该配置桶。
此外,SDK 环境能够通过笼罩返回配置的 configureEnvironment 办法 来调整。
ClusterEnvironment.BuilderClusterEnvironment
更多的货色能够从这个配置中作为自定义 bean 进行自定义和笼罩(例如存储库、验证和自定义转换器)。
如果您应用 SyncGatewayand CouchbaseMobile,您可能会遇到以_. 为前缀的字段的问题。因为默认状况下 Spring Data Couchbase 将类型信息存储为_class 属性,这可能会呈现问题。笼罩 typeKey()(例如返回
MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE)以更改所述属性的名称。
如果您启动应用程序,您应该会在日志中看到 Couchbase INFO 级别的日志记录,这表明底层 Couchbase Java SDK 正在连接到数据库。如果报告任何谬误,请确保给定的凭据和主机信息正确。
- 建模实体
本章形容如何对实体建模并解释它们在 Couchbase 服务器自身中的对应示意。
2.1 对象映射根底
本节涵盖 Spring Data 对象映射、对象创立、字段和属性拜访、可变性和不变性的基础知识。请留神,本节仅实用于不应用底层数据存储(如 JPA)的对象映射的 Spring Data 模块。还请务必查阅特定于存储的局部以获取特定于存储的对象映射,例如索引、自定义列或字段名称等。
Spring Data 对象映射的外围职责是创立域对象的实例并将 store-native 数据结构映射到这些实例上。这意味着咱们须要两个根本步骤:
应用公开的构造函数之一创立实例。
实例填充以实现所有公开的属性。
2.1.1 对象创立
Spring Data 主动尝试检测长久实体的构造函数以用于实现该类型的对象。解析算法的工作原理如下:
如果只有一个构造函数,则应用它。
如果有多个构造函数并且恰好一个用 正文 @PersistenceConstructor,则应用它。
如果有无参数构造函数,则应用它。其余构造函数将被疏忽。
值解析假设结构函数参数名称与实体的属性名称匹配,即解析将像要填充属性一样执行,包含映射中的所有自定义(不同的数据存储列或字段名称等)。这还须要类文件中可用的参数名称信息或 @ConstructorProperties 构造函数上存在的正文。
能够应用 Spring Framework 的 @Valuevalue annotation 应用 store-specific SpEL 表达式来自定义 value 解析。
对象创立外部
为了防止反射的开销,Spring Data 对象创立默认应用运行时生成的工厂类,它会间接调用畛域类的构造函数。即对于这个示例类型:
class Person {
Person(String firstname, String lastname) {…}
}
咱们将在运行时创立一个在语义上等同于这个的工厂类:
class PersonObjectInstantiator implements ObjectInstantiator {
Object newInstance(Object… args) {
return new Person((String) args[0], (String) args[1]);
}
}
与反射相比,这给了咱们大概 10% 的性能晋升。要使域类有资格进行此类优化,它须要恪守一组束缚:
它不能是私人课程
它不能是非动态外部类
它不能是 CGLib 代理类
Spring Data 应用的构造函数不能是公有的
如果这些条件中的任何一个匹配,Spring Data 将通过反射回退到实体实例化。
2.1.2. 物业人口
一旦创立了实体的实例,Spring Data 就会填充该类的所有残余长久属性。除非曾经由实体的构造函数填充(即通过其结构函数参数列表应用),否则将首先填充标识符属性以容许解析循环对象援用。之后,在实体实例上设置所有尚未由构造函数填充的非瞬态属性。为此,咱们应用以下算法:
如果属性是不可变的但公开了一个 with…办法(见下文),咱们应用该 with…办法创立一个具备新属性值的新实体实例。
如果定义了属性拜访(即通过 getter 和 setter 拜访),咱们将调用 setter 办法。
如果属性是可变的,咱们间接设置字段。
如果属性是不可变的,咱们将应用持久性操作(请参阅对象创立)应用的构造函数来创立实例的正本。
默认状况下,咱们间接设置字段值。
Property population internals
与咱们在对象结构中的优化相似,咱们还应用 Spring Data 运行时生成的拜访器类与实体实例进行交互。
class Person {
private final Long id;
private String firstname;
private @AccessType(Type.PROPERTY) String lastname;
Person() {
this.id = null;
}
Person(Long id, String firstname, String lastname) {
// Field assignments
}
Person withId(Long id) {
return new Person(id, this.firstname, this.lastame);
}
void setLastname(String lastname) {
this.lastname = lastname;
}
}
示例 4. 生成的属性拜访器
class PersonPropertyAccessor implements PersistentPropertyAccessor {
private static final MethodHandle firstname;
private Person person;
public void setProperty(PersistentProperty property, Object value) {
String name = property.getName();
if ("firstname".equals(name)) {firstname.invoke(person, (String) value);
} else if ("id".equals(name)) {this.person = person.withId((Long) value);
} else if ("lastname".equals(name)) {this.person.setLastname((String) value);
}
}
}
PropertyAccessor 持有底层对象的可变实例。这是为了启用其余不可变属性的渐变。
默认状况下,Spring Data 应用字段拜访来读取和写入属性值。依据 private 字段的可见性规定,MethodHandles 用于与字段交互。
该类公开了一个 withId(…)用于设置标识符的办法,例如,当将实例插入数据存储并生成标识符时。调用 withId(…)会创立一个新 Person 对象。所有后续的渐变都将产生在新的实例中,而前一个不变。
应用属性拜访容许间接办法调用而不应用 MethodHandles.
与反射相比,这给了咱们大概 25% 的性能晋升。要使域类有资格进行此类优化,它须要恪守一组束缚:
类型不得位于默认值或 java 包下。
类型及其构造函数必须是 public
作为外部类的类型必须是 static.
应用的 Java 运行时必须容许在原始 ClassLoader. Java 9 和更高版本施加了某些限度。
默认状况下,Spring Data 尝试应用生成的属性拜访器,如果检测到限度,则回退到基于反射的拜访器。
让咱们看一下以下实体:
示例 5. 示例实体
class Person {
private final @Id Long id;
private final String firstname, lastname;
private final LocalDate birthday;
private final int age;
private String comment;
private @AccessType(Type.PROPERTY) String remarks;
static Person of(String firstname, String lastname, LocalDate birthday) {
return new Person(null, firstname, lastname, birthday,
Period.between(birthday, LocalDate.now()).getYears());
}
Person(Long id, String firstname, String lastname, LocalDate birthday, int age) {
this.id = id;
this.firstname = firstname;
this.lastname = lastname;
this.birthday = birthday;
this.age = age;
}
Person withId(Long id) {
return new Person(id, this.firstname, this.lastname, this.birthday, this.age);
}
void setRemarks(String remarks) {
this.remarks = remarks;
}
}
Spring Data Couchbase 教程一
标识符属性是最终的,但 null 在构造函数中设置为。该类公开了一个 withId(…)用于设置标识符的办法,例如,当将实例插入数据存储并生成标识符时。Person 创立新实例时,原始实例放弃不变。雷同的模式通常实用于存储管理但可能必须更改以进行持久性操作的其余属性。wither 办法是可选的,因为持久性构造函数(参见 6)实际上是一个复制构造函数,并且设置属性将被转换为创立一个利用了新标识符值的新实例。
的 firstname 和 lastname 个性是通过吸气剂可能裸露一般不可变属性。
该 age 属性是不可变的,但从该属性派生而来 birthday。应用所示的设计,数据库值将胜过默认值,因为 Spring Data 应用惟一申明的构造函数。即便用意是应该首选计算,重要的是此构造函数也将其 age 作为参数(可能会疏忽它),否则属性填充步骤将尝试设置年龄字段并因为它是不可变的且没有 with…办法而失败在场。
该 comment 属性是可变的,通过间接设置其字段来填充。
的 remarks 个性是可变的,并且通过设置填充 comment 间接字段或通过调用用于 setter 办法
该类公开了一个工厂办法和一个用于创建对象的构造函数。这里的核心思想是应用工厂办法而不是额定的构造函数来防止构造函数通过 @PersistenceConstructor. 相同,属性的默认设置是在工厂办法中解决的。