Accéder à la même base de données H2 en mémoire dans plusieurs applications de démarrage Spring

Accéder à la même base de données H2 en mémoire dans plusieurs applications de démarrage Spring

1. Vue d'ensemble

Dans ce rapide didacticiel, nous allons démontrerhow to access the same in-memory H2 database from multiple Spring Boot applications.

Pour ce faire, nous allons créer deux applications Spring Boot distinctes. La première application Spring Boot démarrera une instance H2 en mémoire, tandis que la seconde accédera à une instance H2 intégrée de la première application sur TCP.

2. Contexte

Comme nous le savons, une base de données en mémoire est plus rapide et souvent utilisée en mode intégré dans une application. Cependant, la base de données en mémoire ne conserve pas les données lors des redémarrages du serveur.

Pour plus d'informations, veuillez consulter nos articles sur lesthe most commonly used in-memory databases et lesusage of an in-memory database in automated testing.

3. Les dépendances Maven

Les deux applications Spring Boot de cet article nécessitent les mêmes dépendances:


    
        org.springframework.boot
        spring-boot-starter-data-jpa
    
    
        com.h2database
        h2
    

4. Configuration de la source de données H2

Tout d'abord, définissons le composant le plus important - un bean Spring pour une base de données H2 en mémoire - et exposons-le via un port TCP:

@Bean(initMethod = "start", destroyMethod = "stop")
public Server inMemoryH2DatabaseaServer() throws SQLException {
    return Server.createTcpServer(
      "-tcp", "-tcpAllowOthers", "-tcpPort", "9090");
}

Les méthodes définies par les paramètresinitMethod etdestroyMethod sont appelées par Spring pour démarrer et arrêter la base de données H2.

Le paramètre-tcp indique à H2 d'utiliser un serveur TCP pour lancer H2. Nous spécifions le port TCP à utiliser dans les troisième et quatrième paramètres de la méthodecreateTcpServer.

Le paramètretcpAllowOthers ouvre H2 pour l'accès depuis des applications externes s'exécutant sur le même hôte ou des hôtes distants.

Ensuite, créonsoverride the default data source par la fonction de configuration automatique de Spring Boot en ajoutant quelques propriétés au fichierapplication.properties:

spring.datasource.url=jdbc:h2:mem:mydb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create

Il est important de remplacer ces propriétés carwe’ll need to use the same properties and values in the other applications souhaitent partager la même base de données H2.

5. Démarrer la première application de démarrage de printemps

Ensuite, pour démarrer notre application Spring Boot, nous allons créer une classe avec l'annotation@SpringBootApplication :

@SpringBootApplication
public class SpringBootApp {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootApp.class, args);
    }
}

Pour vérifier que tout est correctement câblé, ajoutons du code pour créer des données de test.

Nous allons définir une méthode nomméeinitDb et l'annoter avec@PostConstruct  afin que le conteneur Spring appelle automatiquement cette méthode dès que la classe principale est initialisée:

@PostConstruct
private void initDb() {
    String sqlStatements[] = {
      "drop table employees if exists",
      "create table employees(id serial,first_name varchar(255),last_name varchar(255))",
      "insert into employees(first_name, last_name) values('Eugen','Paraschiv')",
      "insert into employees(first_name, last_name) values('Scott','Tiger')"
    };

    Arrays.asList(sqlStatements).forEach(sql -> {
        jdbcTemplate.execute(sql);
    });

    // Query test data and print results
}

6. La deuxième application de démarrage du printemps

Examinons maintenant les composants de l'application cliente, qui nécessite les mêmes dépendances Maven que celles définies ci-dessus.

Tout d'abord, nous remplacerons les propriétés de la source de données. Nous devonsensure that the port number in the JDBC URL is the same as the one on which H2 is listening for incoming connections in the first application.

Voici le fichierapplication.properties de l’application cliente:

spring.datasource.url=jdbc:h2:tcp://localhost:9090/mem:mydb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create

Enfin, nous créons une classe principale de l’application cliente Spring Boot.

Encore une fois pour simplifier, nous définissons une méthode@SpringBootApplication containingan initDb avec le@PostConstruct annotation:

@SpringBootApplication
public class ClientSpringBootApp {
    public static void main(String[] args) {
        SpringApplication.run(ClientSpringBootApp.class, args);
    }

    @PostConstruct
    private void initDb() {
        String sqlStatements[] = {
          "insert into employees(first_name, last_name) values('Donald','Trump')",
          "insert into employees(first_name, last_name) values('Barack','Obama')"
        };

        Arrays.asList(sqlStatements).forEach(sql -> {
            jdbcTemplate.execute(sql);
        });

        // Fetch data using SELECT statement and print results
    }
}

7. Exemple de sortie

Désormais, lorsque nous exécutons les applications une à une, nous pouvons consulter les journaux de la console et vérifier que la deuxième application imprime les données comme prévu.

Voici lesconsole logs of the first Spring Boot application:

****** Creating table: Employees, and Inserting test data ******
drop table employees if exists
create table employees(id serial,first_name varchar(255),last_name varchar(255))
insert into employees(first_name, last_name) values('Eugen','Paraschiv')
insert into employees(first_name, last_name) values('Scott','Tiger')
****** Fetching from table: Employees ******
id:1,first_name:Eugen,last_name:Paraschiv
id:2,first_name:Scott,last_name:Tiger

Et voici lesconsole logs of the second Spring Boot application:

****** Inserting more test data in the table: Employees ******
insert into employees(first_name, last_name) values('Donald','Trump')
insert into employees(first_name, last_name) values('Barack','Obama')
****** Fetching from table: Employees ******
id:1,first_name:Eugen,last_name:Paraschiv
id:2,first_name:Scott,last_name:Tiger
id:3,first_name:Donald,last_name:Trump
id:4,first_name:Barack,last_name:Obama

8. Conclusion

Dans cet article rapide, nous avons vu comment nous pouvonsaccess the same in-memory H2 database instance from multiple Spring Boot applications.

Comme toujours, des exemples de code de travail sont disponiblesover on GitHub.