处理多样化的数据库结构通常会给系统架构带来显著的复杂性,尤其是当需要多个数据库实例时。这种碎片化可能会使操作变得复杂,增加成本并降低效率。像 ArangoDB 这样的多模型数据库提供了统一的解决方案来应对这些挑战。它们通过在单个数据库实例中支持多种数据模型——键值、文档和图——来简化架构并优化数据管理。
与关系型数据库不同,NoSQL 数据库并不遵循像 SQL 这样的通用标准。相反,它们是根据存储结构进行分类的。流行的类型包括:
- 键值:类似于 Java 的
Map
或 Python 字典,这种结构使用键来检索整个值作为 BLOB。 - 宽列:类似于键值,但将值拆分成列,提供更精细的数据检索。
- 文档:结构类似于 JSON 或 XML,这种类型提供更大的查询灵活性。
- 图:通过表示实体及其连接,支持复杂关系建模和查询。
多模型数据库将这些功能结合到一个系统中。例如,ArangoDB 支持键值、文档和图模型,消除了对单独数据库的需求。
本文演示如何使用 ArangoDB 在 Java 应用程序中通过 Jakarta NoSQL 探索键值和文档模型。
设置ArangoDB
要开始使用ArangoDB,Docker提供了一种简单的方式来管理第三方服务。通过运行以下命令,您可以轻松设置ArangoDB实例:
docker run -e ARANGO_NO_AUTH=1 -d --name arangodb-instance -p 8529:8529 arangodb/arangodb
探索键-值数据
键-值数据库非常适合简单的数据模型。让我们创建一个示例应用程序,使用ArangoDB的键-值功能来管理机场数据。 Airport
实体将包括两个字段:code
(ID)和 name
。
import jakarta.nosql.Column;
import jakarta.nosql.Entity;
import jakarta.nosql.Id;
import net.datafaker.Faker;
import net.datafaker.providers.base.Aviation;
import java.util.Objects;
public class Airport {
private String code;
private String name;
public String getCode() {
return code;
}
public String getName() {
return name;
}
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) {
return false;
}
Airport airport = (Airport) o;
return Objects.equals(code, airport.code);
}
public int hashCode() {
return Objects.hashCode(code);
}
public String toString() {
return "Airport{" +
"code='" + code + '\'' +
", name='" + name + '\'' +
'}';
}
public static Airport of(Faker faker) {
Aviation aviation = faker.aviation();
var airport = new Airport();
airport.code = aviation.airport();
airport.name = aviation.airport();
return airport;
}
}
定义了实体后,您可以使用 KeyValueTemplate
与数据库交互。在本教程中,我们将探索更多关于Jakarta NoSQL功能的内容,超越使用注释,使用 Eclipse JNoSQL;一旦Eclipse JNoSQL实现并支持Jakarta Data,您就可以创建存储库。
import jakarta.enterprise.inject.se.SeContainer;
import jakarta.enterprise.inject.se.SeContainerInitializer;
import net.datafaker.Faker;
import org.eclipse.jnosql.mapping.keyvalue.KeyValueTemplate;
public class App {
public static void main(String[] args) {
var faker = new Faker();
try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
KeyValueTemplate template = container.select(KeyValueTemplate.class).get();
var airport = template.put(Airport.of(faker));
System.out.println(template.get(airport.getCode(), Airport.class));
}
}
}
此程序会生成一个随机机场记录,将其插入数据库并检索它。如果您在本地运行,可以使用以下网址在浏览器中检查数据库中的值:
http://localhost:8529/_db/airport/_admin/aardvark/index.html#collections
处理文档数据
Jakarta NoSQL提供了丰富的功能,用于处理文档数据库,包括继承和分层数据建模支持。虽然NoSQL数据库通常不会固有地支持这些功能,但Jakarta NoSQL通过其API弥合了这一差距。让我们使用Jakarta NoSQL与ArangoDB一起管理云服务提供商数据,包括两个专业化:亚马逊云服务(AWS)和Azure。
Jakarta NoSQL使用@DiscriminatorColumn
、@DiscriminatorValue
和@Inheritance
注解来管理文档数据库中的继承。
@DiscriminatorColumn
注解指定用于在数据库文档中标识实体类型的字段。@DiscriminatorValue
注解定义了每个子类的特定值,确保它们被正确识别。@Inheritance
注解表示该类层次结构将被映射到数据库中。
首先,定义云服务提供商的基类:
"type") (
public class CloudProvider {
protected String id;
protected String region;
}
接下来,我们介绍专门的云服务提供商类。这些示例展示了Jakarta NoSQL如何利用注解@DiscriminatorValue
来区分不同的文档类型。每个专业化 – AWS和Azure – 都继承自基类CloudProvider
,同时定义了每个提供商独有的属性。此外,还提供了用于生成演示用样本数据的工厂方法(of
)。
AWSCloudProvider
import jakarta.nosql.Column;
import jakarta.nosql.DiscriminatorValue;
import jakarta.nosql.Entity;
import net.datafaker.Faker;
import java.util.UUID;
"AWS") (
public class AWSCloudProvider extends CloudProvider {
private String accountId;
public String getAccountId() {
return accountId;
}
public String toString() {
return "AWSCloudProvider{" +
"accountId='" + accountId + '\'' +
", id='" + id + '\'' +
", region='" + region + '\'' +
'}';
}
public static AWSCloudProvider of(Faker faker) {
var aws = faker.aws();
var cloudProvider = new AWSCloudProvider();
cloudProvider.region = aws.region();
cloudProvider.region = aws.region();
cloudProvider.id = UUID.randomUUID().toString();
cloudProvider.accountId = aws.accountId();
return cloudProvider;
}
}
AzureCloudProvider
package org.soujava.demos.arangodb.document;
import jakarta.nosql.Column;
import jakarta.nosql.DiscriminatorValue;
import jakarta.nosql.Entity;
import net.datafaker.Faker;
import java.util.UUID;
"AZURE") (
public class AzureCloudProvider extends CloudProvider {
private String tenantId;
public String getTenantId() {
return tenantId;
}
public String toString() {
return "AzureCloudProvider{" +
"tenantId='" + tenantId + '\'' +
", id='" + id + '\'' +
", region='" + region + '\'' +
'}';
}
public static AzureCloudProvider of(Faker faker) {
var azure = faker.azure();
var cloudProvider = new AzureCloudProvider();
cloudProvider.region = azure.region();
cloudProvider.region = azure.region();
cloudProvider.id = UUID.randomUUID().toString();
cloudProvider.tenantId = azure.tenantId();
return cloudProvider;
}
}
最后,让我们看看如何使用DocumentTemplate
与数据库进行交互。此代码演示了创建AWS和Azure提供者的实例,将它们插入数据库并检索它们。该实现利用Jakarta NoSQL的API来处理数据持久性,确保在存储和检索过程中无缝应用继承和区分逻辑。
import jakarta.enterprise.inject.se.SeContainer;
import jakarta.enterprise.inject.se.SeContainerInitializer;
import net.datafaker.Faker;
import org.eclipse.jnosql.mapping.document.DocumentTemplate;
import java.util.List;
import java.util.logging.Logger;
public class App {
private static final Logger LOGGER = Logger.getLogger(App.class.getName());
public static void main(String[] args) {
var faker = new Faker();
LOGGER.info("Starting the application");
try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
var template = container.select(DocumentTemplate.class).get();
LOGGER.info("Creating 10 documents");
for (int index = 0; index < 5; index++) {
template.insert(List.of(AWSCloudProvider.of(faker), AzureCloudProvider.of(faker)));
}
System.out.println("The cloud providers here");
template.select(CloudProvider.class).stream().forEach(System.out::println);
System.out.println("The AWS cloud providers here");
template.select(AWSCloudProvider.class).stream().forEach(System.out::println);
System.out.println("The Azure cloud providers here");
template.select(AzureCloudProvider.class).stream().forEach(System.out::println);
}
}
private App() {
}
}
结论
ArangoDB的多模型能力使其成为现代应用程序的多功能选择。在单一数据库中结合键值和文档模型简化了您的数据架构,同时保持灵活性。借助Jakarta NoSQL,将ArangoDB集成到Java应用程序中变得无缝,利用熟悉的注解和编程范式。
要查看完整代码,请访问GitHub仓库。
Source:
https://dzone.com/articles/arangodb-success-through-multivalue-database