概要
- Spring Boot + Spring JDBC で動作するサンプルコードを試す
- データベースには H2 Database を使用する
H2 Database を Spring Framework で使う際のデフォルトの設定情報
デフォルトの設定を application.properties に書き出すと以下のようになる。
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.initialization-mode=embedded
この設定内容は自動で適用されるため application.properties に記述する必要は無い。この設定値ではない値を使いたいときには application.properties に記述する必要がある。
デフォルト設定情報は以下の Spring JDBC のソースコードなどに記述されている。
ClassUtils.forName("org.h2.Driver", H2EmbeddedDatabaseConfigurer.class.getClassLoader()));
@Override
public void configureConnectionProperties(ConnectionProperties properties, String databaseName) {
properties.setDriverClass(this.driverClass);
properties.setUrl(String.format("jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false", databaseName));
properties.setUsername("sa");
properties.setPassword("");
}
public static final String DEFAULT_DATABASE_NAME = "testdb";
application.properties の設定項目は Spring Boot Reference Documentation - Appendices - Appendix A: Common application properties にまとまっている。
schema.sql と data.sql
schema.sql と data.sql は Spring Boot 起動時に実行される SQL 文を記述したファイル。
- schema.sql には DDL (Data Definition Language: データ定義言語) テーブル作成などの SQL 文を記述する
- data.sql には DML (Data Manipulation Language: データ操作言語) レコード追加などの SQL 文を記述する
schema-h2.sql や data-h2.sql のようにデータベースの種類によって実行される SQL 文を変えることも可能。
“How-to” Guides - 10. Database Initialization
Spring Boot can automatically create the schema (DDL scripts) of your DataSource and initialize it (DML scripts). It loads SQL from the standard root classpath locations: schema.sql and data.sql, respectively. In addition, Spring Boot processes the schema-${platform}.sql and data-${platform}.sql files (if present), where platform is the value of spring.datasource.platform. This allows you to switch to database-specific scripts if necessary. For example, you might choose to set it to the vendor name of the database (hsqldb, h2, oracle, mysql, postgresql, and so on).
applicatin.properties に記述することで読み込む SQL ファイルを変更することも可能。
spring.datasource.schema=classpath:foo-schema.sql
spring.datasource.data=classpath:bar-data.sql
サンプルコード
ソースコード一覧
- pom.xml : Maven のビルド設定用ファイル
- .java : Java のソースコードファイル
- .sql : 起動時に実行されるSQL文を記述したファイル
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── example
│ ├── Person.java
│ ├── SampleController.java
│ └── SampleService.java
└── resources
├── data.sql
└── schema.sql
pom.xml
Maven のビルド設定用ファイル。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.M5</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>spring-jdbc-sample</artifactId>
<version>0.0.1</version>
<name>spring-jdbc-sample</name>
<description>Spring JDBC sample</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring JDBC を使う -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- H2 Database を使う -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
</project>
SampleController.java
HTTP リクエストを受けるためのクラス。
package com.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@SpringBootApplication
@RestController
public class SampleController {
public static void main(String[] args) {
SpringApplication.run(SampleController.class, args);
}
@Autowired
private SampleService service;
// 指定した name のデータを追加する
@RequestMapping("/add/{name}")
public List<Person> index(@ModelAttribute Person person) {
service.save(person);
return service.findAll();
}
}
SampleService.java
Spring JDBC の JdbcTemplate クラスを使ってデータベースを操作するクラス。
package com.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SampleService {
@Autowired
private JdbcTemplate jdbcTemplate;
// データの一覧を返す
public List<Person> findAll() {
// 実行する SQL を組み立てて実行
String query = "SELECT * from person";
List<Person> persons = jdbcTemplate.query(query, new BeanPropertyRowMapper<>(Person.class));
return persons;
}
// データを追加する
public Person save(Person person) {
// 実行する SQL を組み立てる
SqlParameterSource param = new BeanPropertySqlParameterSource(person);
SimpleJdbcInsert insert =
new SimpleJdbcInsert(jdbcTemplate)
.withTableName("person")
.usingGeneratedKeyColumns("id");
// SQL を実行して、AUTO_INCREMENT の値を取得する
Number key = insert.executeAndReturnKey(param);
person.setId(key.longValue());
System.out.println("Add: " + person);
return person;
}
}
Person.java
データベースの1レコードを表現するクラス。
package com.example;
public class Person {
private Long id; // AUTO_INCREMENT で ID を付与
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person(id=" + id + ", name=" + name + ")";
}
}
schema.sql
起動時に実行される SQL 文を記述したファイル。
CREATE TABLE IF NOT EXISTS person (
id INTEGER NOT NULL AUTO_INCREMENT,
name VARCHAR(256) NOT NULL,
PRIMARY KEY (id)
);
data.sql
起動時に実行される SQL 文を記述したファイル。
INSERT INTO person (name) VALUES('Alice');
ビルドと Spring Boot の起動
mvn コマンドでビルドして JAR ファイルを生成。
$ mvn package
java コマンドで Spring Boot を起動。
$ java -jar target/spring-jdbc-sample-0.0.1.jar
起動した Spring Boot にアクセスする
データベースにデータが追加される様子がわかる。
$ curl http://localhost:8080/add/Bob
[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}]
$ curl http://localhost:8080/add/Cindy
[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"},{"id":3,"name":"Cindy"}]
今回の動作確認環境
- OpenJDK 11.0.2
- Spring Boot 2.2.0.M5
- Spring JDBC 5.2.0.RC1
- H2 Database 1.4.199
参考資料
- Spring Boot Features - 10. Working with SQL Databases
- “How-to” Guides - 10. Database Initialization
- Spring Boot Reference Documentation - Appendices - Appendix A: Common application properties
- Spring Framework Documentation Version 5.2.0.RC1 - Data Access - 3. Data Access with JDBC
- spring-framework/spring-jdbc at v5.2.0.RC1 · spring-projects/spring-framework · GitHub