JPA 概述及常用注解详解、SpringDataJpa 使用指南

news2024/11/27 16:27:32

JPA(Java Persistence API)是 Java 标准中的一套ORM规范(提供了一些编程的 API 接口,具体实现由 ORM 厂商实现,如Hiernate、TopLink 、Eclipselink等都是 JPA 的具体实现),借助 JPA 技术可以通过注解或者XML描述【对象-关系表】之间的映射关系,并将实体对象持久化到数据库中(即Object Model与Data Model间的映射)。

JPA是Java持久层API,由Sun公司开发,希望规范、简化Java对象的持久化工作,整合ORM技术,整合第三方ORM框架,建立一种标准的方式,目前也是在按照这个方向发展,但是还没能完全实现。在ORM框架中,Hibernate框架做了较好的 JPA 实现,已获得Sun的兼容认证。

JPA 的优势:

1.开发者面向 JPA 规范的接口,但底层的JPA实现可以任意切换:觉得Hibernate好的,可以选择Hibernate JPA实现;觉得TopLink好的,可以选择TopLink JPA实现。

2.开发者可以避免为使用Hibernate学习一套ORM框架,为使用TopLink又要再学习一套ORM框架。

JPA为我们提供了以下规范:

  • ORM映射元数据:JPA支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中
  • JPA的Criteria API:提供API来操作实体对象,执行CRUD操作,框架会自动将之转换为对应的SQL,使开发者从繁琐的 JDBC、SQL中解放出来。
  • JPQL查询语言:通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。

Hibernate介绍

Hibernate对数据库结构提供了较为完整的封装,Hibernate的O/R Mapping实现了POJO 和数据库表之间的映射,以及SQL 的自动生成和执行。往往只需定义好了POJO 到数据库表的映射关系,即可通过Hibernate 提供的方法完成持久层操作。甚至不需要对SQL 的熟练掌握, Hibernate/OJB 会根据制定的存储逻辑,自动生成对应的SQL 并调用JDBC 接口加以执行。

Hibernate框架(3.2及以上版本)对JPA接口规范做了较好的实现,主要是通过以下三个组件来实现的:

  • hibernate-annotation:是Hibernate支持annotation方式配置的基础,它包括了标准的 JPA annotation以及Hibernate自身特殊功能的annotation。
  • hibernate-core:是Hibernate的核心实现,提供了Hibernate所有的核心功能。
  • hibernate-entitymanager:实现了标准的 JPA,可以把它看成hibernate-core和 JPA 之间的适配器,它并不直接提供ORM的功能,而是对hibernate-core进行封装,使得Hibernate符合 JPA 的规范。

hibernate对 JPA 的支持,不是另提供了一套专用于 JPA 的注解。一些重要的注解如@Column, @OneToMany等,hibernate并没有提供,这说明 JPA 的注解已经是hibernate 的核心,hibernate只提供了一些补充,而不是两套注解。JPA 和hibernate都提供了的注解(例如@Entity),若 JPA 的注解够用,就直接用,若 JPA 的注解不够用,直接使用hibernate的即可。

Spring Data JPA介绍

Spring Data JPA是在实现了 JPA 规范的基础上封装的一套 JPA 应用框架(Criteria API还是有些复杂)。虽然ORM框架都实现了 JPA 规范,但是在不同的ORM框架之间切换仍然需要编写不同的代码,而使用Spring Data JPA能够方便的在不同的ORM框架之间进行切换而不需要更改代码。Spring Data JPA旨在通过统一ORM框架的访问持久层的操作,来提高开发人的效率。

Spring Data JPA是一个 JPA 数据访问抽象。也就是说Spring Data JPA不是一个实现或 JPA 提供的程序,它只是一个抽象层,主要用于减少为各种持久层存储实现数据访问层所需的样板代码量。但是它还是需要JPA提供实现程序,其实Spring Data JPA底层就是使用的 Hibernate实现。

Spring Data JPA 其实并不依赖于 Spring 框架。

Spring Data JPA 通过Repository来支持上述功能,默认提供的几种Repository已经满足了绝大多数需求:

  • JpaRepository( 为Repository的子接口:JpaRepository -> PagingAndSortingRepository -> CrudRepository -> Repository)
  • QueryByExampleExecutor
  • JpaSpecificationExecutor
  • QuerydslPredicateExecutor

后三者用于更复杂的查询,如动态查询、关联查询等;第一种用得最多,提供基于方法名(query method)的查询,用户可基于第一种继承创建自己的子接口(只要是Repository的子接口即可),并声明各种基于方法名的查询方法。

  • Repository 的实现类:

    • SimpleJpaRepository
  • QueryDslJpaRepository

JPA与springDataJpa、Hibernate 之间的关系

