Banco de dados H2 com Spring Boot
Pré-requisitos
Conhecimentos básicos em:
-
Maven/Gradle
-
JPA
-
Spring Boot
-
Spring Data
H2
H2 é um banco de dados relacional escrito em Java. Ele pode ser integrado em aplicativos Java ou executado no modo cliente-servidor.
Todos os modos contam com suporte para bancos de dados persistentes e na memória. Não há limite para o número de bancos de dados abertos simultaneamente ou para o número de conexões abertas.
Modo Integrado
No modo integrado, um aplicativo abre um banco de dados de dentro da mesma JVM usando JDBC. Este é o modo de conexão mais rápido e fácil. A desvantagem é que um banco de dados só pode ser aberto em uma máquina virtual.
Neste modo, as operações de I/O são realizadas por threads que executam um comando SQL. O aplicativo não pode interromper essas Threads, pois pode levar à corrupção do banco de dados.
Modo Servidor
Ao usar o modo de servidor, um aplicativo abre um banco de dados remotamente usando a API JDBC ou ODBC. Um servidor precisa ser iniciado na mesma ou em outra máquina virtual, ou em outro computador. Muitos aplicativos podem se conectar ao mesmo banco de dados ao mesmo tempo, conectando-se a este servidor. Internamente, o processo do servidor abre o(s) banco(s) de dados no modo integrado.
O modo de servidor é mais lento do que o modo integrado, porque todos os dados são transferidos por TCP/IP.
Modo misto
O modo misto é uma combinação do modo integrado e do modo de servidor. O primeiro aplicativo que se conecta a um banco de dados faz isso no modo integrado, mas também inicia um servidor para que outros aplicativos (em execução em diferentes processos ou máquinas virtuais) possam acessar simultaneamente os mesmos dados. As conexões locais são tão rápidas como se o banco de dados fosse usado apenas no modo integrado, enquanto as conexões remotas são um pouco mais lentas.
O servidor pode ser iniciado e parado de dentro do aplicativo (usando a API do servidor) ou automaticamente (modo misto automático). Ao usar o modo misto automático, todos os clientes que desejam se conectar ao banco de dados (não importa se é uma conexão local ou remota) podem fazer isso usando exatamente a mesmo URL do banco de dados
Visão geral da URL do banco de dados
Tema | Formato de URL e exemplos |
---|---|
Conexão integrada (local) |
|
Na memória (particular) |
|
Na memória (nomeado) |
|
Modo de servidor (conexões remotas) usando TCP / IP |
|
Modo de servidor (conexões remotas) usando TLS |
|
Usando arquivos criptografados |
|
Métodos de bloqueio de arquivo |
|
Abra apenas se já existir |
|
Não feche o banco de dados quando a VM sair |
|
Execute SQL na conexão |
|
Nome de usuário e/ou senha |
|
Configurações de rastreamento de depuração |
|
Ignorar configurações desconhecidas |
|
Modo de acesso a arquivo personalizado |
|
Banco de dados em um arquivo zip |
|
Modo de compatibilidade |
|
Reconexão automática |
|
Modo misto automático |
|
Tamanho da página |
|
Alterar outras configurações |
|
Configurando o H2 em projetos Spring Boot
Levando em consideração o seu conhecimento em Spring Boot. Nosso primeiro passo é criamos um novo projeto em Spring Boot e adicionar as seguintes dependências.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!--Adicionado apenas para acessar o console do H2-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Após efetuar o download das dependências, vamos configurar o H2 adicionando as seguintes propriedades em nosso arquivo de configurações
.application.properties
# DATASOURCE
spring.datasource.url=jdbc:h2:file:./data/exemplo
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
# H2 Console
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
# JPA
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
Analisando as configurações do DataSource, observe o valor atribuído a propriedade URL, definimos que a conexão deve ser feita pelo modo integrado, e que o banco de dados deve ser armazenado no diretório
. Depois definimos o drive de conexão e as credenciais de acesso./data/exemplo
Na sequencia foi habilitado o console GUI (interface gráfica do utilizador) embutido para navegar pelo conteúdo do banco de dados e executar consultas SQL.
Por fim, configuramos o JPA, definindo o dialeto e também o ddl-auto como update, onde ao subir nossa aplicação o gerente de schemas do Hibernete detecta mudancas em nossas entidades e quando houver alterações as mesmas são aplicadas no banco de dados.
Mapeando uma entidade e testando nossa conexão com o banco de dados
Segue o código da entidade representando uma Pessoa e também de uma classe implementando
que nos fornece inúmeros métodos para manipulação da entidade ao banco de dados.JpaRepository
import javax.persistence.*;
@Entity
@Table(name = "PERSON")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private Long id;
@Column(name = "NAME", length = 50, nullable = false)
private String name;
@Deprecated
public Person() {
}
public Person(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
import org.springframework.data.jpa.repository.JpaRepository;
public interface PersonRepository extends JpaRepository<Person, Long> {
}
Por fim segue um serviço que manipula objetos do tipo Pessoa em nosso banco de dados.
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;
import java.util.logging.Level;
import java.util.logging.Logger;
@Service
public class PersonService implements ApplicationRunner {
private static final Logger LOGGER = Logger.getLogger(PersonService.class.getName());
private final PersonRepository repository;
public PersonService(PersonRepository repository) {
this.repository = repository;
}
@Override
public void run(ApplicationArguments args) throws Exception {
var person = new Person("Gaspar Barancelli Junior");
LOGGER.log(Level.INFO, "Persist");
repository.save(person);
LOGGER.log(Level.INFO, person.toString());
LOGGER.log(Level.INFO, "Find");
repository.findById(person.getId()).ifPresent(it -> {
LOGGER.log(Level.INFO, person.toString());
});
var person2 = new Person("Rodrigo Barancelli");
LOGGER.log(Level.INFO, "Persist");
repository.save(person2);
LOGGER.log(Level.INFO, person2.toString());
person2.setName("Rodrigo Dalla Valle Barancelli");
LOGGER.log(Level.INFO, "Update");
repository.save(person2);
LOGGER.log(Level.INFO, person2.toString());
LOGGER.log(Level.INFO, "FindAll");
repository.findAll().forEach(it -> LOGGER.log(Level.INFO, it.toString()));
LOGGER.log(Level.INFO, "Delete");
repository.delete(person2);
LOGGER.log(Level.INFO, person2.toString());
}
}
Ao executarmos nossa aplicação, obtemos a seguinte saida.
Persist
Person{id=1, name='Gaspar Barancelli Junior'}
Find
Person{id=1, name='Gaspar Barancelli Junior'}
Persist
Person{id=2, name='Rodrigo Barancelli'}
Update
Person{id=2, name='Rodrigo Dalla Valle Barancelli'}
FindAll
Person{id=1, name='Gaspar Barancelli Junior'}
Person{id=2, name='Rodrigo Dalla Valle Barancelli'}
Delete
Person{id=2, name='Rodrigo Dalla Valle Barancelli'}
Acessando o console do H2
Nas configurações realizadas anteriormente definimos que o path da nossa aplicação para acessar o console do banco de dados seria
, portando abra o seguinte endereço em seu navegador http://localhost:8080/h2-console e copie os mesmos valores definimos no arquivo de configuração para os inputs de h2-console
, JDBC URL
e User Name
.Password

Após a conexão ser realizada seremos direcionados para uma nova página, onde podemos manipular nosso banco de dados. Nessa nova página vamos executar o seguinte comando
, e verificar que os dados inseridos anteriormente estão sendo listados no console.SELECT * FROM PERSON

O código fonte dessa aplicação esta no repositório hospedado no GitHub.