エンティティクラスへの自動フィールド設定アノテーションの追加
自動で値を設定したいフィールドには@TableFieldアノテーションを追加し、fill属性を指定します。
fill属性のオプション:
- DEFAULT: デフォルト(処理なし)
- INSERT: 挿入操作時にフィールドを自動設定
- UPDATE: 更新操作時にフィールドを自動設定
- INSERT_UPDATE: 挿入と更新操作の両方でフィールドを自動設定
@TableField(fill = FieldFill.INSERT)
private LocalDateTime registrationDate;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime lastModifiedDate;
@TableField(fill = FieldFill.INSERT)
private Long createdBy;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long modifiedBy;
MetaObjectHandlerインターフェースの実装
データの新規登録や更新操作時に、特定のフィールド(作成日時、更新日時、作成者、更新者など)を自動で設定するカスタムハンドラクラスを実装します。これらの値はシステムの現在時刻や、ThreadLocalを利用して取得した現在のユーザー情報などから設定されます。
@Component
public class CustomMetaObjectHandler implements MetaObjectHandler {
/**
* 挿入操作時の自動フィールド設定
* @param metaObject メタオブジェクト
*/
@Override
public void insertFill(MetaObject metaObject) {
logger.debug("Insert operation metaObject: {}", metaObject);
// 現在日時の設定
LocalDateTime now = LocalDateTime.now();
this.strictInsertFill(metaObject, "registrationDate", LocalDateTime.class, now);
this.strictInsertFill(metaObject, "lastModifiedDate", LocalDateTime.class, now);
// 現在ユーザーの設定
Long currentUserId = UserContext.getCurrentUserId();
this.strictInsertFill(metaObject, "createdBy", Long.class, currentUserId);
this.strictInsertFill(metaObject, "modifiedBy", Long.class, currentUserId);
}
/**
* 更新操作時の自動フィールド設定
* @param metaObject メタオブジェクト
*/
@Override
public void updateFill(MetaObject metaObject) {
logger.debug("Update operation metaObject: {}", metaObject);
// 現在日時の設定
this.strictUpdateFill(metaObject, "lastModifiedDate", LocalDateTime.class, LocalDateTime.now());
// 現在ユーザーの設定
this.strictUpdateFill(metaObject, "modifiedBy", Long.class, UserContext.getCurrentUserId());
}
}
ThreadLocalを利用したユーザー情報管理
ThreadLocalはスレッドごとに独立した変数を保持する機能です。各スレッドが自身の変数コピーにアクセスできるため、スレッドセーフな変数の共有と、スレッド単位でのデータ伝達が可能になります。
ThreadLocalの主な利点:
- スレッド安全性の確保
- スレッド単位での変数伝達
以下は、現在ログイン中のユーザーIDを管理するためのユーティリティクラスの実装例です。
/**
* 現在のログインユーザーIDを管理するためのThreadLocalベースのユーティリティクラス
*/
public class UserContext {
private static final ThreadLocal<Long> userContextHolder = new ThreadLocal<>();
/**
* 現在のユーザーIDを設定
* @param userId ユーザーID
*/
public static void setCurrentUserId(Long userId) {
if (userId == null) {
userContextHolder.remove();
} else {
userContextHolder.set(userId);
}
}
/**
* 現在のユーザーIDを取得
* @return ユーザーID
*/
public static Long getCurrentUserId() {
return userContextHolder.get();
}
/**
* 現在のスレッドからユーザー情報をクリア
*/
public static void clear() {
userContextHolder.remove();
}
}
このクラスを利用することで、リクエスト処理のどの段階からでも現在のユーザー情報にアクセスでき、MetaObjectHandlerでの自動フィールド設定に活用できます。