533121-20160122105513781-959577889.png

JPA 注解

Entity 常用注解

指定对象与数据库字段映射时注解的位置:如@Id、@Column等注解指定Entity的字段与数据库字段对应关系时,注解的位置可以在Field(属性)或Property(属性的get方法上),两者统一用其中一种,不能两者均有。推荐用前者。

@Entity、@Table

@Entity(必需)

标注在实体类上。

映射实体类。指出该 Java 类为实体类,将映射到指定的关系数据库表。

应用了此注解后,将会自动将类名映射作为数据库表名、将类内的字段名映射为数据库表的列名。映射策略默认是按驼峰命名法拆分将类名或字段名拆分成多部分,然后以下划线连接,如StudentEntity -> student_entity、studentName -> student_name。若不按默认映射,则可通过@Table、@Column指定,见下面。

@Table(可选)

标注在实体类上。

映射数据库表名。当实体类与其映射的数据库表名不同名时需要使用 @Table 标注说明,该标注与 @Entity 标注并列使用

  • schema属性:指定数据库名
  • name属性:指定表名,不指定时默认按驼峰命名法拆分将类名,并以下划线连接

@DynamicInsert、@DynamicUpdate

@DynamicInsert(可选)

标注在实体类上。

设置为true,表示insert对象的时候,生成动态的insert语句,如果这个字段的值是null就不会加入到insert语句中,默认false。

@DynamicUpdate(可选)

标注在实体类上。

设置为true,表示执行update对象时,在生成动态的update语句前,会先查询该表在数据库中的字段值,并对比更新使用的对象中的字段值与数据库中的字段值是否相同,若相同(即该值没有修改),则该字段就不会被加入到update语句中。

默认false,表示无论更新使用实体类中的字段值与数据库中的字段值是否一致,都加入到update语句中,即都使用对象中所有字段的值覆盖数据库中的字段值。

比如只想更新某个属性,但是却把整个属性都更改了,这并不是我们希望的结果,我们希望的结果是:我更改了哪写字段,只要更新我修改的字段就够了。

注意:

@DynamicUpdate的动态更新的含义是,比较更新要使用的实体类中的所有字段值与从数据库中查询出来的所有字段值,判断其是否有修改,不同则加入到update语句中更新字段值。看这个例子,数据库中id=1的记录所有字段都是非空的,但是实体类中只有name有值,也就是所有字段都变了,只是其他字段被更新为了新的空值。

所以 jpa 更新数据库字段值,无论是否有 @DynamicUpdate注解,均需要手动先select对象,然后通过set更新对象的属性值,然后再save对象,实现更新操作

@Id、@GeneratedValue

@Id(必需)

标注在实体类成员变量或getter方法之上。

映射生成主键。用于声明一个实体类的属性映射为数据库的一个主键列。

若同时指定了下面的@GeneratedValue则存储时会自动生成主键值,否则在存入前用户需要手动为实体赋一个主键值。

主键值类型可以是:

  • Primitive types:

    boolean, byte, short, char, int, long, float, double

  • Equivalent wrapper classes from package java.lang:

    Byte,Short, Character, Integer, Long, Float, Double

  • java.math.BigInteger, java.math.BigDecimal
  • java.lang.String
  • java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp
  • Any enum type
  • Reference to an entity object
  • composite of several keys above

指定联合主键,有@IdClass、@EmbeddedId两种方法。

@GeneratedValue

@GeneratedValue 用于标注主键的生成策略,通过 strategy 属性指定。

默认情况下,JPA 自动选择一个最适合底层数据库的主键生成策略:SqlServer 对应 identity,MySQL 对应 auto increment

  • AUTO: JPA自动选择合适的策略,是默认选项
  • IDENTITY:采用数据库 ID自增长的方式来自增主键字段,Oracle 不支持这种方式
  • TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。
  • SEQUENCE:通过序列产生主键,通过 @SequenceGenerator 注解指定序列名,MySql 不支持这种方式

@Column、@Basic、@Transient

@Column(可选)

标注在实体类成员变量或getter方法之上。

映射表格列。当实体的属性与其映射的数据库表的列不同名时需要使用 @Column 标注说明。

类的字段名在数据库中对应的字段名可以通过此注解的name属性指定,不指定则默认为将属性名按驼峰命名法拆分并以下划线连接,如 createTime 对应 create_time

注意:即使name的值中包含大写字母,对应到db后也会转成小写,如@ Column(name="create_Time") 在数据库中字段名仍为create_time。可通过SpringBoot配置参数【spring.jpa.hibernate.naming.physical-strategy】配置对应策略,如指定name值是什么,数据库中就对应什么名字的列名。默认值为:【org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy】

