コンテンツにスキップ

マルチテナントプラグイン

TenantLineInnerInterceptor は、MyBatis-Plus が提供するプラグインで、マルチテナントのデータ分離を実現するために使用されます。このプラグインを通じて、各テナントが自身のデータにのみアクセスできることを保証し、データの安全な分離を実現します。

サンプルプロジェクト

TenantLineInnerInterceptor の使用方法をよりよく理解するために、公式が提供するサンプルプロジェクトを参照できます:👉 mybatis-plus-sample-tenant

属性の紹介

TenantLineInnerInterceptor の重要な属性は tenantLineHandler です。これは TenantLineHandler インターフェースのインスタンスであり、テナント関連のロジックを処理するために使用されます。

属性名デフォルト値説明
tenantLineHandlerTenantLineHandlerテナントハンドラ ( TenantId 行レベル )

TenantLineHandler インターフェースは以下のメソッドを定義しています:

public interface TenantLineHandler {
/**
* テナント ID 値の式を取得します。単一の ID 値のみをサポートします
*
* @return テナント ID 値の式
*/
Expression getTenantId();
/**
* テナントフィールド名を取得します
* デフォルトのフィールド名は: tenant_id
*
* @return テナントフィールド名
*/
default String getTenantIdColumn() {
return "tenant_id";
}
/**
* テーブル名に基づいて、マルチテナント条件の追加をスキップするかどうかを判断します
* デフォルトではすべて解析し、マルチテナント条件を追加します
*
* @param tableName テーブル名
* @return スキップするかどうか, true: スキップする, false: 解析してマルチテナント条件を追加する必要がある
*/
default boolean ignoreTable(String tableName) {
return false;
}
/**
* テナントフィールドの挿入ロジックをスキップします
*
* @param columns 挿入フィールド
* @param tenantIdColumn テナント ID フィールド
* @return
*/
default boolean ignoreInsert(List<Column> columns, String tenantIdColumn) {
return columns.stream().map(Column::getColumnName).anyMatch(i -> i.equalsIgnoreCase(tenantIdColumn));
}
}

使用方法

ステップ 1: テナントハンドラを実装する

TenantLineHandler インターフェースを実装し、テナントハンドラを作成します。この例では、各テナントが一意の tenantId を持ち、リクエストヘッダーを通じて現在のテナントの tenantId を取得すると仮定します。

@Component
public class CustomTenantHandler implements TenantLineHandler {
@Override
public Expression getTenantId() {
// テナントコンテキストがあり、現在のユーザーのテナントを取得できると仮定します
Long tenantId = TenantContextHolder.getCurrentTenantId();
// テナントIDの式を返します。LongValue は JSQLParser の bigint 型を表すクラスです
return new LongValue(tenantId);;
}
@Override
public String getTenantIdColumn() {
return "tenant_id";
}
@Override
public boolean ignoreTable(String tableName) {
// 必要に応じて、このテーブルを無視するかどうかを返します
return false;
}
}

ステップ 2: テナントハンドラをプラグインに注入する

カスタムテナントハンドラを TenantLineInnerInterceptor に注入します:

@Configuration
@MapperScan("com.yourpackage.mapper")
public class MybatisPlusConfig {
@Autowired
private CustomTenantHandler customTenantHandler;
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
TenantLineInnerInterceptor tenantInterceptor = new TenantLineInnerInterceptor();
tenantInterceptor.setTenantLineHandler(customTenantHandler);
interceptor.addInnerInterceptor(tenantInterceptor);
return interceptor;
}
}

以上の手順により、Spring Boot プロジェクトでマルチテナントプラグインの設定が正常に行われ、シンプルなテナントハンドラが実装されました。これで、アプリケーションは現在のリクエストのテナントIDに基づいてマルチテナントデータ分離を自動的に処理できるようになります。

実際のアプリケーションでは、テナントIDの取得方法は、アプリケーションのアーキテクチャとビジネス要件によって異なる場合があることに注意してください。また、テナントIDを処理する際には、潜在的なセキュリティリスクを回避するために、セキュリティを考慮するようにしてください。

ローカルキャッシュ SQL 解析

パフォーマンスを向上させるために、MyBatis-Plus はローカルキャッシュ SQL 解析をサポートしています。以下の方法でキャッシュ処理クラスを設定できます:

static {
// デフォルトでシリアライズをサポート FstSerialCaffeineJsqlParseCache, JdkSerialCaffeineJsqlParseCache
JsqlParserGlobal.setJsqlParseCache(new JdkSerialCaffeineJsqlParseCache(
(cache) -> cache.maximumSize(1024)
.expireAfterWrite(5, TimeUnit.SECONDS))
);
}

挿入時にテナントフィールドを自動追加

デフォルトでは、挿入 SQL はテナント条件の判断を必要とするため、自動フィールド埋め込み機能と連携してテナントフィールドを埋め込む必要があります。そうしないと、テナントフィールドは自動的にデータベースに保存されません。

注意事項

以上の設定と使用方法を通じて、MyBatis-Plus アプリケーションでマルチテナントのデータ分離を実現し、各テナントのデータセキュリティを確保できます。

Baomidou

© 2016-2025 Baomidou™. All Rights Reserved.

Power by Astro Starlight | Sponsored by JetBrains

渝ICP备2021000141号-1 | 渝公网安备50011302222097