0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Posted at

環境

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コンテナ上に構築)

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

前提

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

ゴール

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

1. セッション管理の設定を行うクラスを作成する

Spring公式ドキュメント(以下、公式ドキュメント)を参照して、以下のようなクラスを作成します。

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. セッションを管理するテーブルの名前をカスタマイズする

公式ドキュメントを参照し、先ほど作成したクラス内で以下のように@EnableJdbcHttpSessionアノテーションのtableName属性に任意のテーブル名を指定します。こうすることによって、デフォルトのテーブル名であるSPRING_SESSIONSPRING_SESSION_ATTRIBUTESを任意のテーブル名にカスタマイズできます。

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スクリプトのことです。

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

MySQLの場合はALTER TABLE RENAME で直接名前を変更するか、Spring Session JDBCのパッケージに含まれているschema-drop-*.sqlでテーブルを削除して(※既にセッション情報が存在する場合も削除されてしまうので注意)、その後にテーブルを再作成します。

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

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

SESSIONSテーブル
スクショ2

SESSIONS_ATTRIBUTESテーブル
スクショ3

終わりに

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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?