@Column注解一共有10个属性,这10个属性均为可选属性,各属性含义分别如下:

  • name:定义了被标注字段在数据库表中所对应字段的名称。
  • unique:该字段是否为唯一标识,默认为false。也可以使用@Table标记中的@UniqueConstraint。
  • nullable:该字段是否可以为null值,默认为true。
  • length:字段的长度,当字段的类型为varchar时,该属性才有效,默认为255个字符。
  • insertable:在使用“INSERT”脚本插入数据时,是否插入该字段的值。默认为true。
  • updatable:在使用“UPDATE”脚本插入数据时,是否更新该字段的值。默认为true。

    insertable = false 和updatable = false 一般多用于只读的属性,例如主键和外键等。这些字段的值通常是自动生成的。

  • columnDefinition:建表时创建该字段的DDL语句,一般用于通过Entity生成表定义时使用。

    (如果DB中表已经建好,该属性没有必要使用)

  • precision和scale:表示精度,当字段类型为double时,precision表示数值的总长度,scale表示小数点所占的位数。
  • table:定义了包含当前字段的表名。

@Basic(可选)

表示一个简单的属性到数据表的字段的映射,对于没有任何标注的属性或getter方法,默认标注为 @Basic

  • fetch 表示属性的读取策略,有 EAGER 和 LAZY 两种,分别为立即加载和延迟加载
  • optional 表示该属性是否允许为 null,默认为 true

@Transient:忽略属性

定义暂态属性。表示该属性并非一个到数据库表的字段的映射,ORM 框架将忽略该属性。

如果一个属性并非数据库表的字段映射,就必须将其标识为 @Transient,否则ORM 框架默认为其注解 @Basic,例如工具方法不需要映射。

@Temporal:时间日期精度

标注在实体类成员变量或getter方法之上。可选。

在 JavaAPI 中没有定义 Date 类型的精度,而在数据库中表示 Date 类型的数据类型有 Date(年月日),Time(时分秒),TimeStamp(年月日时分秒) 三种精度,进行属性映射的时候可以使用 @Temporal 注解调整精度。

目前此注解只能用于修饰JavaAPI中的【java.util.Date】、【java.util.Calendar】类型的变量,TemporalType 取 DATE、TIME、TIMESTAMP 时在MySQL中分别对应的 DATE、TIME、DATETIME 类型。

 

JPA 概述及常用注解详解、SpringDataJpa 使用指南-阿里云开发者社区

 

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

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

相关文章

Unity3D 入门

文章目录 拖拽快捷键资源商店地形构建器 拖拽快捷键 首先看到Scene界面,我们布置游戏场景中的游戏对象基本是在这个界面完成的 鼠标滚轮键按住:能够拖拽平面,不移动对象鼠标右键按住:能够旋转我们观察界面的视角,不移…

快速理解并实现权限控制

什么是权限控制? 权限控制是指在一个系统或应用中对用户或角色的操作进行限制和管理的过程。它用于确保只有经过授权的用户或角色能够执行特定的操作或访问特定的资源。权限控制是信息安全和访问控制的重要组成部分。 权限控制的主要目的是保护系统的安全性和完整性&#xf…

GEE:支持向量机(SVM)分类参数说明和官方案例

