BT

Diffuser les Connaissances et l'Innovation dans le Développement Logiciel d'Entreprise

Contribuez

Sujets

Sélectionner votre région

Accueil InfoQ Articles NoSQL, Le Cloud Et Java : Seconde Partie, Les Plateformes NoSQL

NoSQL, Le Cloud Et Java : Seconde Partie, Les Plateformes NoSQL

Favoris

Points Clés

  • Qu'est-ce qu'une plateforme NoSQL pour Java ?

  • Les composants d'une plateforme NoSQL

  • Exemples de plates-formes NoSQL

Dans le monde des solutions NoSQL avec Java, il existe plusieurs solutions et de différents types, ce qui était le cœur de la première partie de cet article. Cependant, en plus des points clés, il existe également des plates-formes. Les plates-formes sont un ensemble d'outils qui aident à travailler avec les bases de données NoSQL. Dans cet article, nous aurons pour objectif de parler des plateformes : la définition et les solutions existantes dans l'environnement Java actuel.

Un point important pour démarrer la discussion sur les plates-formes NoSQL est que, comme la description NoSQL elle-même, il n'y a pas de définition unique. Il peut différer selon la littérature et l'expérience de chaque auteur. De manière générale, les plates-formes de solutions NoSQL sont un ensemble d'outils permettant de gérer les bases de données. Autrement dit, en plus de l'API, il y aura d'autres outils.

En pensant aux plates-formes existantes, elles sont composées de quatre points, en plus de l'API elle-même :

  • Injection de dépendance: il s'agit d'un framework basé sur un conteneur pour soit l'injection de dépendance, soit l'inversion de contrôle pour faciliter le couplage faible entre les différents modules de l'application.

  • Template: pensez à une API de mapping. Son objectif principal est d'interpréter les opérations avec une ou plusieurs bases de données pour réduire la courbe d'apprentissage et les erreurs ou bugs.

  • Interfaces pour repository : pensez à DDD, il serait chargé de capturer le domaine de l'entité et d'abstraire, totalement ou partiellement, l'implémentation pour le développeur Java. Par exemple, l'utilisateur du framework crée une interface, développe certaines méthodes et la plate-forme elle-même sera responsable de la mise en œuvre de ces fonctionnalités.

  • Configuration : nous avons appris de The Twelve-Factor l'importance de ne pas laisser d'informations critiques comme le nom d'utilisateur et le mot de passe codés en dur. L'objectif principal de cet outil au sein de la Solution est de faciliter cette bonne pratique du troisième facteur : la configuration.

En réfléchissant à ces scénarios, nous pouvons énumérer cinq solutions de plate-forme dans le monde Java et NoSQL que nous avons actuellement :

Comme l'objectif de cet article sera d'obtenir un aperçu des plates-formes, dans ce premier point, seuls les composants seront explorés avec une simple démonstration de l'API utilisant MongoDB et une entité Philosopher avec quelques attributs.

Hibernate OGM

Hibernate OGM  suit le principe d'une solution basée sur une API bien connue du développeur Java lorsque le sujet est la persistance des données qui est JPA. Ainsi, son grand avantage est d'avoir un niveau d'apprentissage concis puisque, en général, le développeur connaît déjà cette API.

Cependant, l'émulation a tendance à être un fardeau dans certaines solutions, par exemple, les transactions au sein de Cassandra ou les relations étant implicitement indiquées au lieu de la dénormalisation. La même chose se produit avec les bases qui prennent en charge les transactions. Bien qu'il prenne en charge cette fonctionnalité, MongoDB n'est pas très adapté pour être utilisé avec une grande fréquence car cette fonctionnalité est associée à un coût de traitement énorme.

Avantages:

  • Il utilise une API déjà connue de la communauté Java

  • Faible courbe d'apprentissage

  • L'utilisation de JPQL

Désavantages:

  • Une API créée pour les bases de données relationnelles utilisées dans une base de données NoSQL génère une impédance encore plus grande, ce qui entraîne des pertes plus importantes en coûts de calcul.

Dependency Injection

CDI

Template

JPA API

Repository

-----

Configuration (3eme des 12 facteurs)

-----

Metadata

Reflection

La première étape dans l'utilisation d'Hibernate est la configuration, donc le classique persistence.xml. Comme mentionné ci-dessus, cela a tendance à rendre difficile l'utilisation de la configuration en dehors du code.

<persistence-unit name="ogm-mongodb" transaction-type="JTA">
    <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>
    <properties>
        <property name="hibernate.ogm.datastore.provider" value="MONGODB" />
        <property name="hibernate.ogm.datastore.database" value="TestDB" />
        <property name="hibernate.ogm.datastore.create_database" value="true" />
    </properties>
</persistence-unit>

La prochaine étape est la création et la modélisation de l'entité Philosopher. Comme déjà mentionné, rien de très nouveau pour un développeur qui a déjà une expérience avec JPA.

