Anker PowerCor
旅行には必須の大容量モバイルバッテリー!
【最新機種】GoPro hero11 Black
最新機種でVlogの思い出を撮影しよう!
[ノースフェイス] THE NORTH FACE メンズ アウター マウンテンライトジャケット
防水暴風で耐久性抜群なので旅行で大活躍です!
ペヤング ソースやきそば 120g×18個
とりあえず保存食として買っておけば間違いなし!
モンスターエナジー 355ml×24本 [エナジードリンク]
脳を活性化させるにはこれ!
Bauhutte ( バウヒュッテ ) 昇降式 L字デスク ブラック BHD-670H-BK
メインデスクの横に置くのにぴったりなおしゃれな可動式ラック!
サンディスク microSD 128GB
スマホからSwitchまで使える大容量MicroSDカード!
スポンサーリンク
目次
DBはスネークケース、Entityはキャメルケースにしたい
DBアクセスが伴うシステム等の実装をしている際に、設計方針によってはDB側のTable
カラム名はスネークケース、Java側のEntity
フィールド名はキャメルケースにしたい、という要望があります。
この際に、全てのEntity
フィールドに
1 2 |
@Column(name=:"admin_name") private String adminName |
のようにしても良いが、フィールド数が多かったり変更する際に影響範囲が多かったりと課題は沢山あります。
今回はHibernate5系を使っている際にPhysicalNamingStrategyStandardImpl
を継承して、共通処理としてスネークケースとキャメルケースをマッピング出来るようにしようと思います。
手順
前提
今回は以下のような環境での作業とします。
- Hibernate: 5.1.0
- PlayFramework: 2.7
- MySQL: 5.7
PhysicalNamingStrategyStandardImplの継承クラスの追加
まずは、org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
を継承したカスタムクラスを実装します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
package db.sample; import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import com.google.common.base.CaseFormat; public class CustomNamingStrategy extends PhysicalNamingStrategyStandardImpl { @Override public Identifier toPhysicalColumnName( final Identifier identifier, final JdbcEnvironment jdbcEnv) { return convertToSnakeCase(identifier); } private Identifier convertToSnakeCase(final Identifier identifier) { final String entityField = identifier.getText(); String formattedEntityField = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, entityField); return Identifier.toIdentifier(formattedEntityField); } } |
文字列をキャメルケースからスネークケースに変換するのは自前で行うとちょっとめんどくさいので、今回はGoogleが提供しているライブラリを利用しました。
カラム名以外にも処理を追加する事が可能
org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl.java
を観てみると、他にもtoPhysicalSchemaName
やtoPhysicalTableName
メソッドがあるので、必要メソッドだけ@Override
すれば処理を変える事が出来そうです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
/* * Hibernate, Relational Persistence for Idiomatic Java * * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.boot.model.naming; import java.io.Serializable; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; /** * Standard implementation of the PhysicalNamingStrategy contract. * * @author Steve Ebersole */ public class PhysicalNamingStrategyStandardImpl implements PhysicalNamingStrategy, Serializable { /** * Singleton access */ public static final PhysicalNamingStrategyStandardImpl INSTANCE = new PhysicalNamingStrategyStandardImpl(); @Override public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment context) { return name; } @Override public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment context) { return name; } @Override public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) { return name; } @Override public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment context) { return name; } @Override public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) { return name; } } |
hibernate.physical_naming_strategyの追加
次に、presistence.xml
のhibernate.physical_naming_strategy
に上記のクラスを利用するようにプロパティを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd" version="2.1"> <persistence-unit name="defaultPersistenceUnit" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <non-jta-data-source>DefaultDS</non-jta-data-source> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/> <property name="org.hibernate.flushMode" value="COMMIT"/> <property name="hibernate.physical_naming_strategy" value="repositories.db.CustomNamingStrategy" /> <!-- 追加 --> </properties> </persistence-unit> </persistence> |
これで@Column
アノテーションを使わなくても、DBのスネークケースのカラムをEntityのキャメルケースのフィールドに自動でマッピングするようになります。
終わりに
以上のように、Hibernateを使っているのであれば便利なクラスや設定が存在します。
同じような課題を抱えている方はぜひ試してみてください♪