Spring Data JPA 从入门到精通~Naming命名策略详解及其实践

 Naming 命名策略详解及其实践

用 JPA 离不开 @Entity 实体,我都知道实体里面有字段映射,而字段映射的方法有两种:

  • 显式命名:在映射配置时,设置的数据库表名、列名等,就是进行显式命名,即通过 @Column 注解配置。
  • 隐式命名:显式命名一般不是必要的,所以可以选择当不设置名称,这时就交由 Hibernate 进行隐式命名,另外隐式命名还包括那些不能进行显式命名的数据库标识符,即不加 @Column 注解时的默认映射规则。

Naming 命名策略详解

我们通过源码发现:Naming 的源码发现 Hibernate 4 的时候隐式命名策略是 org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy;而我们发现 Hibernate 5 将隐式命名策略拆分成了两步:implicitStrategy 和 physicalStrategy。从官方的文档中得知这样做的目的是提高灵活性,减少构建命名策略过程中用到的重复的信息。

  • 第一个阶段是从对象模型中提取一个合适的逻辑名称,这个逻辑名称可以由用户指定,通过 @Column 和 @Table 等注解完成,也可以通过被 Hibernate 的 ImplicitNamingStrategy 指定。
  • 第二个阶段是将上述的逻辑名称解析成物理名称,物理名称是由 Hibernate 中的 PhysicalNamingStrategy 决定,两个阶段是有先后顺序的。

(1)ImplicitNamingStrategy

当一个实体对象没有显式的指明它要映射的数据库表或者列的名称时,在 Hibernate 内部就要为我们隐式处理,比如一个实体没有在 @Table 中的指明表名,那么表名隐式的被认为是实体名,或者 @Entity 中的提供的名称。比如一个实体没有在 @Column 中的指明列名,那么列名隐式的被认为是该实体对应的字段名,而我们看到源码默认的隐式策略采用的类是:“org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy”。

Hibernate 中定义了多个 ImplicitNamingStrategy 的实现,可以开箱即用,而之前的逻辑名名称就是物理名称这种策略只是其中一种,其他还包括:

  • ImplicitNamingStrategyJpaCompliantImpl:默认的命名策略,兼容 JPA 2.0 的规范;
  • ImplicitNamingStrategyLegacyHbmImpl:兼容 Hibernate 老版本中的命名规范;
  • ImplicitNamingStrategyLegacyJpaImpl:兼容 JPA 1.0 规范中的命名规范;
  • ImplicitNamingStrategyComponentPathImpl:大部分与 ImplicitNamingStrategyJpaCompliantImpl,但是对于 @Embedded 等注解标志的组件处理是通过使用 attributePath 完成的,因此如果我们在使用 @Embedded 注解的时候,如果要指定命名规范,可以直接继承这个类来实现。

看一下 UML 类图:

SpringImplicitNamingStrategy 继承 ImplicitNamingStrategyJpaCompliantImpl,从源码可以看到,对外键、链表查询、索引如果未定义,都有下划线的处理策略,而 table 和 column 名字都默认与字段一样。

(2)PhysicalNamingStrategy

在这个阶段中,是根据业务需要制定自己的命名规范,通过使用 PhysicalNamingStrategy 可以实现这些规则,而不需要将表名和列名通过 @Table 和 @Column 等注解显式指定,无论对象模型中是否显式地指定列名或者已经被隐式决定,PhysicalNamingStrategy 都会被调用。但是对于 ImplicitNamingStrategy,仅仅只有当没有显式地提供名称时才会使用,也就是说当对象模型中已经指定了 @Table 或者 @Entity 等 name 时,设置的 ImplicitNamingStrategy 并不会起作用。

所以可以看应用场景,我们可以根据实际需求来定义自己的策略是继承 ImplicitNamingStrategy 还是继承 PhysicalNamingStrategy,比如加上前缀 t_ 等等,或者使用分隔符“-”等等。

需要注意的是:PhysicalNamingStrategy 永远是在 ImplicitNamingStrategy 之后执行的,并且永远会被执行到。我们看下 PhysicalNamingStrategyStandardImpl 的源码:

public class PhysicalNamingStrategyStandardImpl implements PhysicalNamingStrategy, Serializable {public static final PhysicalNamingStrategyStandardImpl INSTANCE = new PhysicalNamingStrategyStandardImpl();@Overridepublic Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment context) {return name;}@Overridepublic Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment context) {return name;}@Overridepublic Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {return name;}@Overridepublic Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment context) {return name;}@Overridepublic Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {return name;}
}

默认情况下,使用就是这种策略,将 ImplicitNamingStrategy 传过来的逻辑名直接作为数据库中的物理名称,什么都没干直接返回。看下类图:

实际工作中的一些扩展

