O manuseio de estruturas de banco de dados diversas frequentemente introduz complexidade significativa na arquitetura do sistema, especialmente quando são necessárias múltiplas instâncias de banco de dados. Essa fragmentação pode complicar as operações, aumentar os custos e reduzir a eficiência. Bancos de dados multimodelo como o ArangoDB oferecem uma solução unificada para lidar com esses desafios. Eles simplificam a arquitetura e otimizam a gestão de dados ao suportar múltiplos modelos de dados — chave-valor, documento e grafo — dentro de uma única instância de banco de dados.
Ao contrário dos bancos de dados relacionais, os bancos de dados NoSQL não seguem um padrão universal como o SQL. Em vez disso, são categorizados com base em sua estrutura de armazenamento. Entre os tipos populares estão:
- Chave-valor: Semelhante a um
Map
em Java ou um dicionário em Python, essa estrutura recupera valores inteiros como BLOBs usando uma chave. - Coluna-larga: Similar ao chave-valor, mas divide os valores em colunas, oferecendo uma recuperação de dados mais granular.
- Documento: Estruturado como JSON ou XML, esse tipo fornece maior flexibilidade de consulta.
- Grafo: Permite a modelagem e consulta de relacionamentos complexos ao representar entidades e suas conexões.
Um banco de dados multimodelo combina essas capacidades em um único sistema. Por exemplo, o ArangoDB suporta modelos chave-valor, documento e grafo, eliminando a necessidade de bancos de dados separados.
Este artigo demonstra como usar o ArangoDB para explorar os modelos chave-valor e documento em aplicações Java usando o Jakarta NoSQL.
Configurando o ArangoDB
Para iniciar com o ArangoDB, o Docker fornece uma maneira direta de gerenciar serviços de terceiros. Ao executar o seguinte comando, você pode configurar uma instância do ArangoDB facilmente:
docker run -e ARANGO_NO_AUTH=1 -d --name arangodb-instance -p 8529:8529 arangodb/arangodb
Explorando Dados Chave-Valor
Bancos de dados chave-valor são ideais para modelos de dados simples. Vamos criar um aplicativo de exemplo para gerenciar dados de aeroportos usando as capacidades chave-valor do ArangoDB. A entidade Airport
incluirá dois campos: code
(ID) e 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;
}
}
Com a entidade definida, você pode usar o KeyValueTemplate
para interagir com o banco de dados. Neste tutorial, vamos explorar mais a capacidade do Jakarta NoSQL além das anotações usando o Eclipse JNoSQL; você pode criar o repositório uma vez que o Eclipse JNoSQL implemente e suporte o 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));
}
}
}
Este programa gera um registro aleatório de aeroporto, o insere no banco de dados e o recupera. Se estiver executando localmente, você pode verificar os valores no banco de dados usando seu navegador com a URL:
http://localhost:8529/_db/airport/_admin/aardvark/index.html#collections
Trabalhando com Dados de Documentos
O Jakarta NoSQL oferece recursos avançados para trabalhar com bancos de dados de documentos, incluindo suporte para herança e modelagem de dados hierárquicos. Embora os bancos de dados NoSQL geralmente não suportem esses recursos inerentemente, o Jakarta NoSQL preenche essa lacuna com sua API. Vamos usar o Jakarta NoSQL com o ArangoDB para gerenciar dados de provedores de nuvem, incluindo duas especializações: Amazon Web Services (AWS) e Azure.
O Jakarta NoSQL usa as anotações @DiscriminatorColumn
, @DiscriminatorValue
e @Inheritance
para gerenciar herança em bancos de dados de documentos.
- A anotação
@DiscriminatorColumn
especifica o campo usado para identificar um tipo de entidade no documento do banco de dados. - A anotação
@DiscriminatorValue
define o valor específico para cada subclasse, garantindo que sejam corretamente identificadas. - A anotação
@Inheritance
indica que a hierarquia de classes será mapeada no banco de dados.
Primeiro, defina a classe base para provedores de nuvem:
"type") (
public class CloudProvider {
protected String id;
protected String region;
}
Em seguida, introduzimos as classes especializadas de provedores de nuvem. Esses exemplos mostram como o Jakarta NoSQL aproveita as anotações @DiscriminatorValue
para distinguir entre diferentes tipos de documentos. Cada especialização – AWS e Azure – herda da classe base CloudProvider
, além de definir atributos únicos para cada provedor. Além disso, métodos de fábrica (of
) são fornecidos para gerar dados de exemplo para fins de demonstração.
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;
}
}
Por fim, vamos ver como usar o DocumentTemplate
para interagir com o banco de dados. Este código demonstra a criação de instâncias dos provedores AWS e Azure, inserindo-os no banco de dados e recuperando-os. A implementação utiliza a API do Jakarta NoSQL para lidar com a persistência de dados, garantindo que a lógica de herança e discriminador seja aplicada de forma transparente durante o armazenamento e recuperação.
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() {
}
}
Conclusão
As capacidades multimodelo do ArangoDB o tornam uma escolha versátil para aplicações modernas. Combinar modelos chave-valor e de documentos em um único banco de dados simplifica a arquitetura de seus dados enquanto mantém a flexibilidade. Com o Jakarta NoSQL, integrar o ArangoDB em aplicativos Java se torna fácil, aproveitando anotações e paradigmas de programação familiares.
Para ver o código completo, visite o Repositório GitHub.
Source:
https://dzone.com/articles/arangodb-success-through-multivalue-database