作者:CSDN @ _养乐多_ 本文记录了在GEE平台上进行支持向量机(SVM)分类使用ee.Classifier.libsvm的说明和官方案例。 文章目录 一、函数介绍1.1 GEE上说明1.2 函数说明二、官方案例一、函数介绍 1.1 GEE上说明 ee.Classifier.libsvm(decisionProcedure, svmType, kernelTyp…

CentOS5678 repo源 地址 阿里云开源镜像站

CentOS5678 repo 地址 阿里云开源镜像站 https://mirrors.aliyun.com/repo/ CentOS-5.repo https://mirrors.aliyun.com/repo/Centos-5.repo [base] nameCentOS-$releasever - Base - mirrors.aliyun.com failovermethodpriority baseurlhttp://mirrors.aliyun.com/centos/$r…

Springboot JPA 集成多租户

背景: ​ iot-kit项目用的是jpa,不是mybatis,项目中需要引入多租户 参考文章: 【讲解多租户的实现与原理】 https://www.bilibili.com/video/BV1F84y1T7yf/?share_sourcecopy_web&vd_source981718c4abc87423399e43793a5d3…

pytest实现用例间参数传递的方式

pytest实现用例间参数传递的方式 一、通过conftest创建全局变量二、使用tmpdir_factory方法 我们在做接口自动化测试的时候,会经常遇到这种场景:接口A的返回结果中的某个字段,是接口B的某个字段的入参。如果是使用postman,那我们可…

前端精度丢失处理

前端操作数据时,如果数据超出一定范围会出现精度丢失的问题,这是因为,在传输过程中,数据类型被转换成Number,Number的精度范围在2^53之间,即 -9007199254740991 ~ 9007199254740991,超出范围就会…

Unity游戏源码分享-迷你高尔夫球游戏MiniGolfConstructionKitv1.1

Unity游戏源码分享-迷你高尔夫球游戏MiniGolfConstructionKitv1.1 有多个游戏关卡 工程地址:https://download.csdn.net/download/Highning0007/88052881

Unity游戏源码分享-射酒瓶游戏Demo

Unity游戏源码分享-射酒瓶游戏Demo 工程地址:https://download.csdn.net/download/Highning0007/88052883

财务报表制作:哪些软件值得推荐?

当今,企业需要准确、及时地制作各种会计报表,以便管理者更好地掌握财务状况。然而,使用传统的纸质方式进行制表常常会出现复杂、繁琐等问题,降低制表效率。因此,使用会 计软件成为了制表的首选。 传统制作财务报表的方…

前端理解的HTTP缓存(缓存的过程/策略/控制机制/作用和应用)

目录 一、HTTP缓存有什么作用? 二、 浏览器的缓存策略有哪些? 1、强缓存(Expires、Cache-control) 2、协商缓存(Last-Modified、ETag) 3、缓存过程是什么? 三、浏览器缓存控制机制有哪些&…

八股文(消息队列)

文章目录 1. RabbitMQ特点2. 如何保证消息的可靠性3. RabbitMQ消息的顺序性4. 实现RabbitMQ的高可用性5. 如何解决消息队列的延时以及过期失效问题?6. RabbitMQ死信队列7. RabbitMQ延迟队列8.RabbitMQ的工作模式9. RabbitMQ消息如何传输10. 核心概念10.1 生产者和消…

MATLAB 常用函数小结

文章目录 【 生成 】随机数零或一其他 【 提取 】【 统计 】【 算法 】【 文件 】 【 生成 】 随机数 rand() rand(a,b) 生成区间 (0,1) 内均匀分布的随机数字组成的 axb 列矩阵。 均值0.5,方差1/120.08333。k*rand(a,b) 生成区间 (0,k) 内服从均匀分布的随机数字组…

华为OD机试真题 Java 实现【分割数组的最大差值】【2023 B卷 100分】,附详细解题思路

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷&#…

layui实现选项卡(万字博客!!!)

今日金句 努力不一定会被看到,但成功会 文章目录 前言一、什么是Tab选项卡二、Tab分类2.1 默认风格2.2 动态Tab2.3 Hash Tab2.4 简洁Tab2.5 卡片Tab2.6 响应式Tab2.7 带删除的Tab2.8 Js代码 三、实例3.1 引入html代码3.2 编写Js代码3.3 优化1:对应名称、…

javascript编写奇迹mu原版(含服务端)(7) 地图界面

其实主要的功能还是聊天,打怪我打算弄成自动的。可以传送到地图怪密集的地方打怪,然后获得经验和道具,也可发广告收消息。地图上那些是石头等不可移动的区域。怪和人都还没标上去,暂时想的是在地图上标一个红色的点。

人工智能自然语言处理:N-gram和TF-IDF模型详解

人工智能自然语言处理:N-gram和TF-IDF模型详解 1.N-gram 模型 N-Gram 是一种基于统计语言模型的算法。它的基本思想是将文本里面的内容按照字节进行大小为 N 的滑动窗口操作,形成了长度是 N 的字节片段序列。 每一个字节片段称为 gram,对所…

第一阶段-第九章 Python的异常、模块与包

目录 一、了解异常  1.学习目标  2.什么是异常  3.bug单词的诞生  4.本节的演示  5.本小节的总结 二、异常的捕获方法  1.学习目标  2.为什么要捕获异常  3.如何进行异常的捕获(异常为常规的、指定的、多个时,捕获所有异常、异常else、f…

跟我一起从零开始学python(八)全栈开发

前言 回顾之前讲了python语法编程 ,必修入门基础和网络编程,多线程/多进程/协程等方面的内容,后续讲到了数据库编程篇MySQL,Redis,MongoDB篇,和机器学习前面没看的也不用往前翻,系列文已经整理…

【ArcGIS Pro微课1000例】0028:绘制酒店分布热力图(POI数据)

本文讲解在ArcGIS Pro中文版中,基于长沙市酒店宾馆分布矢量点数据(POI数据)绘制酒店分布热力图。 文章目录 一、加载酒店分布数据二、绘制热度图参考阅读: 【GeoDa实用技巧100例】004:绘制长沙市宾馆热度图 【ArcGIS微课1000例】0070:制作宾馆酒店分布热度热力图 一、加载…