SpringBootでH2DataBaseを使う

# はじめに
H2DataBaseにてログイン後の以下の画面が見れるまでの記事となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457845/279c5b4b-1b2a-68f9-f7b4-1a6a1769c0aa.png)

# Spring InitializrでSpringプロジェクトを作成
[Spring Initializr](https://start.spring.io/)

上記サイトから以下画像の状態でGENERATEボタンをクリックしてZIPファイルをダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457845/de8cf086-e3ca-68ad-5153-3315e28e09b1.png)

# Mavenを利用して必要なライブラリをインストール
以下がGENERATE時点のpom.xml
```xml:pom.xml
<?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 https://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>3.2.5</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>sample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>sample</name>
	<description>H2DataBaseのログイン画面が見れるまで</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
```
上記の状態ではアプリケーション起動してもサーバーが起動したままにならず、すぐに正常終了して終わってしまうため以下のように`spring-boot-starter`の部分を`spring-boot-starter-web`に修正します。
```xml:pom.xml
<?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 https://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>3.2.5</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>sample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>sample</name>
	<description>H2DataBaseのログイン画面が見れるまで</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId> ← この部分
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

```
これで起動したままの状態を保てるため次にdependenyにH2DataBaseの依存を追加します。
```xml:pom.xml
<?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 https://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>3.2.5</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>sample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>sample</name>
	<description>H2DataBaseのログイン画面が見れるまで</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>                              )
			<groupId>com.h2database</groupId>     )
			<artifactId>h2</artifactId>           ) この部分
			<scope>runtime</scope>                )
		</dependency>                             )
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
```

