Spring Session JDBC デフォルトテーブル名の変更

## 環境
Mac OS Sonoma : 14.6.1
Eclipse IDE : 2024-09 (4.33.0)
Spring Framework : 6.1.13
Spring Boot : 3.3.4
Spring Security : 6.3.3
Spring Session JDBC: 3.3.0
Eclipse Embedded Maven : 3.9.9
JDK (Java Development Kit) : 21
MySQL Server : 8.0.28 MySQL Community Server - GPL（Dockerコンテナ上に構築)

:::note warn
注意
情報が正確かつ明確であるよう努めていますが、間違いや不完全な説明があるかもしれません。
内容を改善するためのフィードバックや修正を歓迎します。 ご理解のほど、よろしくお願いいたします。
:::


## 前提
①なんらかのSpring Bootプロジェクトが作成済みであること。
②セッション管理を必要とする処理が実装されていること。（今回はあらかじめ、ログイン機能が実装されています。）
③spring-session-jdbcの依存関係がプロジェクトに追加されていること。

## ゴール
テーブル名をカスタマイズしたテーブルにセッション情報の保存が行われていること。

## 1. セッション管理の設定を行うクラスを作成する
[Spring公式ドキュメント](https://spring.pleiades.io/spring-session/reference/configuration/jdbc.html#adding-spring-session-jdbc)(以下、公式ドキュメント)を参照して、以下のようなクラスを作成します。
```java:SessionConfig.java
package sample.app.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession;

@Configuration
@EnableJdbcHttpSession
public class SessionConfig {
}
```

## 2. セッションを管理するテーブルの名前をカスタマイズする
[公式ドキュメント](https://spring.pleiades.io/spring-session/reference/configuration/jdbc.html#customizing-table-name)を参照し、先ほど作成したクラス内で以下のように`@EnableJdbcHttpSession`アノテーションの`tableName`属性に任意のテーブル名を指定します。こうすることによって、デフォルトのテーブル名である`SPRING_SESSION`と`SPRING_SESSION_ATTRIBUTES`を任意のテーブル名にカスタマイズできます。
```java:SessionConfig.java
package sample.app.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession;

@Configuration
@EnableJdbcHttpSession(tableName = "SESSIONS")
public class SessionConfig {
}
```

## 3. スキーマスクリプトを修正する
スキーマスクリプトとは、DBのテーブルやカラムなどを定義するSQLスクリプトのことです。

上記２で行ったことは、セッションデータを管理するクラスに対して、
「セッションを管理するテーブルは"SESSIONS"("SESSIONS_ATTRIBUTES"も含む)ですよ。なので、セッションに関する処理をするときはこのテーブル名を指定してくださいね」
と伝えているだけです。なので、**実際のDB上のテーブル名が自動的に変更されるわけではないため、このまま実行してもエラーが発生します。** というわけで、DB上のテーブル名を変更しなければなりません。

MySQLの場合は`ALTER TABLE RENAME` で直接名前を変更するか、[Spring Session JDBCのパッケージ](https://github.com/spring-projects/spring-session/blob/main/spring-session-jdbc/src/main/resources/org/springframework/session/jdbc
)に含まれているschema-drop-*.sqlでテーブルを削除して（※既にセッション情報が存在する場合も削除されてしまうので注意）、その後にテーブルを再作成します。

(自分の環境は、Dockerコンテナ上でのMySQL環境構築時に、スキーマスクリプトを実行させてテーブル作成も行っていたため、一度コンテナごと削除して、スキーマスクリプトを以下のように修正してから、再構築を行いました。)
```sql: init.sql
use sample;

DROP TABLE IF EXISTS SESSIONS;

CREATE TABLE SESSIONS (
	PRIMARY_ID CHAR(36) NOT NULL,
	SESSION_ID CHAR(36) NOT NULL,
	CREATION_TIME BIGINT NOT NULL,
	LAST_ACCESS_TIME BIGINT NOT NULL,
	MAX_INACTIVE_INTERVAL INT NOT NULL,
	EXPIRY_TIME BIGINT NOT NULL,
	PRINCIPAL_NAME VARCHAR(100),
	CONSTRAINT SESSIONS_PK PRIMARY KEY (PRIMARY_ID)
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;

CREATE UNIQUE INDEX SESSIONS_IX1 ON SESSIONS (SESSION_ID);
CREATE INDEX SESSIONS_IX2 ON SESSIONS (EXPIRY_TIME);
CREATE INDEX SESSIONS_IX3 ON SESSIONS (PRINCIPAL_NAME);

DROP TABLE IF EXISTS SESSIONS_ATTRIBUTES;

CREATE TABLE SESSIONS_ATTRIBUTES (
	SESSION_PRIMARY_ID CHAR(36) NOT NULL,
	ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
	ATTRIBUTE_BYTES BLOB NOT NULL,
	CONSTRAINT SESSIONS_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
	CONSTRAINT SESSIONS_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SESSIONS(PRIMARY_ID) ON DELETE CASCADE
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;

DROP TABLE IF EXISTS USERS;

CREATE TABLE USERS (
	id INT(36) AUTO_INCREMENT PRIMARY KEY,
	username VARCHAR(255) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    role VARCHAR(50) NOT NULL CHECK (role IN ('ADMIN', 'USER')),
    email VARCHAR(255)
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
```


## 4. 確認
アプリケーションを実行して、カスタマイズしたテーブルにセッション情報が格納されているか確認します。
ログインをして、画面に表示されたセッションIDとテーブルに保存されているセッションIDが一致することを確認できました。

**ログイン成功画面**
![スクショ1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2370416/5464e7e2-80b1-bfd8-a237-19913be9574c.png "ログイン成功画面")

**SESSIONSテーブル**
![スクショ2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2370416/a84df0a0-1d0a-d499-f419-5f78918d81de.png)

**SESSIONS_ATTRIBUTESテーブル**
![スクショ3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2370416/d245777b-6aa4-3922-fe98-62b14d45adc3.png)


## 終わりに
この記事では、Spring Session JDBCを使ってセッション管理を行うときに、セッション情報を保存するテーブル名をカスタマイズする方法を紹介しました。
少しでも参考になれば幸いです。