实际工作中,我们有这样的应用场景:当我们使用 MySQL 数据库的时候,一般架构师会给我们定义规范和要求,字段一般都是小写加 "_" 下划线组成,而我们的 Java 类当中都是驼峰式的字段命名方式。如果我们一个新的微服务,每个表都非常标准和规范,那么就可以让实体当中省去 @column 指定名称的过程。

定义自己的 PhysicalNamingStrategy 继承 PhysicalNamingStrategyStandardImpl 类即可内容如下:

package com.jack.model.naming;
public class MyPhysicalNamingStrategy extends PhysicalNamingStrategyStandardImpl {
//重载PhysicalColumnName方法,修改字段的物理名称。@Overridepublic Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {String text = warp(name.getText());if(Objects.equals(text.charAt(0) , '_')){text = text.replaceFirst("_","");}return super.toPhysicalColumnName(new Identifier(text,name.isQuoted()), context);}
//将驼峰式命名转化成下划线分割的形式public static String warp(String text){text = text.replaceAll("([A-Z])","_$1").toLowerCase();if(Objects.equals(text.charAt(0) , '_')){text = text.replaceFirst("_","");}return text;}
}

修改 application.properties 添加如下内容即可:

spring.jpa.hibernate.naming.physical-strategy=com.jack.model.naming.MyPhysicalNamingStrategy

总结:

不过在实际工作中还是建议大家用显式 @Table @Column 等注解的时候就指明比较好,而可以在我们扩展的 MyPhysicalNamingStrategy 做规则验证工作,避免有些程序员没有按照我们的数据库规范命名。

H2 Database

H2 Database 是一个开源的嵌入式数据库引擎,采用 Java 语言编写,支持 SQL,同时 H2 提供了一个十分方便的 Web 控制台用于操作和管理数据库内容。是一种内存数据库,Spring Data JPA 官方也推荐使用,不过作者建议读者在实际生产环境,我们都是用来跑测试用例的。这样可以对各种关键的 DB 没有影响,因为它是每次运行创建一份新的数据库的。

使用起来比较方便,不需要安装 Server 和 Client 的任何软件和工具,只需要我们用的时候引用一个 Jar 就可以自带 SQL 的 Server 和 Client 的操作了,非常适合演示项目使用。

我们来看一个使用案例。

(1)Gradle 引入 H2 的 jar 包

testCompile group: 'com.h2database', name: 'h2', version: '1.3.148'

(2)配置 application.properties 如下:

//# JDBC Url to use H2 DB File for persisting
spring.datasource.url:jdbc:h2:./database/samspledb;AUTO_SERVER=TRUE
//# Use H2 DB Driver
spring.datasource.driverClassName:org.h2.Driver

(3)其他什么都用改,直接启动项目就可以操作我们默认的 JPA @Entity了。

spring.jpa.hibernate.ddl-auto=update

我们再加上 ddl-auto 的配置成 update,就可以完美实现内存数据库方式的 test case 了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/496273.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C 和 C++ 字符串格式化

--------------------------------------------------------------------------------- gcc中格式化输出函数的研究:http://blog.csdn.net/dai_xiangjun/article/details/41356723 C语言格式化输出小结:http://blog.51cto.com/happyliu/1621709 代码如…

转载(四).Net Framework中的委托与事件

尽管 (委托、事件与Observer设计模式 )中的范例很好地完成了我们想要完成的工作,但是我们不仅疑惑:为什么.Net Framework 中的事件模型和上面的不同?为什么有很多的EventArgs参数? 在回答上面的问题之前&am…

激光雷达:从光电技术角度看自动驾驶