@Entity
public class Philosopher {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String id;
    private String name;
    @ManyToOne
    private Book books;
}

Dans le dernier exemple de code, il y a utilisation et interaction avec une base de données. Le point d’entrée, tout comme dans JPA, se fera avec un  EntityManager.

Philosopher socrates = ...;
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("ogm-mongodb");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transactionManager.begin();
entityManager.persist(socrates);
transaction.commit();
entityManager.close();

Quarkus

Quarkus est l'une des solutions qui a gagné en popularité ces dernières années. Il repose sur une solution qui évite la réflexion pour améliorer à la fois le démarrage et la consommation initiale de mémoire. Red Hat, en tant que sponsor principal, indique que sa caractéristique la plus importante est une API plus conviviale et proche des normes existantes dans le monde Java.

Avantages:

  • Quarkus est très proche des standards. L'API existe déjà dans le monde Java, comme MicroProfile et Jakarta EE.

  • La solution prend en charge à la fois le concept de Repository et ActiveRecord

Désavantages:

  • La prise en charge de NoSQL sur Quarkus est encore limitée.

Dependency Injection

Quarkus DI (CDI like)

Template

Active Record

Repository

PanacheMongoRepository

Configuration (3eme des 12 facteurs)

MicroProfile Configuration

Metadata

Quarkus extension (Compilation time)

La première étape est la configuration; après la configuration de MicroProfile, il est possible de placer ces informations, par exemple, dans un fichier de propriétés à utiliser dans l'environnement local et peut être écrasé pour une utilisation en production.

quarkus.mongodb.connection-string = mongodb://localhost:27017

La classe Philiosopher avec Quarkus prend en charge Active Record, il est donc possible de placer des opérations dans l'entité. Cette fonctionnalité est intéressante pour sa simplicité. Cependant, il y a le problème de la responsabilité exclusive. Cette fonctionnalité vient grâce à Panache.

public class Philosopher extends PanacheMongoEntity {
    public String name;
    public List<String> quotes;

    public static Philosopher findByName(String name){
        return find("name", name).firstResult();
    }
}

En plus des opérations Active Record, il existe la possibilité de ne pas utiliser cette ressource ou d'utiliser cette ressource en conjonction avec un concept de Repository.

@ApplicationScoped
public class PhilosopherRepository implements PanacheMongoRepository<Philosopher> {
   public Philosopher findByName(String name){
       return find("name", name).firstResult();
   }
}

Dans l'interaction, il est possible de voir qu'il sera possible d’utiliser à la fois l'active record  et le  repository.

Philosopher aristotle = ...;
aristotle.persist();
aristotle.update();
aristotle.delete();

repository.persist(aristotle);
repository.update(aristotle);
repository.delete(aristotle);

Micronaut

Parmi les solutions existantes qui évitent d'utiliser la Reflection, jusqu'à présent, c'est la solution la plus efficace en matière de moteur d’injection ou d'inversion de contrôle. Pour ceux qui sont habitués aux API comme Reflection et aimeraient connaître un peu les API natives, Micronaut est un moyen naturel (bien que, actuellement, il existe des travaux pour que Spring prenne en charge le mode natif).

Avantages:

  • Micronaut se caractérise par une API très proche des standards actuels, par exemple Spring.

Désavantages:

  • La prise en charge des bases de données NoSQL est encore limitée par rapport aux suivantes.

Dependency Injection

Micronaut IoC

Template

Mongo Client

Repository

---

Configuration (3eme des 12 facteurs)

Micronaut Configuration

Metadata

Java Annotation Processing

La configuration de Micronaut suivra la même ligne que les frameworks prenant en charge ce type de fonctionnalité, il est donc possible de mettre en œuvre les avantages du troisième facteur pour une application. La classe d'entité n'a besoin que de l'annotation Introspected.

@Introspected
public class Philosopher {
    private String name;
    private List<String> quotes;
    //getter and setter
}

Comme mentionné précédemment, Micronaut n'a pas beaucoup de support pour les bases de données NoSQL. Il utilise MongoClient, qui est une API au niveau de la communication.

public class PhilosopherService {

    private final MongoClient mongoClient;

    public PhilosopherService(MongoClient mongoClient) {
        this.mongoClient = mongoClient;
    }
    public Philosopher show(String name) {
        Bson filter = Filters.eq("name", name);
        return getCollection().find(filter).first();
    }

    public Iterable<Philosopher> findAll() {
        final FindIterable<Philosopher> iterable = getCollection().find();
        return StreamSupport.stream(iterable.spliterator(), false)
            .collect(Collectors.toList());
    }

    public void save(Philosopher philosopher) {
       getCollection().insertOne(philosopher);
    }

    private MongoCollection<Philosopher> getCollection() {
        return mongoClient
            .getDatabase("main")
            .getCollection("Philosopher", Philosopher.class);
    }
}

Spring

