摘要:所以設計的表名映射格式為,如果不加注解,則將實體名按照默認的生成規則進行生成,如果加了注解,則填寫的就作為表名映射,不進行任何處理。云智命名策略實體與數據表名的關系配置然后將該項配置修改為我們自己建立的實現類。
問題描述 Hibernate映射介紹
Hibernate中,默認的生成關系是將我們駝峰命名的實體進行拼接下劃線同時轉小寫。
這種情況我們可以接受,默認的設置很規范。
但是這樣,我們在實體之上聲明了@Table注解,并說我們的表名是Mandatory_Instrument_Apply,但是Hibernate還是將我們的數據表映射為小寫加下劃線的形式。這種情況看起來就有些不合理了。
業務需求因為需要兼容老項目,老項目的數據表命名不很很規范,所以需要用最小的成本實現數據庫的兼容。
所以設計的表名映射格式為,如果不加@Table注解,則將實體名按照Hibernate默認的生成規則進行生成,如果加了@Table注解,則填寫的name就作為表名映射,不進行任何處理。
功能實現 入門拋出來一個問題,無從下手。
打開瀏覽器,看看有沒有前人的經驗,Google來Google去發現找不著啥有價值的信息。但是在StackOverflow上找到一篇引人思索的問題。
Spring boot JPA insert in TABLE with uppercase name with Hibernate - StackOverflow
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
將這個配置聲明為org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl,就能實現大寫的轉換。
試試再說:
將配置按該問題的回答進行修改:
測試一番:
加了@Table注解的,是我們想要的配置,直接映射。那不加注解的呢?
這個又不是我們想要的了,這個注解應該是直接將注解中的名或實體名映射到數據表,不做任何修改。
發現新大陸正當一籌莫展之時,再去看一下配置,有了新的領悟。
org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl,這個配置的不就是一個實現類嗎?我是不是也可以寫一個類然后將我寫的類配置上呢?
點進去,發現不過是一個實現了PhysicalNamingStrategy與Serializable兩個接口的類。
看實現的toPhysicalTableName方法,應該就是生成數據表名的方法。直接將name返回,這就和我們之前猜想的一致,這個配置是直接將@Table或實體名映射到數據表。
YunzhiNamingStrategy建立配置類YunzhiNamingStrategy.java,云智命名策略,分別實現上述PhysicalNamingStrategyStandardImpl實現的兩個接口。同時實現接口中聲明的方法。
package com.mengyunzhi.demo.config; import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.naming.PhysicalNamingStrategy; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import java.io.Serializable; /** * @author zhangxishuo on 2018/6/15 * 云智命名策略 * 實體與數據表名的關系配置 */ public class YunzhiNamingStrategy implements PhysicalNamingStrategy, Serializable { @Override public Identifier toPhysicalCatalogName(Identifier identifier, JdbcEnvironment jdbcEnvironment) { return null; } @Override public Identifier toPhysicalSchemaName(Identifier identifier, JdbcEnvironment jdbcEnvironment) { return null; } @Override public Identifier toPhysicalTableName(Identifier identifier, JdbcEnvironment jdbcEnvironment) { return null; } @Override public Identifier toPhysicalSequenceName(Identifier identifier, JdbcEnvironment jdbcEnvironment) { return null; } @Override public Identifier toPhysicalColumnName(Identifier identifier, JdbcEnvironment jdbcEnvironment) { return null; } }
然后將該項配置修改為我們自己建立的實現類。
兼容原配置項因為該接口中有多個配置項,如:數據庫名、字段名等,我們只想修改實體到數據表的命名策略,所以我們找到了另一個實現PhysicalNamingStrategy命名策略的實現類:SpringPhysicalNamingStrategy。
這就是我們第一次演示的策略,無論添不添加@Table注解,都會映射到小寫的加下劃線的表名。
同時這里的字段映射為小寫下劃線我們是需要保留的,為了代碼的復用,我們用到了面向對象的繼承大法。
package com.mengyunzhi.demo.config; import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy; /** * @author zhangxishuo on 2018/6/15 * 云智命名策略 * 實體與數據表名的關系配置 */ public class YunzhiNamingStrategy extends SpringPhysicalNamingStrategy { }
我們對父類中的toPhysicalTableName方法不滿意,Command + N,重寫父類方法。
package com.mengyunzhi.demo.config; import org.hibernate.boot.model.naming.Identifier; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy; /** * @author zhangxishuo on 2018/6/15 * 云智命名策略 * 實體與數據表名的關系配置 */ public class YunzhiNamingStrategy extends SpringPhysicalNamingStrategy { @Override public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) { return super.toPhysicalTableName(name, jdbcEnvironment); } }注解判斷
我們可以開始我們的邏輯了。
有@Table注解的,就按@Table中的名稱中,否則就按Spring默認的父類走。
但是問題出現了,Identifier中給我們的名稱就是已經處理好的名稱。
Identifier假如這么寫:
@Entity public class MandatoryInstrumentApply { }
那我們的Identifier中的text值就是MandatoryInstrumentApply。
@Entity @Table(name = "Mandatory_Instrument_Apply") public class MandatoryInstrumentApply { }
那我們的Identifier中的text值就是Mandatory_Instrument_Apply。
Hibernate是把應該處理好的名稱告訴我們,但是不會告訴我們這個名稱是實體的名還是在注解上獲取的。
解決方案package com.mengyunzhi.demo.config; import org.hibernate.boot.model.naming.Identifier; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy; import javax.persistence.Table; /** * @author zhangxishuo on 2018/6/15 * 云智命名策略 * 實體與數據表名的關系配置 */ public class YunzhiNamingStrategy extends SpringPhysicalNamingStrategy { // 定義包名 private static final String packageName = "com.mengyunzhi.demo.entity."; /** * 重寫父類生成表名的方法 */ @Override public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) { try { // 獲取實體類 Class entityClass = Class.forName(packageName + name.getText()); // 判斷類上是否有Table注解 Boolean hasAnnotation = entityClass.isAnnotationPresent(Table.class); // 存在Table注解 if (hasAnnotation) { // 獲取Table注解實例 Table table = (Table) entityClass.getAnnotation(Table.class); // 如果注解中的name字段不為空 if (!table.name().equals("")) { // 不對名稱進行處理 return name; } } // 表示這是一個類名,按父類操作進行處理 return super.toPhysicalTableName(name, jdbcEnvironment); } catch (ClassNotFoundException e) { // 找不到實體類,說明肯定是@Table注解中的名稱 return name; } } }測試
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/71208.html
摘要:文章系列從零入門系列之從零入門系列之程序結構設計說明前言本篇文章開始代碼實踐,系統設計從底向上展開,因此本篇先介紹如何實現數據庫表實體類的設計實現。主鍵由數據庫自動生成主要是自動增長型主鍵由程序控制。 文章系列 【從零入門系列-0】Sprint Boot 之 Hello World 【從零入門系列-1】Sprint Boot 之 程序結構設計說明 前言 本篇文章開始代碼實踐,系統...
摘要:一配置屬性詳解可以在各式各樣不同環境下工作而設計的因此存在著大量的配置參數。以簡便操作,多數配置參數都有默認的配置值也是我們日常使用的必須品。 Hibernate (開放源代碼的對象關系映射框架) Hibernate是一個開放源代碼的對象關系映射框架,它對JDBC進行了非常輕量級的對象封裝, 它將POJO與數據庫表建立映射關系,是一個全自動的orm框架,hibernat...
摘要:聲明添加對樂觀鎖定的支持一些屬性關聯關系獲取方式即是否采用延時加載及時加載,是在查詢數據時,也直接一起獲取關聯對象的數據。在前面的基礎上增加課程類并補充學生類學生類負責關聯關系 Hibernate 注解使用 在Hibernate中通常配置對象關系映射關系有兩種,一種是基于xml的方式,另一種是基于Hibernate Annotation庫的注解方式。在Hibernate 3.2版本和J...
摘要:前言首先聲明,這是一篇轉發博客,不屬于原創。關系映射有下面幾種類型一對一外鍵關聯映射單向一對一外鍵關聯,使用,并設置了級聯操作。設置了外鍵的名稱為數據庫字段名,如果不設置,則默認為另一類的屬性名,外鍵的值是唯一的。 前言 首先聲明,這是一篇轉發博客,不屬于原創。但是感覺很有用,所以在本人的博客中記錄下來。 Hibernate Annotation關系映射有下面幾種類型: 一對一...
摘要:不管是還是,表之間的連接查詢,被映射為實體類之間的關聯關系,這樣,如果兩個實體類之間沒有實現關聯關系,你就不能把兩個實體或者表起來查詢。 因為項目需要選擇數據持久化框架,看了一下主要幾個流行的和不流行的框架,對于復雜業務系統,最終的結論是,JOOQ是總體上最好的,可惜不是完全免費,最終選擇JDBC Template。 Hibernate和Mybatis是使用最多的兩個主流框架,而JOO...
閱讀 3201·2021-11-25 09:43
閱讀 3206·2021-11-23 09:51
閱讀 3519·2019-08-30 13:08
閱讀 1569·2019-08-29 12:48
閱讀 3594·2019-08-29 12:26
閱讀 397·2019-08-28 18:16
閱讀 2562·2019-08-26 13:45
閱讀 2429·2019-08-26 12:15