dy业务低价自助下单平台网站/seo外包服务专家
✅✅作者主页:🔗孙不坚1208的博客
🔥🔥精选专栏:🔗JavaWeb从入门到精通(持续更新中)
📋📋 本文摘要:本篇文章主要介绍JPA的概念、注解实现ORM规范的关联关系、JPA实战以及ORM流行框架。💞💞觉得文章还不错的话欢迎大家点赞👍➕收藏⭐️➕评论💬支持博主🤞
👉 👉你的一键三连是我更新的最大动力❤️❤️
JPA基础
- 一、JPA概述
- 1.JPA概念
- 2.实体
- 3.ORM注解
- 一对一关系
- 一对多关系
- 多对一关系
- 多对多关系
- 4.JPQL
- 二、JPA实战
- 三、流行的ORM框架(基于JPA)
- 1.Hibernate
- 2.Spring Data JPA
一、JPA概述
1.JPA概念
JPA(Java Persistence API)是用于对象持久化的API,是Java EE平台标准的ORM规范
,使得应用程序以统一的方式访问持久层。
ORM:
- Object Relational Mapping
- Java对象与关系数据库之间的映射
JPA:
- 通过JDK注解或XML描述对象-关系的映射关系
- 并将运行期的实体对象持久化到数据库中
- Sun希望整合ORM技术,统一各种ORM框架的规范,实现天下归一:JPA提供了现有ORM实现框架功能的核心子集
JPA包含三方面的技术
- ORM映射元数据:JPA支持XML和JDK注解两种元数据的形式,元数据描述对象和表之间对的映射关系,框架据此将实体对象持久化到数据库表中
- JPA的API:用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。
- 查询语言JPQL:这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
2.实体
一个实体是一个轻量级的持久化对象。
- 通常一个实体表示关系数据库中的一张表
- 实体的每个实例对应表中的一行
假设有一个表名为 user
,包含以下字段:
Field | Type |
---|---|
id | INT |
name | VARCHAR(100) |
age | INT |
VARCHAR(100) | |
password | VARCHAR(100) |
我们使用JPA定义一个实体类 User
,对应 user
表中的一条记录:
@Entity
@Table(name = "user")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;private String name;private Integer age;private String email;private String password;// getters and setters
}
在上述代码中,我们使用 @Entity
注解表示这是一个实体类,使用 @Table
注解指定了实体对应的表名为 user
。同时,我们在类中定义了实体对应的属性,并使用 @Id
和 @GeneratedValue
注解表示该属性为实体的唯一标识,并指定了该属性的生成策略为自增长。
实体的状态:
- 新建态new(自由状态):新创建的实体对象,尚未拥有持久化主键,没有和一个持久化上下文关联起来
- 受控态managed(持久状态):已经拥有持久化主键并和持久化上下文建立了联系
- 游离态detached(分离状态):拥有持久化主键,但尚未和持久化上下文建立联
- 删除态removed(删除状态):拥有持久化主键,已经和持久化上下文建立联系系,但已经被安排从数据 库中删除
3.ORM注解
基本注解
@Entity 将对象标注为一个实体,表示需要保存到数据库中
@Table 默认情况下类名即为表名,通过name属性显式指定表名
@Id 对应的属性是表的主键
@GeneratedValue 主键的产生策略,通过strategy属性指定
@EmbeddedId或@IdClass 组合关键字
@Column 属性对应的表字段
@Transient 表示对应属性不需要持久化。在保存或更新实体对象时,该属性不会持 久化到数据库中
关联关系
@OneToOne
@OneToMany
@ManyToOne
@ManyToMany
下面是使用 JPA 实现一对一、一对多、多对一和多对多关系的示例。
一对一关系
在 JPA 中,一对一关系通常使用 @OneToOne 注解来表示。例如,一个 Person 实体可以拥有一个 Passport 实体,如下所示:
@Entity
public class Person {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;private String name;@OneToOne(mappedBy = "person")private Passport passport;// getters and setters
}@Entity
public class Passport {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;private String number;@OneToOne@JoinColumn(name = "person_id")private Person person;// getters and setters
}
上述示例中,Person 实体与 Passport 实体之间建立了一对一的关系,Person 实体拥有一个 Passport 实体,而 Passport 实体则有一个对应的 Person 实体。在 Person 实体中,使用 mappedBy 属性指定了关系的维护方是 Passport 实体,即 Passport 实体维护了这个关系。在 Passport 实体中,使用 @JoinColumn 注解指定了外键列的名称,即 person_id。
一对多关系
在 JPA 中,一对多关系通常使用 @OneToMany 注解来表示。例如,一个 Department 实体可以拥有多个 Employee 实体,如下所示:
@Entity
public class Department {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;private String name;@OneToMany(mappedBy = "department")private List<Employee> employees;// getters and setters
}@Entity
public class Employee {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;private String name;@ManyToOne@JoinColumn(name = "department_id")private Department department;// getters and setters
}
上述示例中,Department 实体与 Employee 实体之间建立了一对多的关系,Department 实体拥有多个 Employee 实体,而每个 Employee 实体都对应一个 Department 实体。在 Department 实体中,使用 mappedBy 属性指定了关系的维护方是 Employee 实体,即 Employee 实体维护了这个关系。在 Employee 实体中,使用 @ManyToOne 注解指定了关联的 Department 实体,同时使用 @JoinColumn 注解指定了外键列的名称,即 department_id。
多对一关系
在 JPA 中,多对一关系与一对多关系相反,通常使用 @ManyToOne 注解来表示。例如,一个 Employee 实体可以属于一个 Department 实体,如下所示:
@Entity
public class Department {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;private String name;// getters and setters
多对多关系
在 JPA 中,多对多关系通常使用 @ManyToMany 注解来表示。例如,一个 Student 实体可以选修多个 Course 实体,而每个 Course 实体也可以被多个 Student 实体选修,如下所示:
@Entity
public class Student {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;private String name;@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})@JoinTable(name = "student_course",joinColumns = @JoinColumn(name = "student_id"),inverseJoinColumns = @JoinColumn(name = "course_id"))private List<Course> courses;// getters and setters
}@Entity
public class Course {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;private String name;@ManyToMany(mappedBy = "courses")private List<Student> students;// getters and setters
}
上述示例中,Student 实体与 Course 实体之间建立了多对多的关系,一个 Student 实体可以选修多个 Course 实体,而每个 Course 实体也可以被多个 Student 实体选修。在 Student 实体中,使用 @ManyToMany 注解指定了与 Course 实体的关系,并在 JoinTable 注解中指定了关联表的名称,以及关联 Student 实体的主键和 Course 实体的主键。在 Course 实体中,使用 mappedBy 属性指定了关系的维护方是 Student 实体,即 Student 实体维护了这个关系。
需要注意的是,为了避免出现重复的数据,通常使用 CascadeType.PERSIST 和 CascadeType.MERGE 级联操作来保存关联的实体。同时,由于 JoinTable 中的主键是由 Student 实体和 Course 实体组合而成的复合主键,所以需要在 Student 和 Course 实体中实现 equals 和 hashCode 方法,以确保比较两个实体对象时正确性。
4.JPQL
Java Persistence Query Language(Java持久化查询语言)
- 是一种可移植的查询语言,可以被编译成所有主流数据库服务器 上的SQL
- JPQL是面向对象的,通过面向对象而非面向数据库的查询语言查 询数据,在Java空间对类和对象进行操作,避免程序的SQL语句 紧密耦合
- 使用 javax.persistence.Query接口代表一个查询实例
二、JPA实战
使用JPA持久化对象步骤
- 创建EntityManagerFactory:创建和销毁都相当耗费资源,通常一个系统内一个数据库仅创建一个。
- 创建EntityManager
- 创建实体类,使用注解来描述实体类跟数据库之间的一一映射关系
- 使用JPA API完成数据增加、删除、修改和查询操作(persisit、remove、merge、find)
假设有一个表名为 user
,包含以下字段:
Field | Type |
---|---|
id | INT |
name | VARCHAR(100) |
age | INT |
VARCHAR(100) | |
password | VARCHAR(100) |
接下来,我们需要使用 JPA 完成实体类及使用 EntityManager
完成增删改查操作。
首先,我们需要定义一个实体类 User
,对应 user
表中的一条记录:
@Entity
@Table(name = "user")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;private String name;private Integer age;private String email;private String password;// getters and setters
}
在上述代码中,我们使用 @Entity
注解表示这是一个实体类,使用 @Table
注解指定了实体对应的表名为 user
。同时,我们在类中定义了实体对应的属性,并使用 @Id
和 @GeneratedValue
注解表示该属性为实体的唯一标识,并指定了该属性的生成策略为自增长。
接下来,我们可以使用 EntityManager
对实体进行增删改查操作。以下是一个示例:
public class UserDao {@PersistenceContextprivate EntityManager entityManager;// 添加用户public void addUser(User user) {entityManager.persist(user);}// 根据 id 查询用户public User getUserById(Integer id) {return entityManager.find(User.class, id);}// 更新用户信息public void updateUser(User user) {entityManager.merge(user);}// 根据 id 删除用户public void deleteUserById(Integer id) {User user = entityManager.find(User.class, id);entityManager.remove(user);}}
在上述代码中,我们使用 @PersistenceContext
注解将 EntityManager
注入到 UserDao
类中。接着,我们定义了几个方法,分别用于添加、查询、更新和删除用户。
在 addUser
方法中,我们使用 EntityManager
的 persist
方法将用户对象保存到数据库中。
在 getUserById
方法中,我们使用 EntityManager
的 find
方法根据用户的唯一标识 id
查询用户信息,并将查询结果返回。
在 updateUser
方法中,我们使用 EntityManager
的 merge
方法将修改后的用户对象保存到数据库中。
在 deleteUserById
方法中,我们使用 EntityManager
的 remove
方法将根据用户的唯一标识 id
查询到的用户对象从数据库中删除。
需要注意的是,为了使用 EntityManager
,我们需要将 JPA 的实现框架(如 Hibernate)配置到项目中,并在 persistence.xml
配置文件中配置数据源等信息。
三、流行的ORM框架(基于JPA)
1.Hibernate
Hibernate是一个流行的ORM(对象关系映射)框架,它提供了一种方便的方式来映射Java对象与关系型数据库表之间的关系。Hibernate是一个开源框架,可以在Java平台上使用,并支持多种关系型数据库。
Hibernate主要功能包括:
- 实体映射:Hibernate通过Java注解或XML文件将Java对象映射到数据库表上,实现了Java对象与关系型数据库的映射。开发人员可以通过简单的配置来实现复杂的对象关系映射。
- 数据库操作:Hibernate提供了一组API,用于执行各种数据库操作,例如插入、更新、删除和查询数据。
- 事务管理:Hibernate支持事务处理,确保所有数据库操作都可以在事务中进行,以保证数据的完整性和一致性。
- 缓存管理:Hibernate提供了一些缓存机制,可以减少数据库访问次数,提高性能。
- 查询语言:Hibernate提供了一种名为HQL(Hibernate Query Language)的查询语言,它允许开发人员以面向对象的方式查询数据库。
除了以上功能,Hibernate还支持诸如延迟加载、级联操作、事件监听、版本控制等高级特性,使得开发人员可以更加灵活地使用Hibernate。Hibernate还有一个称为Hibernate Tools的插件,可以集成到Eclipse等开发工具中,提供一些便捷的工具,帮助开发人员更加高效地使用Hibernate。
Hibernate是一个成熟的ORM框架,在Java开发中得到了广泛应用,也是JPA规范的实现之一。
2.Spring Data JPA
Spring Data JPA是Spring框架中的一个模块,它提供了一种更方便的方式来使用JPA(Java Persistence API)规范。它简化了JPA的使用,并提供了一些便利的功能,如自动生成查询、分页和排序等。使用Spring Data JPA可以减少代码量,提高开发效率。
Spring Data JPA主要功能包括:
- Repository接口:Spring Data JPA提供了一个Repository接口,它包含了一组常用的CRUD(Create, Retrieve, Update, Delete)操作,可以用来访问数据库中的数据。开发人员只需定义一个接口继承Repository接口,就可以直接使用这些操作。
- 自定义查询方法:除了提供常用的CRUD操作外,Spring Data JPA还支持通过方法名来自动生成查询,这样就不需要编写JPQL(Java Persistence Query Language)语句了。例如,如果要根据用户名查询用户信息,可以定义一个名为findByUsername的方法,Spring Data JPA会自动生成查询语句。
- 分页和排序:Spring Data JPA支持分页和排序,开发人员只需要在Repository接口的方法中传入Pageable对象,就可以实现分页和排序功能。
- JPA Criteria查询:Spring Data JPA还支持使用JPA Criteria查询,它可以以面向对象的方式构建动态查询。使用JPA Criteria查询可以提高代码的可维护性和灵活性。
Spring Data JPA是一种非常方便的ORM框架,它可以减少代码量,提高开发效率。它建立在JPA之上,提供了一些便利的功能,使得开发人员可以更加轻松地使用JPA。
相关文章:

【JavaWeb】一文学会JPA
✅✅作者主页:🔗孙不坚1208的博客 🔥🔥精选专栏:🔗JavaWeb从入门到精通(持续更新中) 📋📋 本文摘要:本篇文章主要介绍JPA的概念、注解实现ORM规范…...

【安卓逆向】APK修改与反编译回编译
【安卓逆向】反编译修改APK回编译使用工具流程步骤Apktool相关安装与使用常用命令备查APK签名命令备查实战练习反编译查看修改的地方使用Apktool反编译得到产物文件夹并进行修改回编APK实用场景在日常开发我们可能需要替换某些资源或者修改某些代码,但是我们没有源码…...

【计组笔记04】计算机组成原理之多模块存储器、Cache高速缓存存储器、Cache地址映射
这篇文章,主要介绍计算机组成原理之多模块存储器、Cache高速缓存存储器、Cache地址映射。 目录 一、双口RAM和多模块存储器 1.1、存取周期 1.2、双口RAM 1.3、多模块存储器...

英语基础-状语的应用
1. 非谓语动词作状语 1. 试着翻译下列句子 当他是一个小孩子的时候,他很喜欢玩电脑游戏。 When he was a child, he liked playing computer games. 如果他通过考试,他妈妈就会给他买一台新电脑。 If he passes the examination, his mother will b…...

发表论文需要注意的两点(建议收藏)
在学习人工智能的过程中,论文有着重要的作用,无论是深入学术科研,还是毕业找工作,都离不开发表论文这一步骤,所以今天就和大家分享一些关于论文发表的经验,希望对大家有所帮助。 为什么要早点发表论文&…...

ISTQB-TM-大纲
1. 测试过程 1.1 简介 在 ISTQB 软件测试基础级认证大纲中已描述了基本的测试过程包括以下活动: 计划和控制分析和设计实施和执行评估出口准则和报告测试结束活动 基础级大纲认同这些活动虽然有逻辑顺序,但过程中的某些活动可能重叠,或并行…...

Java SPI 机制详解
在面向对象的设计原则中,一般推荐模块之间基于接口编程,通常情况下调用方模块是不会感知到被调用方模块的内部具体实现。一旦代码里面涉及具体实现类,就违反了开闭原则。如果需要替换一种实现,就需要修改代码。 为了实现在模块装…...

腾讯前端经典react面试题(附答案)
React 性能优化在哪个生命周期?它优化的原理是什么? react的父级组件的render函数重新渲染会引起子组件的render方法的重新渲染。但是,有的时候子组件的接受父组件的数据没有变动。子组件render的执行会影响性能,这时就可以使用s…...

Go语言基础(十五):垃圾回收机制(三色标记)
文章目录一、标记清除(三色标记)大致原理1、标记细节2、root对象二、垃圾回收触发机制垃圾回收(Garbage Collection),是一种自动管理内存的机制。传统编程语言(如C/C)需要开发者对无用内存资源进…...

一文了解build.gradle配置
Gradle 参考官方文档:https://developer.android.com/studio/build?hlzh-cn#groovy settings.gradle 存放于项目根目录下,此设置文件会定义项目级代码库设置,并告知 Gradle 在构建应用时应将哪些模块包含在内 接下来将以一个简单的 settin…...

【Redis 高级】- 持久化 - RDB
【Redis 高级】- 持久化 - RDB 👑什么是持久化呢? 那当然是够持久呀,这个持久如果在你不主动去删除的情况下,它就一直存在的。 🎷那么这有什么用呢? 举个栗子:我们在用 PowerPoint 在写价值 …...

SpringSecurity的安全认证的详解说明(附完整代码)
SpringSecurity登录认证和请求过滤器以及安全配置详解说明 环境 系统环境:win10 Maven环境:apache-maven-3.8.6 JDK版本:1.8 SpringBoot版本:2.7.8 根据用户名密码登录 根据用户名和密码登录,登录成功后返回Token数据…...

详解制造业业务数据模型
业务数据在企业数字化转型或单体应用的开发中都是至关重要的。站在跨业务跨部门的企业数字化转型角度,离不开业务架构的设计,详细的业务领域和业务数据模型是后续应用架构和数据架构的必要输入。站在单部门单场景的信息化角度,应用程序的需求…...

BigDecimal使用注意避坑
目录一. BigDecimal的初始化精度丢失问题二. BigDecimal在进行除法运算时需设置精度,否则对于除不尽的情况会抛出异常三. 不要使用BigDecimal的equals方法比较大小, 否则可能会因为精度问题导致比较结果和预期的不一致在java.math包中提供了对大数字的操作类,用于进…...

windows环境下,vue启动项目后打开chrome浏览器
前言:关于vue启动后打开chrome浏览器,我查了很多资料,方案如下: 1、增加环境变量BROWSER为chrome(试了没效果) 2、设置系统的默认浏览器为chrome(应该可以,但没试;因为…...
SpringBoot2.X整合ClickHouse项目实战-从零搭建整合(三)
一、ClickHouseSpringBoot2.XMybatisPlus整合搭建 二、需求描述和数据库准备 三、ClickHouse统计SQL编写实战和函数使用 四、ClickHouseSpringBoot2.X案例-基础模块搭建 controller/request层 mapper层 model层 service层 五、ClickHouseSpringBoot2.X案例-数据统计接口 …...

学海记录项目测试报告
⭐️前言⭐️ 本篇文章是博主基于学海记录的个人项目所做的测试报告,用于总结运用自动化测试技术,应用于自己的项目。 🍉欢迎点赞 👍 收藏 ⭐留言评论 📝私信必回哟😁 🍉博主将持续更新学习记录…...

【1792. 最大平均通过率】
来源:力扣(LeetCode) 描述: 一所学校里有一些班级,每个班级里有一些学生,现在每个班都会进行一场期末考试。给你一个二维数组 classes ,其中 classes[i] [passi, totali] ,表示你…...

言简意赅+图解 函数传参问题(传值、传地址 500字解决战斗)
1、传值 2、传地址 不论是传值,还是传地址,形参都是对于实参的一份拷贝 下图为按值传递进行交换: 形参left拷贝一块新空间,形参right拷贝一块新空间 下图为按指针传递进行交换 形参left拷贝一块新的空间,形参right…...

UML-时序图以及PlantUML绘制
介绍 时序图(Sequence Diagram),又名序列图、循序图,是一种UML交互图。它通过描述对象之间发送消息的时间顺序显示多个对象之间的动态协作。它可以表示用例的行为顺序,当执行一个用例行为时,其中的每条消息…...

【Redis】Redis 有序集合 Zset 操作 ( 简介 | 查询操作 | 增加操作 | 删除操作 | 修改操作 )
文章目录一、有序集合 Zset二、查询操作1、查询 Zset 所有数据2、查询 Zset 所有数据和评分3、查询指定评分范围的 Zset 数据4、查询指定评分范围的 Zset 数据并从大到小排序5、统计指定评分范围的 Zset 数据个数6、查询指定元素在 Zset 有序集合中的排名三、增加操作1、向 Red…...

Java特性之设计模式【策略模式】
一、策略模式 概述 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略…...

IR-CUT 保证摄像机成像效果的滤镜
IR-CUT双滤镜是指在摄像头镜头组里内置了一组滤镜,当镜头外的红外感应点侦测到光线的强弱变化后,内置的IR-CUT自动切换滤镜能够根据外部光线的强弱随之自动切换,使图像达到最 佳效果。也就是说,在白天或黑夜下,双滤光片…...

openpnp - 普通航空插头和PCB的连接要使用线对板连接器
文章目录openpnp - 普通航空插头和PCB的连接要使用线对板连接器概述改进实际效果总结ENDopenpnp - 普通航空插头和PCB的连接要使用线对板连接器 概述 和同学讨论问题, 准备将航空插头连接到PCB上. 航空插头选用GX12-4公头, 拧到开孔的铁板上. 然后航空插头公头再与PCB连接. 铁…...

Python3 错误和异常实例及演示
作为 Python 初学者,在刚学习 Python 编程时,经常会看到一些报错信息,在前面我们没有提及,这章节我们会专门介绍。 Python 有2种错误很容易辨认:语法错误和异常。 Python assert(断言)用于判断…...

Android 9.0第三方app根据包名设置为横屏显示
1.概述 在android9.0的系统rom定制化开发中,在某些横屏的设备比如平板电脑,tv智能电视,广告机等等设备中,通常系统是默认横批显示的,但是在安装一些竖屏app的时候, 就会旋转为竖屏,这个时候操作app也不方便,所以产品需求要求竖屏也需要根据包名横屏显示出来,这就需要在…...

MySQL会导致索引失效的情况与解决索引失效的方法
什么情况会导致索引失效 索引失效也是慢查询的主要原因之一,常见的导致索引失效的情况有下面这些: 1.使用 SELECT * 进行查询;2.创建了组合索引,但查询条件未准守最左匹配原则;3.在索引列上进行计算、函数、类型转换等操作;4.以 % 开头的 L…...

使用nginx单独部署Vben应用
前言 本文主要介绍Vben使用nginx单独部署的方式,其实前端发展到现在已经不是当年的jsp,asp必须要和后端一起部署了。单独部署调试的工具也很多,比如vue-cli-service 和 Vben中用到的vite ,当然这些我们一般用在开发的工程中。正式…...

ES6新特性详解
文章目录1. let和const1.1 let声明变量1.2 const声明常量2. 模板字符串3. 解构赋值3.1 数组的解构赋值3.2 对象的解构赋值4. 函数扩展4.1 参数默认值4.2 剩余参数4.3 箭头函数5. 对象扩展5.1 对象简写5.2 属性名表达式5.3 扩展运算符6. Symbol7. Iterator和Generator7.1 Iterat…...

Ubuntu下安装 ntfs-3g
目录1.FAT32、NTFS和exFAT2.ubuntu 安装 ntfs-3g2.1 直接安装2.2 源码安装1.FAT32、NTFS和exFAT U盘在格式化的时候都会有三种格式分别是FAT32、NTFS和exFAT。 FAT32格式 FAT32格式硬盘分区的最大容量为2TB,虽然U盘做不到,但是现在1xTB硬盘都有了&…...