Parmi les plates-formes qui prennent en charge NoSQL dans le monde Java, Spring est sans aucun doute la plate-forme avec le support le plus important possible des bases de données. Il a la maturité la plus fantastique et est la solution qui a le support le plus remarquable des fonctionnalités spécifiques de diverses bases de données NoSQL.

Avantages:

  • La plate-forme la plus mature et la plus ingénieuse pour ce qui concerne Java et NoSQL.

  • Intègre et prend en charge tous les composants de la famille Spring

Désavantages:

  • Comme Spring est l'un des outils les plus innovants, il a tendance à rompre plus souvent la compatibilité, comme il l'a fait dans la version 2.0 de Spring Data.

Dependency Injection

Spring IoC

Template

MongoTemplate

Repository

PagingAndSortingRepository

Configuration (3eme des 12 facteurs)

Spring Configuration

Metadata

Reflection

La configuration des paramètres fonctionne de manière très similaire à celle du Micronaut, y compris la flexibilité de configuration. L'annotation est très claire. Il a besoin de l'annotation Document pour définir la classe et de l'annotation Id pour définir l'ID de l'entité.

@Document
public class Philosopher {
    @Id
    private String id;
    private String name;
    private List<String> quotes;
    //getter and setter
}

L'API MongoDB dans Spring prend en charge à la fois le concept de Repository et l'utilisation de modèles avec la classe MongoTemplate. En plus d'utiliser un Repository qui fonctionne comme par magie pour le développeur : il est nécessaire de créer l'interface, et toute l'implémentation sera de la responsabilité de Spring.

@Repository
public interface PhilosopherRepository extends MongoRepository<Philosopher, String> {
}

Philosopher plato = ...;
mongodbTemplate.insert(plato);
mongodbTemplate.update(plato);
repository.save(plato);
repository.delete(plato);
repository.findOne(plato.getId());

Jakarta NoSQL

Jakarta NoSQL est la première spécification du processus Jakarta EE. Son but est de réaliser une intégration entre Java et NoSQL. Sa caractéristique la plus incroyable est d'utiliser les meilleures pratiques et outils disponibles sur le marché.

Avantages:

  • Il s'inspire des bonnes pratiques du marché, telles que la fonctionnalité Repository de Spring.

  • Il intègre et prend en charge tous les composants de la famille Jakarta EE / MicroProfile

Désavantages:

  • Jakarta NoSQL n'est pas encore dans la version finale, il est donc toujours susceptible d’avoir des modifications dans  l'API.

Dependency Injection

CDI

Template

Template

Repository

Repository

Configuration (3eme des 12 facteurs)

MicroProfile Config

Metadata

Reflection and Annotation Processor (WIP)

La configuration et sa flexibilité dépendent du MicroProfile Config, donc du même principe que Quarkus. Les entités ont le même vocabulaire JPA. Cependant, ils utilisent l'annotation elle-même. Le point critique est que, contrairement à JPA, il est essentiel d’annoter tous les champs qui seront rendus persistants.

@Entity
public class Philosopher {
    @Id
    private String id;
    @Column
    private String name;
    @Column
    private List<String> quotes;
}

Comme mentionné précédemment, Jakarta NoSQL utilise Spring Data comme source d'inspiration à plusieurs endroits, y compris la fonctionnalité Repository.

@Repository
public interface PhilosopherRepository extends Repository<Philosopher, String> {

}

Il est donc possible d'utiliser à la fois la ressource template avec la classe DocumentTemplate et la ressource Repository. Un avantage non négligeable de cette API est de faciliter les échanges entre bases de données. En général, il est possible de basculer entre les documents de base de données, par exemple, MongoDB à ArangoDB, avec le moins d'impact possible.

Philosopher thalesMiletus = ...;
mongodbTemplate.insert(thalesMiletus);
mongodbTemplate.update(thalesMiletus);

repository.save(thalesMiletus);
repository.delete(thalesMiletus);
repository.findById(thalesMiletus.getId());

Conclusion

Dans cet article, nous avons discuté de ce que sont les plates-formes, des composants minimum d'une plate-forme et de quelques exemples dans l'environnement Java. L'une des grandes beautés du monde Java est la grande diversité de solutions, démontrant une communauté Java vibrante et vivante.

 

A propos de l'auteur

Otávio Santana est un ingénieur logiciel avec une vaste expérience dans le développement open source, avec plusieurs contributions à JBoss Weld, Hibernate, Apache Commons et à d'autres projets. Axé sur le développement multilingue et les applications haute performance, Otávio a travaillé sur de grands projets dans les domaines de la finance, du gouvernement, des médias sociaux et du commerce électronique. Membre du comité exécutif du JCP et de plusieurs groupes d'experts JSR, il est également un champion Java et a reçu le JCP Outstanding Award et le Duke's Choice Award.

 

Evaluer cet article

Pertinence
Style

Contenu Éducatif

BT