On this tutorial, we’ll evaluate an instance utility that’s written within the Groovy programming language and display the way to use the H2 relational database (H2 DB/H2) with Spring Boot.
The advantage of utilizing the Groovy Programming Language, on this case, is that it permits an instance to ship precisely one file which comprises every little thing we have to run the applying.
The H2 Database Engine is a strong open-source relational database that’s written within the Java programming language and is used with some frequency in software program growth initiatives — particularly in the case of testing functions.
Utilizing H2 with the Spring Framework and with Spring Boot, particularly, is the use case that we’ll display right here.
Within the subsequent part, we’ll check out the instance and dissect, intimately, what occurs in every step.
H2 With Spring Boot Instance on GitHub
Included here’s a hyperlink to the GitHub gist pertaining to the instance used to display connecting the H2 Relational Database with Spring Boot.
I’ve additionally added the complete instance later on this article, which you need to be capable to paste into the groovyConsole and run as-is.
Maven Dependencies
The next dependencies are used on this instance:
- Spring Boot
- Spring Boot AutoConfigure
- Spring JDBC
- H2 Database Engine
- Javax Annotation API
- SLF4J Easy Supplier
The Groovy Grape dependency administration system ought to discover these dependencies robotically when the script is executed nevertheless for reference functions I’ve included these right here.
An Instance Pertaining To Utilizing the H2 Database Engine With Spring Boot
On this part, we’ll check out the script in nearer element and go over what’s occurring in every step.
Stipulations
With a view to run this instance, you have to the next:
- Java model 22.0.1 (required) — see OpenJDK on java.web and Oracle Java SE Growth Package 22.0.1 (JDK 22.0.1)
- Groovy 4.0.17 (required)
- groovyConsole (elective)
This script might be executed utilizing Groovy alone; therefore, the groovyConsole is elective.
The script makes use of the Groovy Adaptable Packaging Engine (Groovy Grape) to tug in dependencies from Maven Central therefore a connection to the Web is required as nicely.
I’ve included an instance of what the output ought to appear like when operating this script from the command line right here.
H2 DB with Spring Boot Profitable CRUD Instance Output
The pink arrow factors to the command used to run the script, and orange arrow factors to the log assertion that signifies the script is beginning, and the blue arrow factors to the log assertion that signifies that the script has completed operating.
On this instance, the script runs a Spring Boot utility that creates a desk within the H2 DB, executes a number of CRUD (create
, learn
, replace
, delete
) operations on that desk, after which drops the desk.
The Groovy script runs to completion efficiently after which exits.
Step 1: Declare a Bundle
After we outline the Spring Boot Utility, we’ll embody the scanBasePackages setting, which requires a package deal title so we set that right here.
Step 2: Add the Groovy Grape GrabConfig Annotation
In step two we have to add the Groovy Grape GrabConfig annotation and in addition set the systemClassLoader property to true — if we do not need this an exception shall be thrown when the script is executed.
Step 3: Seize Dependencies and Import Required Courses
In step three we have to seize the dependencies essential to run this instance in addition to import required courses — this contains the Spring Boot, H2 Database, and different supporting courses.
Notice that we’re utilizing the Hikari database driver on this instance.
See the part on this article for full particulars.
Step 4: Acquire a Reference to an SLF4J Logger
We’re utilizing the SLF4J log delegation framework on this instance and we’ll ship messages to console output so we will watch what’s occurring because the script executes.
The HikariCP dependency is one different framework that we’re utilizing that additionally makes use of SLF4J and we’ve included this high-performance connection pooling implementation on this instance.
Step 5: Configure H2 Database Datasource and JdbcTemplate Beans
Within the fifth step, we’ll configure the H2 Database datasource which makes use of the HikariCP high-performance connection pool dependency because the datasource sort.
Since this instance demonstrates some easy CRUD operations executed towards the H2 Database from a Spring Boot utility, we’ll additionally configure an occasion of JdbcTemplate
right here which makes use of this knowledge supply.
Notice that we’re assigning the HikariDataSource
class because the datasource sort.
The H2 DB occasion configured on this instance will reside in reminiscence solely — if we need to persist this info to disk, then we have to change the URL.
Step 6: Create a Repository Class
On this step, we implement a repository that comprises the CRUD operations that we will execute on the H2 Database occasion through the JdbcTemplate
, which is auto-wired on this instance by Spring Boot.
Step 7: Implement a Service Bean
On this step, we implement a transactional service bean that has stop-and-start lifecycle strategies together with comfort strategies that delegate to the repository bean.
The begin technique creates the instance desk in H2 when Spring Boot initializes the beans that the container is managing, and the cease technique drops the instance desk earlier than the container stops.
Different strategies outlined within the ExampleService ship comfort and conceal implementation particulars.
Utilizing a service aids in reuse and can be useful when testing our code.
Because the picture has been truncated, confer with the complete instance beneath or see the GitHub Gist.
Step 8: Implement the Spring Boot CommandLineRunner Interface
On this step, we implement the Spring Boot CommandLineRunner
specification.
Our implementation contains executing CRUD operations through the service created in step seven towards the H2 Database.
We log some info alongside the way in which so we will see what occurs as every CRUD operation completes.
Step 9: Configure Spring Boot Utility for Element Scanning
The code within the snippet defines a Spring Boot utility and specifies the bottom package deal for part scanning.
Step Ten: Configure and Then Run the Spring Boot Utility
The code on this snippet configures after which runs the Spring Boot utility with the next configuration:
- Initialize
SpringApplicationBuilder
: Creates a builder for the Spring Boot utility utilizingH2SpringBootExampleApplication
- Set profiles and net utility sort: Configures the applying to make use of the default profile and disables the online surroundings (this isn’t an internet utility so we don’t want this)
- Set mother or father context: Specifies the
BeanConfiguration
,ExampleRepository
,ExampleService
, andExampleCommandLineRunner
courses as elements within the mother or father context - Run the applying: Execute the applying with the offered arguments
- Shut the context: Closes the applying context — this step ensures that the cease lifecycle technique within the service (see step six) known as earlier than the Spring Boot instance utility has exited ensuing within the names desk within the H2 DB being dropped.
Lastly, the script logs a completion message after which exits.
The following part contains the entire Spring Boot with the H2 Database instance script.
Spring Boot With The H2 Database Engine Full Instance
Right here, I’ve included a replica of the complete script, which you need to be capable to run both utilizing the groovyConsole or through the command line with the groovy shell.
/* * Precondition: * * - Java model "22.0.1" 2024-04-16 * - Groovy model 4.0.17 */ package deal com.thospfuller.examples.h2.database.spring.boot @GrabConfig(systemClassLoader=true) @Seize(group='org.springframework.boot', module="spring-boot", model='3.3.0') @Seize(group='org.springframework.boot', module="spring-boot-autoconfigure", model='3.3.0') import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.builder.SpringApplicationBuilder import org.springframework.context.annotation.Configuration import org.springframework.beans.manufacturing unit.annotation.Autowired import org.springframework.stereotype.Repository import org.springframework.stereotype.Element import org.springframework.boot.jdbc.DataSourceBuilder @Seize(group='org.springframework', module="spring-jdbc", model='6.1.8') import org.springframework.jdbc.core.JdbcTemplate import org.springframework.jdbc.core.ParameterizedPreparedStatementSetter import org.springframework.transaction.annotation.Transactional import org.springframework.context.annotation.Bean import org.springframework.boot.CommandLineRunner import org.springframework.boot.WebApplicationType import org.springframework.stereotype.Service @Seize(group='com.h2database', module="h2", model='2.2.224') @Seize(group='com.zaxxer', module="HikariCP", model='5.1.0') import com.zaxxer.hikari.HikariDataSource import javax.sql.DataSource import java.sql.PreparedStatement @Seize(group='javax.annotation', module="javax.annotation-api", model='1.3.2') import javax.annotation.PostConstruct import javax.annotation.PreDestroy @Seize(group='org.slf4j', module="slf4j-simple", model='2.0.9') import org.slf4j.LoggerFactory def log = LoggerFactory.getLogger(this.class) log.data "H2 Database with Spring Boot example begins; args: $args" @Configuration class BeanConfiguration { @Bean DataSource getDataSource () { return DataSourceBuilder .create() .driverClassName("org.h2.Driver") .sort(HikariDataSource) .url("jdbc:h2:mem:example-db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE") .username("sa") .password("sa") .construct() } @Bean JdbcTemplate getJdbcTemplate (DataSource dataSource) { return new JdbcTemplate (dataSource) } } @Repository class ExampleRepository { non-public static remaining def log = LoggerFactory.getLogger(ExampleRepository) static remaining def TABLE_NAME = "NAMES" @Autowired non-public JdbcTemplate jdbcTemplate void createExampleTable () { log.data "createExampleTable: method begins." jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name VARCHAR(255));") log.data "createExampleTable: method ends." } def deleteExampleTable () { log.data "deleteExampleTable: method begins." jdbcTemplate.execute("DROP TABLE IF EXISTS ${TABLE_NAME};") log.data "deleteExampleTable: method ends." } def addNames (String... names) { return addNames (names as Checklist) } def addNames (Checklist nameList) { return jdbcTemplate.batchUpdate( "INSERT INTO ${TABLE_NAME} (name) VALUES (?);", nameList, nameList.measurement (), { PreparedStatement preparedStatement, String title -> preparedStatement.setString(1, title) } as ParameterizedPreparedStatementSetter ) } def updateName (int id, String newName) { return jdbcTemplate.replace( "UPDATE ${TABLE_NAME} SET NAME = ? WHERE ID = ?;", newName, id ) } def deleteName (int id) { return jdbcTemplate.replace( "DELETE FROM ${TABLE_NAME} WHERE ID = ?;", id ) } def readNames () { return jdbcTemplate.queryForList ("select name from ${TABLE_NAME}") } } @Service @Transactional class ExampleService { non-public static remaining def log = LoggerFactory.getLogger(ExampleService) @Autowired def exampleRepository @PostConstruct def begin () { log.data "start: method begins." exampleRepository.createExampleTable () log.data "start: method ends." } @PreDestroy def cease () { log.data "stop: method begins." exampleRepository.deleteExampleTable () log.data "stop: method ends." } def addNames (String... nameList) { return exampleRepository.addNames (nameList) } def updateName (int id, String newName) { return exampleRepository.updateName (id, newName) } def deleteName (int id) { return exampleRepository.deleteName (id) } def readNames () { return exampleRepository.readNames () } } @Element class ExampleCommandLineRunner implements CommandLineRunner { non-public static remaining def log = LoggerFactory.getLogger(H2SpringBootExampleApplication) @Autowired non-public def exampleService @Override public void run (String... args) { log.data "run: method begins; args: $args" def namesAdded = exampleService.addNames ("aaa", "bbb", "ccc", "ddd") log.data "namesAdded: $namesAdded" def updateResult = exampleService.updateName (2, "ZZZ") def names = exampleService.readNames () log.data "updateResult: $updateResult, names after update: $names" def deletedNames = exampleService.deleteName (2) names = exampleService.readNames () log.data "deletedNames: $deletedNames, names after deletion: $names" log.data "run: method ends." } } @SpringBootApplication(scanBasePackages = ["com.thospfuller.examples.h2.database.spring.boot"]) class H2SpringBootExampleApplication {} def springApplicationBuilder = new SpringApplicationBuilder(H2SpringBootExampleApplication) def context = springApplicationBuilder .profiles("default") .net(WebApplicationType.NONE) .mother or father ( BeanConfiguration, ExampleRepository, ExampleService, ExampleCommandLineRunner ) .run(args) context.shut () log.data "...done!" return
Conclusion
I hope that this tutorial has offered enough steerage in addition to a helpful instance concerning the way to use the H2 Database with Spring Boot.
When you encounter any issues or have questions on this tutorial, please depart a remark and I’ll attempt to assist.