Het omgaan met diverse databasestructuren introduceert vaak aanzienlijke complexiteit in de systeemarchitectuur, vooral wanneer meerdere database-instanties vereist zijn. Deze fragmentatie kan de operaties compliceren, kosten verhogen en de efficiëntie verminderen. Multimodel databases zoals ArangoDB bieden een eenduidige oplossing om deze uitdagingen aan te pakken. Ze vereenvoudigen de architectuur en stroomlijnen het gegevensbeheer door meerdere gegevensmodellen — sleutel-waarde, document en grafiek — te ondersteunen binnen één database-instantie.
In tegenstelling tot relationele databases, NoSQL-databases houden zich niet aan een universele standaard zoals SQL. In plaats daarvan worden ze gecategoriseerd op basis van hun opslagstructuur. Onder de populaire typen zijn:
- Sleutel-waarde: Vergelijkbaar met een Java
Map
of een Python-dictionary, haalt deze structuur volledige waarden op als BLOBs met behulp van een sleutel. - Brede kolom: Vergelijkbaar met sleutel-waarde maar splitst waarden in kolommen, waardoor meer gedetailleerde gegevensopvraging mogelijk is.
- Document: Gestructureerd als JSON of XML, biedt dit type meer queryflexibiliteit.
- Grafiek: Maakt complexe relatiemodellering en query’s mogelijk door entiteiten en hun verbindingen voor te stellen.
Een multimodel database combineert deze mogelijkheden in één systeem. Zo ondersteunt ArangoDB bijvoorbeeld sleutel-waarde, document en grafiekmodellen, waardoor de noodzaak voor afzonderlijke databases verdwijnt.
Dit artikel demonstreert hoe ArangoDB te gebruiken om sleutel-waarde en documentmodellen te verkennen in Java-toepassingen met behulp van Jakarta NoSQL.
ArangoDB Instellen
Om te beginnen met ArangoDB, biedt Docker een eenvoudige manier om services van derden te beheren. Door de volgende opdracht uit te voeren, kun je eenvoudig een ArangoDB-instantie opzetten:
docker run -e ARANGO_NO_AUTH=1 -d --name arangodb-instance -p 8529:8529 arangodb/arangodb
Verkenning van Sleutel-Waarde Gegevens
Sleutel-waarde databases zijn ideaal voor eenvoudige datamodellen. Laten we een voorbeeldapplicatie maken om luchthavengegevens te beheren met behulp van de sleutel-waarde mogelijkheden van ArangoDB. De Luchthaven
entiteit zal twee velden bevatten: code
(ID) en naam
.
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;
}
}
Met de entiteit gedefinieerd, kun je KeyValueTemplate
gebruiken om met de database te communiceren. In deze tutorial zullen we meer van de Jakarta NoSQL-mogelijkheden verkennen, naast de annotaties met behulp van Eclipse JNoSQL; je kunt de repository aanmaken zodra Eclipse JNoSQL Jakarta Data implementeert en ondersteunt.
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));
}
}
}
Dit programma genereert een willekeurige luchthavenregistratie, voegt deze toe aan de database en haalt deze op. Als je lokaal werkt, kun je de waarden in de database controleren met je browser via de URL:
http://localhost:8529/_db/airport/_admin/aardvark/index.html#collections
Werken met Documentgegevens
Jakarta NoSQL biedt rijke functies voor het werken met documentdatabases, waaronder ondersteuning voor overerving en hiërarchische datamodellering. Hoewel NoSQL-databases over het algemeen deze functies niet van nature ondersteunen, overbrugt Jakarta NoSQL deze kloof met zijn API. Laten we Jakarta NoSQL gebruiken met ArangoDB om gegevens van cloudproviders te beheren, inclusief twee specialisaties: Amazon Web Services (AWS) en Azure.
Jakarta NoSQL gebruikt de @DiscriminatorColumn
, @DiscriminatorValue
en @Inheritance
annotaties om overerving in documentdatabases te beheren.
- De
@DiscriminatorColumn
annotatie specificeert het veld dat wordt gebruikt om een entiteitstype in het database-document te identificeren. - De
@DiscriminatorValue
annotatie definieert de specifieke waarde voor elke subklasse, waardoor ze correct worden geïdentificeerd. - De
@Inheritance
annotatie geeft aan dat de klassenhiërarchie in de database zal worden gemapt.
Eerst definiëren we de basisclass voor cloudproviders:
"type") (
public class CloudProvider {
protected String id;
protected String region;
}
Vervolgens introduceren we de gespecialiseerde cloudproviderklassen. Deze voorbeelden tonen aan hoe Jakarta NoSQL annotaties @DiscriminatorValue
gebruikt om te onderscheiden tussen verschillende documenttypen. Elke specialisatie — AWS en Azure — erft van de basis CloudProvider
klasse, terwijl ook unieke attributen voor elke provider worden gedefinieerd. Bovendien worden fabrieksmethoden (of
) aangeboden om voorbeeldgegevens te genereren voor demonstratiedoeleinden.
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;
}
}
Tenslotte, laten we zien hoe we de DocumentTemplate
kunnen gebruiken om te communiceren met de database. Deze code toont het aanmaken van instanties van AWS en Azure providers, deze invoegen in de database en ze ophalen. De implementatie maakt gebruik van de API van Jakarta NoSQL om dataperistentie te beheren, zodat overerving en discriminatorlogica naadloos worden toegepast tijdens opslag en ophalen.
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() {
}
}
Conclusie
De multimodelmogelijkheden van ArangoDB maken het een veelzijdige keuze voor moderne toepassingen. Door key-value en documentmodellen te combineren in een enkele database wordt de data-architectuur vereenvoudigd terwijl de flexibiliteit behouden blijft. Met Jakarta NoSQL wordt het integreren van ArangoDB in Java-toepassingen naadloos, waarbij vertrouwde annotaties en programmeerparadigma’s worden benut.
Voor de volledige code, bezoek de GitHub Repository.
Source:
https://dzone.com/articles/arangodb-success-through-multivalue-database