これで行けると思ってたけどコンソールログを見ても分かるとおり、これだけではH2DataBaseは起動しません。
[http://localhost:8080/h2-console](http://localhost:8080/h2-console)へアクセスすると接続画面の表示までは出来ますがいざ接続しようとするとDBが作成されていないというエラーが発生します。(後述するapplication.propertiesのありなしは関係ありません。)

```text:コンソールログ
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.2.5)

2024-05-01T09:28:51.377+09:00  INFO 60548 --- [sample] [           main] com.example.sample.SampleApplication     : Starting SampleApplication using Java 17 with PID 60548 (/home/xxx/target/classes started by yt in /home/xxx)
2024-05-01T09:28:51.386+09:00  INFO 60548 --- [sample] [           main] com.example.sample.SampleApplication     : No active profile set, falling back to 1 default profile: "default"
2024-05-01T09:28:53.056+09:00  INFO 60548 --- [sample] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
2024-05-01T09:28:53.074+09:00  INFO 60548 --- [sample] [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-05-01T09:28:53.074+09:00  INFO 60548 --- [sample] [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.20]
2024-05-01T09:28:53.147+09:00  INFO 60548 --- [sample] [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-05-01T09:28:53.149+09:00  INFO 60548 --- [sample] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1629 ms
2024-05-01T09:28:53.670+09:00  INFO 60548 --- [sample] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path ''
2024-05-01T09:28:53.683+09:00  INFO 60548 --- [sample] [           main] com.example.sample.SampleApplication     : Started SampleApplication in 3.188 seconds (process running for 4.022)

Process finished with exit code 130 (interrupted by signal 2: SIGINT)
```
実はあと一つ依存が必要なようです。以下のようにpom.xmlを書き換えます。
どこかの記事を参考にしたとかではないので他に正規のやり方があるかもしれません。

```xml:pom.xml
<?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 https://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>3.2.5</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>sample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>sample</name>
	<description>H2DataBaseのログイン画面が見れるまで</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>                                             )
			<groupId>org.springframework.boot</groupId>          ) この部分
			<artifactId>spring-boot-starter-jdbc</artifactId>    )
		</dependency>                                            )
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
```
その後起動すると以下の通りコンソールログからもH2DataBaseが起動していることの確認が取れました。
もちろん[http://localhost:8080/h2-console](http://localhost:8080/h2-console)からのログインも可能です。
```text:コンソールログ
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.2.5)

2024-05-01T09:38:32.707+09:00  INFO 61487 --- [sample] [           main] com.example.sample.SampleApplication     : Starting SampleApplication using Java 17 with PID 61487 (/home/xxx/sample/target/classes started by yt in /home/xxx/sample)
2024-05-01T09:38:32.712+09:00  INFO 61487 --- [sample] [           main] com.example.sample.SampleApplication     : No active profile set, falling back to 1 default profile: "default"
2024-05-01T09:38:34.579+09:00  INFO 61487 --- [sample] [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JDBC repositories in DEFAULT mode.
2024-05-01T09:38:34.609+09:00  INFO 61487 --- [sample] [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 21 ms. Found 0 JDBC repository interfaces.
2024-05-01T09:38:35.414+09:00  INFO 61487 --- [sample] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
2024-05-01T09:38:35.435+09:00  INFO 61487 --- [sample] [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-05-01T09:38:35.436+09:00  INFO 61487 --- [sample] [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.20]
2024-05-01T09:38:35.530+09:00  INFO 61487 --- [sample] [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-05-01T09:38:35.532+09:00  INFO 61487 --- [sample] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2643 ms
2024-05-01T09:38:36.139+09:00  INFO 61487 --- [sample] [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2024-05-01T09:38:36.355+09:00  INFO 61487 --- [sample] [           main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:65d228e7-633d-4ad6-893a-a0213855caf7 user=SA
2024-05-01T09:38:36.357+09:00  INFO 61487 --- [sample] [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2024-05-01T09:38:36.555+09:00  INFO 61487 --- [sample] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path ''
2024-05-01T09:38:36.572+09:00  INFO 61487 --- [sample] [           main] com.example.sample.SampleApplication     : Started SampleApplication in 4.644 seconds (process running for 5.433)
```

コンソールログに出力されている`url=jdbc:h2:mem:65d228e7-633d-4ad6-893a-a0213855caf7`の表示でインメモリデータベースが作られていることが分かります。

これで終了ですがSpringアプリケーションから接続するための基本的な設定も以下に残します。
```properties:
# ①データベースのドライバクラス名
spring.datasource.driver-class-name=org.h2.Driver

# ②データベースのユーザー名
spring.datasource.username=sample

# ③データベースのパスワード
spring.datasource.password=sample

# ④データベースのURL。メモリ内のH2データベースを使用し、終了時にデータベースを閉じ、PostgreSQLモードを有効にし、テーブル/列名を大文字と小文字を区別して扱わない設定
spring.datasource.url=jdbc:h2:mem:sample;DB_CLOSE_ON_EXIT=TRUE;MODE=PostgreSQL;DATABASE_TO_UPPER=false

# ⑤一意の名前を生成する代わりに固定の名前を使用する
spring.datasource.generate-unique-name=false

# ⑥アプリケーションの起動時にデータベースを常に初期化する
spring.datasource.initialization-mode=always

# ⑦schema.sqlファイルを使用してデータベースのスキーマを初期化する
spring.datasource.schema=classpath:schema.sql
```
⑤以降はなくても大丈夫です。また、④も`spring.datasource.url=jdbc:h2:mem:sample`のみの記述で十分で、これによって指定したDB名でデータベースを自動作成できます。

# MyBatisの場合

pom.xmlは以下のように記述することでH2DataBaseは起動しました。
```xml:pom.xml
<?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 https://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>3.2.5</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>sample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>sample</name>
	<description>H2DataBaseのログイン画面が見れるまで</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>                                                     ) 
			<groupId>org.springframework.boot</groupId>                  ) ①
			<artifactId>spring-boot-starter-jdbc</artifactId>            )
		</dependency>                                                    )
  
		<dependency>                                                     )
			<groupId>org.mybatis.spring.boot</groupId>                   )
			<artifactId>mybatis-spring-boot-starter-test</artifactId>    ) ②
			<version>3.0.3</version>                                     )
			<scope>test</scope>                                          )
		</dependency>                                                    )
        <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
```

`spring-boot-starter-jdbc`は1つ追加するだけでよかったですがMyBatisを使いたいとなると②だけではなく①の依存も必要なようです。DomaやJPAの場合も試してないですが恐らくベースとして①は必要だと思います。