devstory

Intégration de Spring Spring, JPA et H2 Database

1- Objectif de leçon

H2 est une base de données relationnelle (Relational database), source ouverte, compacte, écrite par la langage Java. La capacité de l'installeur H2 est très restreinte, environ 8MB.
Une des caractéristiques intéressantes de H2 est que vous pouvez créer une base de données en mémoire (In Memory Database) au lieu d'être stocké sur un disque dur de l'ordinateur. Cela rend la requête rapide et la manipulation des données très rapide. Cependant, si vous sélectionnez la fonction "In Memory Database", les données n'existent que lorsque l'application fonctionne, lorsque l'application est arrêtée (shutdown), les données sont également supprimées de la mémoire.
H2 vous fournit un outil d'administration baptisé H2 Console, et vous travaillez avec lui via le navigateur.
Dans cette leçon, je vous donnerai des instructions comment créeer un projet Spring Boot qui intègre à la base de données H2 et utilise des caractéristiques de "In Memory Database", et configure pour user l'outil de management H2 Console.
Il n'y a pas de grandes différences si vous voulez vous connecter à la base de données H2 installée sur votre ordinateur (Voir l'appendice  à la fin de cette publication).

2- Créer un projet Spring Boot

Sur Eclipse créez le projet Spring Boot :
OK, le projet a été créé.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>SpringBootJpaH2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>SpringBootJpaH2</name>
    <description>Spring Boot + Jpa + H2</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>
SpringBootJpaH2Application.java
package org.o7planning.springbooth2;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootJpaH2Application {

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

3- Entity Class, DAO, DataInit, Controller

Person.java
package org.o7planning.springbooth2.entity;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name = "PERSON")
public class Person {

    @Id
    @GeneratedValue
    @Column(name = "Id", nullable = false)
    private Long id;

    @Column(name = "Full_Name", length = 64, nullable = false)
    private String fullName;

    @Temporal(TemporalType.DATE)
    @Column(name = "Date_Of_Birth", nullable = false)
    private Date dateOfBirth;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }

    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }

}
PersonDAO est une interface étendue (extends) de CrudRepository<Person, Long>. Spring Data JPA qui créera par lui même une classe qui implémente (implements) cette interface en même temps du démarrage de l'application.
Voir plus :
PersonDAO.java
package org.o7planning.springbooth2.dao;

import java.util.Date;
import java.util.List;

import org.o7planning.springbooth2.entity.Person;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface PersonDAO extends CrudRepository<Person, Long> {

    public List<Person> findByFullNameLike(String name);

    public List<Person> findByDateOfBirthGreaterThan(Date date);

}
La classe DataInit implémente l'interface ApplicationRunner, elle exécutera automatiquement en même temps du démarrage de l'application. Dans cette classe, nous allons intérer quelques enregistrements (record) au tableau PERSON.
DataInit.java
package org.o7planning.springbooth2.init;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.o7planning.springbooth2.dao.PersonDAO;
import org.o7planning.springbooth2.entity.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class DataInit implements ApplicationRunner {

    private PersonDAO personDAO;

    private static final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

    @Autowired
    public DataInit(PersonDAO personDAO) {
        this.personDAO = personDAO;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        long count = personDAO.count();

        if (count == 0) {
            Person p1 = new Person();

            p1.setFullName("John");

            Date d1 = df.parse("1980-12-20");
            p1.setDateOfBirth(d1);
            //
            Person p2 = new Person();

            p2.setFullName("Smith");
            Date d2 = df.parse("1985-11-11");
            p2.setDateOfBirth(d2);

            personDAO.save(p1);
            personDAO.save(p2);
        }

    }
    
}
MainController.java
package org.o7planning.springbooth2.controller;

import org.o7planning.springbooth2.dao.PersonDAO;
import org.o7planning.springbooth2.entity.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MainController {

    @Autowired
    private PersonDAO personDAO;

    @ResponseBody
    @RequestMapping("/")
    public String index() {
        Iterable<Person> all = personDAO.findAll();

        StringBuilder sb = new StringBuilder();

        all.forEach(p -> sb.append(p.getFullName() + "<br>"));

        return sb.toString();
    }

}

4- Configurer Spring Boot & H2

Dans cet exemple, je vais configurer Spring Boot afin d'utiliser H2 comme une base de données (In memory Database), celui-ci signifit que nous n'avons pas besoin d'installer la base de données H2, elle sera automatiquent créée et stockée dans la mémoire de l'ordinateur.
Dans un autre cas, si vous avez intégré une base de données H2 sur votre ordinateur et que vous voulez interagir Spring Boot avec cette base de données, vous pouvez également voir l'annexe au bas de ce post.
application.properties

# To See H2 Console in Browser:
# http://localhost:8080/h2-console
# Enabling H2 Console
spring.h2.console.enabled=true

# ===============================
# DB
# ===============================

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=

# ===============================
# JPA / HIBERNATE
# ===============================

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect

spring.h2.console.enabled=true

Cette configuration dit à Spring de démarrer l'outil d'administration de la base de données H2 ​​​​​​​et vous pouvez accéder cet outil sur le navigateur :

spring.datasource.url=jdbc:h2:mem:testdb

Cette configuration dit à Spring que vous voulez utiliser la base de données H2 dans la mémoire (In Memory Database).

spring.jpa.hibernate.ddl-auto=update

Cette structure dit à Spring de créer (ou de mettre à jour) la structure des tableaux comme celle des classes Entity. En conséquence, le tableau PERSON sera automatiquement créé par la structure de la classe Person.

5- Exécuter l'application

Sur Eclipse exécutez votre application :
En ce moment, H2 Console est également démarrée avec l'application et vous pouvez accéder à cet outil d'administration :
le tableau PERSON sera automatiquement créée sur la base de la structure de la classe Person.
Requêtez (query) le tableau PERSON :

6- Appendice H2

Dans ce cas, utilisez H2 (Server) :
application.properties (H2 Server)
# To See H2 Console in Browser:
# http://localhost:8080/h2-console
# Enabling H2 Console
spring.h2.console.enabled=true

# ===============================
# DB
# ===============================

spring.datasource.url=jdbc:h2:tcp://localhost/~/testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=

# ===============================
# JPA / HIBERNATE
# ===============================

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect