Introduction
In this guide, we'll take a look at how to integrate the H2 database with Spring Boot projects.
What is the H2 Database?
H2 is an open-source, Java-based, embedded database. It's very fast and very lightweight. Typically, it's used as an in-memory database which means it stores the data in memory and will not persist data on disk. Although if we need to persist the data, at the flick of a switch - you can persist data as well.
The H2 database is not recommended for production environments and is rather used for proofs of concept, tests, prototypes and similar applications.
Difference Between Persistent and In-Memory Databases
It is worth understanding the difference between persistent and in-memory databases. Persistent databases persist the data in physical memory - that's the entire point of databases. In the case of in-memory databases, data is stored in system memory and data will be lost when the program is closed. In essence - it's just like using RAM to store your objects.
Once the program is closed, the data is lost.
Why use in-memory databases at all then?
In-memory databases are helpful for proofs of concept, as you can easily substitute an in-memory database with a persistent one. It mocks the functionality and backgone of an actual persistent database, while giving you the ease of use and flexibility of performing queries and "persisting" objects, while still being lightweight.
Although H2 does allow you to persist data outside of memory - don't be tempted to replace a more robust database, such as PostgreSQL, MySQL, OracleDB, etc. with it.
Setting up the Spring Boot Project
Let's start out with a skeleton application. The easiest way is to use Spring Initializr and generate a Spring Boot project.
Make sure to add Web, H2 and JPA (Java Persistence API) dependencies.
Again, even though H2 typically isn't used as a persistent database - it mocks classical databases, and it interfaces with the Persistence API.
Clicking on the "Generate Project" button will download the SpringBootH2Integration.zip
file, which you can import into your IDE of choice:
Understanding H2's Defaults Configurations
Spring Boot is an opinionated framework and does all the default configurations based on the dependencies available in the classpath.
Since we added H2 as a dependency, Spring Boot knows that in this project we will be connecting to the H2 database, so it auto-configures H2-related properties like the database URL
, username
, password
, etc:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=false
If we look at the datasource.url
property, the name of the schema is testdb
and is an in-memory database (refered to as "mem"). We will see how we can override the default values in upcoming sections.
Overriding H2's Default Configurations
To override any property, just redefine the property with the updated value in the application.properties
file available under the src/main/resources
folder.
For example, by default H2 console is disabled, so let's enable it by adding below property in the application.properties
file:
spring.h2.console.enabled=true
Performing CRUD Operations with H2 in Spring Boot
In the following sections, we are going to create a Person API, which is a simple REST service in which we will interact with H2 using Spring Boot.
If you're not yet familiar with the creation of REST APIs, read our Complete Guide to Building REST APIs with Spring Boot!
The Person API will perform CRUD operations using different endpoints. Below are the details of endpoints:
GET
call to/persons
will display all person objects available in H2 database.GET
call to/persons/{id}
will display the person object with the given id.POST
call to/persons
will insert a new person object in the database.DELETE
call to/persons/{id}
will delete the person object with the given id from the database.
Before moving further, it makes sense to verify that the project we have created in the previous section is working fine and there are no errors in it.
To verify, run the SpringBootH2IntegrationApplication.java
file the way we run any Java program. Doing so, the application will start and we can see the server startup message in the console.
From the console, we can find the URL where we can open the H2 console:
2018-08-18 22:43:30.578 INFO 3792 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet webServlet mapped to [/h2-console/*]
Recall that we did enable the H2 console in the application.properties
file.
Let's open the H2 console by typing in http://localhost:8080/h2-console in the browser address bar:
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
Click connect to log in and see the various options:
You may see different value in the JDBC URL so change the Database URL to jdbc:h2:mem:testdb
in the login screen as this is the default URL configured by Spring Boot.
Implementing a REST API with CRUD Functionalities
Finally, let's spin up a simple REST API that performs CRUD operations on a Person
entity.
Defining an Entity
Naturally, we'll be starting out with our domain model and a definition of the Person
model:
@Entity
public class Person {
@Id
@GeneratedValue
private int id;
private String name;
private int age;
private String emailId;
// Getters and setters
}
Defining a PersonRepository
Utilizing the best of Spring Data JPA - we'll create a really simple, auto-generated CrudRepository
for our entities, named PersonRepository
:
public interface PersonRepository extends CrudRepository<Person, Integer> {}
Without any further implementation, the PersonRepository
has CRUD functionality through save()
, findById()
, deleteById()
and update()
methods, which accept any valid Person
entity.
Defining a PersonService
Once the repository interface is ready - let's create a concrete service to use the repository to actually perform the reading, writing and updating:
@Service
public class PersonService {
@Autowired
PersonRepository personRepository;
public List<Person> findAll() {
return personRepository.findAll();
}
public Person getPersonById(int id) {
return personRepository.findById(id).get();
}
public void saveOrUpdate(Person person) {
personRepository.save(person);
}
public void delete(int id) {
personRepository.deleteById(id);
}
}
Defining a PersonController
Finally - to expose the service to end-users, we'll create a @Controller
-annotated class, PersonController
and expose a few endpoints:
@RestController
public class PersonController {
@Autowired
PersonService personService;
@GetMapping("/persons")
private List<Person> getAllPersons() {
return personService.findAll();
}
@GetMapping("/persons/{id}")
private Person getPerson(@PathVariable("id") int id) {
return personService.getPersonById(id);
}
@DeleteMapping("/persons/{id}")
private void deletePerson(@PathVariable("id") int id) {
personService.delete(id);
}
@PostMapping("/persons")
private int savePerson(@RequestBody Person person) {
personService.saveOrUpdate(person);
return person.getId();
}
}
Great! We can now test out the functionality of the API and the responses we get.
Testing the Person API
To test the REST service, we'll be using Postman, which can be integrated into the Chrome browser easily using their browser extension or used as a standalone tool.
Test Case 1: Creating a New Person
Using postman, we'll configure a valid POST
request for the creation of users:
- Set Request Type: POST
- Set URL: http://localhost:8080/persons
- Set Request Header: Content-Type:application/json
- Set Body as: {"name":"person A", "age":23, "emailId": "[email protected]"}
- Click "Send"
- In the response we will get a
personId
.
To validate the data inserted in the H2 database:
- Open the H2 console
- Validate the
PERSON
table. It will show us the data we have inserted in POST request.
Repeat Test Case 1 with a different person and you'll have two person objects inserted in the database:
Test Case 2: Retrieving the new Person Object
Now, let's try to retrieve one of these users, via their ID. To do this, we'll construct a new request in postman:
- Request Type: GET
- URL: http://localhost:8080/persons/1
- Request Header: Content-Type:application/json
- Click "Send"
- In response, we will get person data with id 1.
Test Case 3: Deleting a Person Object
Finally, let's try to delete a person from the database:
- Request Type: DELETE
- URL: http://localhost:8080/persons/1
- Request Header: Content-Type:application/json
- Click "Send"
After running this, validate that data has been deleted from H2 database:
Conclusion
In this short guide, we've taken a look at how to integrate the in-memory H2 database with Spring Boot, and built a simple REST API around it to showcase the usage.
H2 is a lightweight, embedded database written in Java, typically used for prototyping.