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,一经查实,立即删除!

相关文章

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

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

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

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

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

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

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

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

不用地图如何导航?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 语言中的 宏定义…

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

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

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

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

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

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

Spring Data JPA 从入门到精通~关键字列表

注意除了 find 的前缀之外,我们查看 PartTree 的源码,还有如下几种前缀: private static final String QUERY_PATTERN "find|read|get|query|stream"; private static final String COUNT_PATTERN "count"; private s…

当科学遇上众包:9个值得关注的前沿科技算力众包平台

来源: 资本实验室 . 作者:李鑫找到癌症治疗的方法,预测气候的变化,追踪可能与地球相撞的小行星……甚至预测地震,我们每天都面临着各种世界性难题。如果你想参与解决这些难题,公民科学应用将让你发挥作用…

htop 命令详解

htop 官网:http://htop.sourceforge.net/ Linux top 命令的用法详细详解:https://www.cnblogs.com/zhoug2020/p/6336453.html htop 使用详解:https://www.cnblogs.com/programmer-tlh/p/11726016.html 使用 yum 无法直接安装 htop&#xff…

linux主机服务器日志采集,Linux通过Rsyslog搭建集中日志服务器

(一)Rsyslog简介ryslog 是一个快速处理收集系统日志的程序,提供了高性能、安全功能和模块化设计。rsyslog 是syslog 的升级版,它将多种来源输入输出转换结果到目的地。rsyslog是一个开源工具,被广泛用于Linux系统以通过TCP/UDP协议转发或接收…

IDC预测2022年全球智能家居连接设备市场规模将达10亿台!

来源: IDC官网、智慧生活; 物联网资本论编译摘要:2017年,全球智能家居连接设备市场规模达到43310万台,比上一年增长27.6%。2022年市场达到9.397亿台,IDC预计复合年增长率(CAGR&#…

effective C++ 读书笔记

本篇文章都是摘自 《Effective C》 中文版 第三版 和 第二版。 再好的记性也有忘记的一天,记录下以备随时查看。。。 电子书下载地址:https://download.csdn.net/download/freeking101/10278088 《Effective C》第二版在线教程:http://www.…

Spring Data JPA 从入门到精通~思维导图

#原图 System.out.println("https://www.processon.com/view/61c7227c0e3e7474fb9b4b76?fromnew1");

高通5G版图现身!你的网络生活将迎来巨变?

来源:36Kr 作者:桐由于骁龙845移动平台和骁龙636移动平台的首发,3月的手机市场对于持币代购的消费者而言注定是充满期待的,在三星S9和红米Note5刷屏之时,曾经隐身手机幕后的高通也再一次引发用户热议,高通…

linux添加nginx,linux下安装Nginx1.16.0的教程详解

因为最近在倒腾linux,想安装新版本的nginx,找了一圈教程没有找到对应的教程,在稍微倒腾了一会之后终于成功的安装了最新版。服务器环境为centos,接下来是详细步骤:安装必要依赖插件?创建文件夹并切换过去?下载安装包…

深度|2030年8亿人会失业!图解机器人如何取代你的工作

来源:财看见-腾讯财经(ID:qqckj2017)未来智能实验室是人工智能学家与科学院相关机构联合成立的人工智能,互联网和脑科学交叉研究机构。未来智能实验室的主要工作包括:建立AI智能系统智商评测体系&#xff0…

Java使用Itext5.5.10进行pdf签章

来源:Java使用Itext5.5.10进行pdf签章_liumengya007007的博客-CSDN博客_itext 签章 啰嗦 说到PDF数字签名签章,这个其实也是数字证书信息安全的应用范畴,关于数字证书和数字签名,网上有很多解释说明,但讲解都多不够详…