来源: 传感器技术激光雷达和与之竞争的传感器技术(相机、雷达和超声波)加强了对传感器融合的需要,也对认真谨慎地选择光电探测器、光源和MEMS振镜提出了更高的要求。传感器技术、成像、雷达、光探测技术及测距技术(激光…

Spring Data JPA 从入门到精通~定义查询方法的配置方法

定义查询方法的配置方法 由于 Spring JPA Repository 的实现原理是采用动态代理的机制,所以我们介绍两种定义查询方法,从方法名称中可以指定特定用于存储的查询和更新,或通过使用 Query 手动定义的查询,取决于实际对数据的操作&a…

socket的长连接、短连接、半包、粘包与分包

socket的半包,粘包与分包的问题和处理代码:http://blog.csdn.net/qq_16112417/article/details/50392463 知乎关于长连接和短连接:https://www.zhihu.com/search?typecontent&q长连接%20短连接 TCP网络通讯如何解决分包粘包问题&#…

在Windows2003server上安装msn9.0以上版本的解决办法

方法一: 最近windows 强制升级了msn 9的版本。导致我在windows2003下的msn又一次需要剥离出msi文件才能安装了。在网上逛了一圈发现了如下方法,这里分享下,同时,也感谢作者的详细步骤。 2003SERVER版安装MSN 9.0(版本2…

oracle exec编译失效,编译oracle失效的函数、存储过程、视图等

进行oracle开发时常常为不时失效的存储过程,函数等苦恼,于是下决心解决这个问题,东查西找,找到一个好东东,在基础上又修改了一下,问题终于被我解决了。1。建立一个存储过程CREATE OR REPLACE PROCEDURE TIMER_AUTO_REC…

2018年中国人工智能行业研究报告|附下载

来源:网络大数据、艾瑞咨询广义人工智能指通过计算机实现人的头脑思维所产生的效果,是对能够从环境中获取感知并执行行动的智能体的描述和构建;相对狭义的人工智能包括人工智能产业(包含技术、算法、应用等多方面的价值体系)、人工智能技术(包括凡是使用…

浅谈基于TCP和UDP的协议设计

From:http://blog.sina.com.cn/s/blog_48d4cf2d0101859x.html 一个基于TCP/WebSockets的超级精简的长连接消息协议:https://studygolang.com/articles/10506 github 上 一个简单的消息协议:https://github.com/acrazing/stmp google prot…

Spring Data JPA 从入门到精通~方法的查询策略设置

方法的查询策略设置 通过下面的命令来配置方法的查询策略: EnableJpaRepositories(queryLookupStrategy QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND) 其中,QueryLookupStrategy.Key 的值一共就三个: Create:直接根据方法名…

IE6下PNG图片透明效果(PNG图片做背景也可以)

懒人萱在这里保证发的文章都是高质量的经过测试的JS代码,而且IE6、IE7和火狐都兼容的,希望大家多多关注我的帖子,我会把我的经验都共享出来哦!  懒人萱在寻找PNG图片透明效果的JS特效代码的时候,发现大部分的效果只能…

oracle数据块调用存储过程,VC调用存储过程的通用方法(ORACLE篇)

先对上一篇调用SQLServer的存储过程作一点补充,就是如果存储过程里有Insert,update,delete等操作,最后返回结果集,按示例代码有可能得不到数据,因为返回的数据有可能不在第一个结果集,需要进行遍历:long ln…

不用地图如何导航?DeepMind提出新型双路径强化学习「智能体」架构

来源:deepmind、arXiv作者:Piotr Mirowski、Matthew Koichi Grimes、Mateusz Malinowski、Karl Moritz Hermann、Keith Anderson、Denis Teplyashin、Karen Simonyan、Koray Kavukcuoglu、Andrew Zisserman、Raia Hadsell「雷克世界」编译:嗯…

C 和 C++ 宏 详解

From:https://www.cnblogs.com/njczy2010/p/5773061.html C中的预编译宏详解:http://www.cppblog.com/bellgrade/archive/2010/03/18/110030.html C语言的宏总结:http://blog.csdn.net/pirlck/article/details/51254590 C 语言中的 宏定义…

常用代码生成工具介绍

1:CodeSmith工具优点:支持模板类,可扩展强。建议使用。目前公认的最强大的代码生成工具,支持各种语言。可以和开发环境无缝集成。例如:Vs2008等。缺点:不免费,最新的可破解版本为4.0.2&#xff…

Spring Data JPA 从入门到精通~查询方法的创建

查询方法的创建 内部基础架构中有个根据方法名的查询生成器机制,对于在存储库的实体上构建约束查询很有用,该机制方法的前缀 find…By、read…By、query…By、count…By 和 get…By 从所述方法和开始分析它的其余部分(实体里面的字段&#x…

oracle表参数,Oracle 表的创建 及相关参数

1、创建表完整语法CREATE TABLE [schema.]table(column datatype [, column datatype] … )[TABLESPACE tablespace][PCTFREE integer][PCTUSED integer][INITRANS integer][MAXTRANS integer][STORAGE storage-clause][LOGGING | NOLOGGING][CACHE | NOCACHE] ];说明&#xff…

人工智能在能源行业的5个应用

作者:CB Insights . 来源:CometLabs摘要:自2012年以来,把人工智能和能源产业放在一起进行报道的新闻开始增多。本文简要描述了人工智能在能源行业的5个应用方向,及对应的案例。能源行业会产生大量的数据。为了将这些数…

fork vfork exit _exit (转)

原文地址&#xff1a;http://hi.baidu.com/ikaruga11/blog/item/fb6d75725a8d8d148701b080.htmlAPUE上的一个例子&#xff1a;example1 (forkt.c ):#include<stdlib.h>#include<unistd.h>#include<stdio.h>#include<sys/types.h>int glob 5;int main(…

VMware 安装 win7、win10、MAC 和网络模式VMnet0、VMnet1、VMnet8解释

VMware虚拟机安装ghost win7系统方法&#xff1a;http://www.xitongcheng.com/jiaocheng/xtazjc_article_15314.html VMWare14 安装Mac OS系统&#xff08;图解&#xff09;&#xff1a;http://blog.csdn.net/u011415782/article/details/78505422 虚拟机&#xff08;VMware …