Skip to content

Instantly share code, notes, and snippets.

@thospfuller
Last active June 19, 2024 21:25
Show Gist options
  • Save thospfuller/c0ac73cf450592ac262c2b098e65b4f6 to your computer and use it in GitHub Desktop.
Save thospfuller/c0ac73cf450592ac262c2b098e65b4f6 to your computer and use it in GitHub Desktop.
An example of the H2 Database running with Spring Boot and written in Groovy.
/*
* Precondition:
*
* - Java version "22.0.1" 2024-04-16
* - Groovy version 4.0.17
*/
package com.thospfuller.examples.h2.database.spring.boot
@GrabConfig(systemClassLoader=true)
@Grab(group='org.springframework.boot', module='spring-boot', version='3.3.0')
@Grab(group='org.springframework.boot', module='spring-boot-autoconfigure', version='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.factory.annotation.Autowired
import org.springframework.stereotype.Repository
import org.springframework.stereotype.Component
import org.springframework.boot.jdbc.DataSourceBuilder
@Grab(group='org.springframework', module='spring-jdbc', version='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
@Grab(group='com.h2database', module='h2', version='2.2.224')
@Grab(group='com.zaxxer', module='HikariCP', version='5.1.0')
import com.zaxxer.hikari.HikariDataSource
import javax.sql.DataSource
import java.sql.PreparedStatement
@Grab(group='javax.annotation', module='javax.annotation-api', version='1.3.2')
import javax.annotation.PostConstruct
import javax.annotation.PreDestroy
@Grab(group='org.slf4j', module='slf4j-simple', version='2.0.9')
import org.slf4j.LoggerFactory
def log = LoggerFactory.getLogger(this.class)
log.info "H2 Database with Spring Boot example begins; args: $args"
@Configuration
class BeanConfiguration {
@Bean
DataSource getDataSource () {
return DataSourceBuilder
.create()
.driverClassName("org.h2.Driver")
.type(HikariDataSource)
.url("jdbc:h2:mem:example-db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE")
.username("sa")
.password("sa")
.build()
}
@Bean
JdbcTemplate getJdbcTemplate (DataSource dataSource) {
return new JdbcTemplate (dataSource)
}
}
@Repository
class ExampleRepository {
private static final def log = LoggerFactory.getLogger(ExampleRepository)
static final def TABLE_NAME = "NAMES"
@Autowired
private JdbcTemplate jdbcTemplate
void createExampleTable () {
log.info "createExampleTable: method begins."
jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name VARCHAR(255));")
log.info "createExampleTable: method ends."
}
def deleteExampleTable () {
log.info "deleteExampleTable: method begins."
jdbcTemplate.execute("DROP TABLE IF EXISTS ${TABLE_NAME};")
log.info "deleteExampleTable: method ends."
}
def addNames (String... names) {
return addNames (names as List<String>)
}
def addNames (List<String> nameList) {
return jdbcTemplate.batchUpdate(
"INSERT INTO ${TABLE_NAME} (name) VALUES (?);",
nameList,
nameList.size (),
{ PreparedStatement preparedStatement, String name ->
preparedStatement.setString(1, name)
} as ParameterizedPreparedStatementSetter<String>
)
}
def updateName (int id, String newName) {
return jdbcTemplate.update(
"UPDATE ${TABLE_NAME} SET NAME = ? WHERE ID = ?;",
newName,
id
)
}
def deleteName (int id) {
return jdbcTemplate.update(
"DELETE FROM ${TABLE_NAME} WHERE ID = ?;",
id
)
}
def readNames () {
return jdbcTemplate.queryForList ("select name from ${TABLE_NAME}")
}
}
@Service
@Transactional
class ExampleService {
private static final def log = LoggerFactory.getLogger(ExampleService)
@Autowired
def exampleRepository
@PostConstruct
def start () {
log.info "start: method begins."
exampleRepository.createExampleTable ()
log.info "start: method ends."
}
@PreDestroy
def stop () {
log.info "stop: method begins."
exampleRepository.deleteExampleTable ()
log.info "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 ()
}
}
@Component
class ExampleCommandLineRunner implements CommandLineRunner {
private static final def log = LoggerFactory.getLogger(H2SpringBootExampleApplication)
@Autowired
private def exampleService
@Override
public void run (String... args) {
log.info "run: method begins; args: $args"
def namesAdded = exampleService.addNames ("aaa", "bbb", "ccc", "ddd")
log.info "namesAdded: $namesAdded"
def updateResult = exampleService.updateName (2, "ZZZ")
def names = exampleService.readNames ()
log.info "updateResult: $updateResult, names after update: $names"
def deletedNames = exampleService.deleteName (2)
names = exampleService.readNames ()
log.info "deletedNames: $deletedNames, names after deletion: $names"
log.info "run: method ends."
}
}
@SpringBootApplication(scanBasePackages = ["com.thospfuller.examples.h2.database.spring.boot"])
class H2SpringBootExampleApplication {}
def springApplicationBuilder = new SpringApplicationBuilder(H2SpringBootExampleApplication)
def context = springApplicationBuilder
.profiles("default")
.web(WebApplicationType.NONE)
.parent (
BeanConfiguration,
ExampleRepository,
ExampleService,
ExampleCommandLineRunner
)
.run(args)
context.close ()
log.info "...done!"
return
@thospfuller
Copy link
Author

thospfuller commented Jun 19, 2024

h2-database-with-spring-boot-groovy-cli

Here's an example pertaining to what this script should output when run from the command line using:

./groovy [.../your/path/to]/h2-database-spring-boot-with-jdbctemplate.groovy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment