How To Use the H2 Database With Spring Boot – DZone – Uplaza

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:

  1. Spring Boot
  2. Spring Boot AutoConfigure
  3. Spring JDBC
  4. H2 Database Engine
  5. Javax Annotation API
  6. 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:

  1. Initialize SpringApplicationBuilder: Creates a builder for the Spring Boot utility utilizing H2SpringBootExampleApplication
  2. 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)
  3. Set mother or father context: Specifies the BeanConfiguration, ExampleRepository, ExampleService, and ExampleCommandLineRunner courses as elements within the mother or father context
  4. Run the applying: Execute the applying with the offered arguments
  5. 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.

Share This Article
Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Exit mobile version