投稿日:
2019年10月6日
最終更新日:
【ImprovedNamingStrategyは廃止】スネークケースのDBカラムをキャメルケースのEntityフィールドにマッピングする方法【PhysicalNamingStrategyStandardImpl】
YouTubeも見てね♪
ねこじゃすり
猫を魅了する魔法の装備品!
[ノースフェイス] THE NORTH FACE メンズ アウター マウンテンライトジャケット
防水暴風で耐久性抜群なので旅行で大活躍です!
ペヤング ソースやきそば 120g×18個
とりあえず保存食として買っておけば間違いなし!
レッドブル エナジードリンク 250ml×24本
翼を授けよう!
ドラゴンクエスト メタリックモンスターズギャラリー メタルキング
みんな大好き経験値の塊をデスクに常備しておこう!
BANDAI SPIRITS ULTIMAGEAR 遊戯王 千年パズル 1/1スケール
もう一人の僕を呼び覚ませ!!
MOFT X 【新型 ミニマム版】 iPhone対応 スマホスタンド
Amazon一番人気のスマホスタンド!カード類も収納出来てかさ張らないのでオススメです!
目次
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を使っているのであれば便利なクラスや設定が存在します。
同じような課題を抱えている方はぜひ試してみてください♪