【JavaWeb】一文学会JPA

news2024/11/15 19:33:48

在这里插入图片描述

✅✅作者主页:🔗孙不坚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,包含以下字段:

FieldType
idINT
nameVARCHAR(100)
ageINT
emailVARCHAR(100)
passwordVARCHAR(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,包含以下字段:

FieldType
idINT
nameVARCHAR(100)
ageINT
emailVARCHAR(100)
passwordVARCHAR(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 {

    @PersistenceContext
    private 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 方法中,我们使用 EntityManagerpersist 方法将用户对象保存到数据库中。

getUserById 方法中,我们使用 EntityManagerfind 方法根据用户的唯一标识 id 查询用户信息,并将查询结果返回。

updateUser 方法中,我们使用 EntityManagermerge 方法将修改后的用户对象保存到数据库中。

deleteUserById 方法中,我们使用 EntityManagerremove 方法将根据用户的唯一标识 id 查询到的用户对象从数据库中删除。

需要注意的是,为了使用 EntityManager,我们需要将 JPA 的实现框架(如 Hibernate)配置到项目中,并在 persistence.xml 配置文件中配置数据源等信息。

三、流行的ORM框架(基于JPA)

1.Hibernate

Hibernate是一个流行的ORM(对象关系映射)框架,它提供了一种方便的方式来映射Java对象与关系型数据库表之间的关系。Hibernate是一个开源框架,可以在Java平台上使用,并支持多种关系型数据库。

Hibernate主要功能包括:

  1. 实体映射:Hibernate通过Java注解或XML文件将Java对象映射到数据库表上,实现了Java对象与关系型数据库的映射。开发人员可以通过简单的配置来实现复杂的对象关系映射。
  2. 数据库操作:Hibernate提供了一组API,用于执行各种数据库操作,例如插入、更新、删除和查询数据。
  3. 事务管理:Hibernate支持事务处理,确保所有数据库操作都可以在事务中进行,以保证数据的完整性和一致性。
  4. 缓存管理:Hibernate提供了一些缓存机制,可以减少数据库访问次数,提高性能。
  5. 查询语言: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主要功能包括:

  1. Repository接口:Spring Data JPA提供了一个Repository接口,它包含了一组常用的CRUD(Create, Retrieve, Update, Delete)操作,可以用来访问数据库中的数据。开发人员只需定义一个接口继承Repository接口,就可以直接使用这些操作。
  2. 自定义查询方法:除了提供常用的CRUD操作外,Spring Data JPA还支持通过方法名来自动生成查询,这样就不需要编写JPQL(Java Persistence Query Language)语句了。例如,如果要根据用户名查询用户信息,可以定义一个名为findByUsername的方法,Spring Data JPA会自动生成查询语句。
  3. 分页和排序:Spring Data JPA支持分页和排序,开发人员只需要在Repository接口的方法中传入Pageable对象,就可以实现分页和排序功能。
  4. JPA Criteria查询:Spring Data JPA还支持使用JPA Criteria查询,它可以以面向对象的方式构建动态查询。使用JPA Criteria查询可以提高代码的可维护性和灵活性。

Spring Data JPA是一种非常方便的ORM框架,它可以减少代码量,提高开发效率。它建立在JPA之上,提供了一些便利的功能,使得开发人员可以更加轻松地使用JPA。

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

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

相关文章

微信小程序学习第11天——Vant Weapp组件库、API Promise化、全局数据共享Mobx、分包

目录一、小程序对npm 的限制二、使用Vant Weapp组件库1、安装组件2、使用组件3、定制全局样式三、API Promise化1、下载miniprogram-api-promise2、引入3、使用四、全局数据共享五、分包1、分包概念2、使用分包3、独立分包4、分包预下载一、小程序对npm 的限制 在小程序中使用…

数值方法笔记2:解决非线性方程

1. 不动点定理及其条件验证2. 收敛阶、收敛检测与收敛加速2.1 如何估计不动点迭代的收敛阶xk1g(xk){x}_{{k}1}{g}\left({x}_{{k}}\right)xk1​g(xk​)2.2 给定精度的情况下&#xff0c;如何预测不动点迭代需要迭代的次数2.3 如何加快收敛的速度2.4 停止不定点迭代的条件2.5 不动…

基于Transformer的NLP处理管线

HuggingFace transformers 是一个整合了跨语言、视觉、音频和多模式模态与最先进的预训练模型并且提供用户友好的 API 的AI开发库。 它由 170 多个预训练模型组成&#xff0c;支持 PyTorch、TensorFlow 和 JAX 等框架&#xff0c;能够在代码之间进行互操作。 这个库还易于部署&…

【Leedcode】数据结构中链表必备的面试题(第一期)

链表必备的面试题 &#xff08;附图解和源码&#xff09;&#xff08;第一期&#xff09; 文章目录链表必备的面试题 &#xff08;附图解和源码&#xff09;&#xff08;第一期&#xff09;一、第一题1.题目2.思路图解&#xff08;1&#xff09;pos是首链表&#xff08;2&#…

基于SpringBoot+Vue的鲜花商场管理系统

【辰兮要努力】&#xff1a;hello你好我是辰兮&#xff0c;很高兴你能来阅读&#xff0c;昵称是希望自己能不断精进&#xff0c;向着优秀程序员前行&#xff01; 博客来源于项目以及编程中遇到的问题总结&#xff0c;偶尔会有读书分享&#xff0c;我会陆续更新Java前端、后台、…

【Vue3源码】第三章 readonly详解 从零实现Vue3 readonly API

【Vue3源码】第三章 readonly详解 从零实现Vue3 readonly API 前言 上一章节我们实现了effect函数的stop和onstop功能&#xff0c;至此effect函数源码的编写就暂时告一段落了&#xff0c;这一章我们继续解读Vue3源码&#xff0c;开始实现Vue3 Reactivity &#xff1a;core 中…

Java基础361问14问——为什么非静态内部类会默认持有外部类的引用?

在内存泄露问题排查中最常遇到就是 【非静态内部类默认持有外部类的引用】 文章目录1 字节码分析javac Activity.javajavap -c Activity.class2 静态内部类会持有外部类引用吗?参考文档// 简化处理相关代码 public class Activity {private Handler inner new Handler();priv…

C++面向对象(中)

文章目录前言1.类的6个默认成员函数介绍2.构造函数3.析构函数1.概念2.析构函数特征4.拷贝构造1.概念2.拷贝构造函数特征3.注意事项5.赋值运算符重载1.概念6.补充知识const成员函数7.取地址运算符和const取地址运算符重载8.总结前言 本文主要介绍C中的六个天选之子&#xff0c;…

MicroBlaze系列教程(6):AXI_IIC的使用

文章目录 @[toc]AXI_IIC简介MicroBlaze硬件配置常用函数使用示例波形实测参考资料工程下载本文是Xilinx MicroBlaze系列教程的第6篇文章。 AXI_IIC简介 一般情况下,使用FPGA实现I2C协议主要有两种方式:一种是基于Verilog实现起始位、停止位、ACK产生和判断、数据的发送和接收…

程终止、进程睡眠、进程对信号处理过程中等的方法

上一章学习了调度的方式&#xff0c;分为主调度器和周期性调度器&#xff0c;明白了进程切换分为自愿(voluntary)和强制(involuntary)两种。 自愿切换&#xff1a; 是指任务由于等待某种资源&#xff0c;将state改为非running状态后&#xff0c;主动调用schedule让出CPU 任务…

html中元素居中的五种方法

在网页开发中&#xff0c;经常会有嵌套元素中将子元素居中的要求。下边将五种常用的居中方法进行总结。 1&#xff1a;原始图&#xff08;父子元素无border&#xff0c;无padding&#xff09;&#xff1a; 2&#xff1a;实现居中效果&#xff1a; 一&#xff1a;使用margin…

一篇文章带你学会Anisble中的如何处理失败任务

目录 一、循环 1、简单循环 2、循环散列或字典列表 3、练习 二、条件 三、触发器 四、处理失败任务 1、ignore_errors 2、force_handlers 3、changed_when 4、failed_when 5、block 练习 一、循环 作用&#xff1a;循环迭代任务 1、简单循环 loop: ##赋值列表 -…

[软件工程导论(第六版)]第4章 形式化说明技术(复习笔记)

文章目录4.1 概述4.2 有穷状态机4.3 Petri网4.4 Z语言按照形式化程度&#xff0c;可以把软件工程使用的方法划分成非形式化、半形式化、形式化三类非形式化方法&#xff1a;使用自然语言描述需求规格说明半形式化方法&#xff1a;使用数据流图或实体-联系图建立模型形式化方法&…

P2P视频聊天技术分析

整个P2P视频过程需要知道双方的媒体类型、流和候选者&#xff0c;所以这里就会用到一下技术&#xff1a; ​ 信令服务器socket.io ​ 状态机 ​ ICE服务器 ​ WebRTC框架 ​ 媒体协商 信令服务器Socket.io 信令服务器说白了作用就是发消息的中转站&#xff0c;A把msg发到…

网络流与图(二)

上一节我们讲到了退化圈方向搜索算法&#xff0c;它能得到全局最优解。然而算法运行过程中需要选择一个可行改进圈方向&#xff0c;对于一个大型网络流来说&#xff0c;这并非容易的。我们需要找到在每次循环中确认可行改进圈方向或者证明不存在的方法。我们现在就来探讨这个问…

Andriod入门级开发

这学期有个课设&#xff0c;我们组我负责一个手机APP的开发&#xff0c;虽然刚开始说要实现什么智能导航&#xff0c;类似高德地图那种&#xff0c;但最后阉割的只剩一个Socket通信了&#xff0c;因为之前没有接触过&#xff08;可能之后也不会再接触&#xff09;&#xff0c;记…

【数据管理】谈谈哈希原理和散列表

一、说明 提起哈希&#xff0c;有人要说&#xff1a;不就是一个稀疏表格么&#xff0c;谈的上什么原理&#xff1f;我说&#xff1a;非也&#xff0c;哈希是是那种看似无物&#xff0c;其实解决大问题的东西。如何提高数据管理效率&#xff1f;这是个问题&#xff0c;随着这个问…

测试2:编写测试用例的方法

2.编写测试用例的方法 7种 测试常用的方法&#xff1a;code review 代码静态分析、CI/CD CI–持续集成–开发成员经常集成它们的工作&#xff0c;尽快发现集成错误 CD–持续部署–将集成后的代码部署到更贴近真实运行的环境 2.1 测试用例的描述&#xff1a; 用例编号 用例…

Python纯Numpy手撕SGD

文章目录简介问题建模数据加载和预处理数据加载预处理分batch损失函数训练运行简介 本博客用多元线性回归展示如何从零实现一个随机梯度下降SGD, 不使用torch等AI框架 问题建模 给定一个数据集X∈RN(D1)\large X \in \R^{N \times (D1)}X∈RN(D1)和对应标签向量Y∈RN\large …

centos7防火墙工具firewall-cmd使用

centos7防火墙工具firewall-cmd使用防火墙概述centos7防火墙工具firewall-cmd使用介绍firewalld的基本使用服务管理工具相关指令配置firewalld-cmd防火墙概述 防火墙是可以帮助计算机在内部网络和外部网络之间构建一道相对隔绝的保护屏障&#xff0c;从而保护数据信息的一种技…