【Spring Boot】Java 持久层 API:JPA

news2024/11/20 8:43:02

Java 持久层 API:JPA

  • 1.Spring Data
    • 1.1 主要模块
    • 1.2 社区模块
  • 2.JPA
  • 3.使用 JPA
    • 3.1 添加 JPA 和 MySQL 数据库的依赖
    • 3.2 配置数据库连接信息
  • 4.了解 JPA 注解和属性
    • 4.1 常用注解
    • 4.2 映射关系的注解
    • 4.3 映射关系的属性
  • 5.用 JPA 构建实体数据表

1.Spring Data

Spring Data 是 Spring 的一个子项目,旨在统一和简化各类型数据的持久化存储方式,而不拘泥于是关系型数据库还是 NoSQL 数据库。

无论是哪种持久化存储方式,数据访问对象Data Access ObjectsDAO)都会提供对对象的增加、删除、修改和查询的方法,以及排序和分页方法等。

Spring Data 提供了基于这些层面的统一接口(如:CrudRepository、PagingAndSortingRepository),以实现持久化的存储。

Spring Data 包含多个子模块,主要分为主模块和社区模块。

1.1 主要模块

模块名称
作用
Spring Data Commons提供共享的基础框架,适合各个子项目使用,支持跨数据库持久化。
Spring Data JDBC提供了对 JDBC 的支持,其中封装了 JDBCTemplate。
Spring Data JDBC Ext提供了对 JDBC 的支持,并扩展了标准的 JDBC,支持 Oracle RAD、高级队列和高级数据类型。
Spring Data JPA简化创建 JPA 数据访问层和跨存储的持久层功能。
Spring Data KeyValue集成了 Redis 和 Riak,提供多个常用场景下的简单封装,便于构建 key-value 模块。
Spring Data LDAP集成了 Spring Data repository 对 Spring LDAP 的支持。
Spring Data MongoDB集成了对数据库 MongoDB 支持。
Spring Data Redis集成了对 Redis 的支持。
Spring Data REST集成了对 RESTful 资源的支持。
Spring Data for Apache Cassandra集成了对大规模、高可用数据源 Apache Cassandra 的支持。
Spring Data for Apace Geode集成了对 Apache Geode 的支持。
Spring Data for Apache Solr集成了对 Apache Solr 的支持。
Spring Data for Pivotal GemFire集成了对 Pivotal GemFire 的支持。

1.2 社区模块

模块名称
作用
Spring Data Aerospike集成了对 Aerospike 的支持
Spring Data ArangoDB集成了对 ArangoDB 的支持。
Spring Data Couchbase集成了对 Couchbase 的支持。
Spring Data Azure Cosmos DB集成了对 Azure Cosmos 的支持。
Spring Data Cloud Datastore集成了对 Google Datastore 的支持
Spring Data Cloud Spanner集成了对 Google Spanner 的支持。
Spring Data DynamoDB集成了对 DynamoDB 的支持。
Spring Data Elasticsearch集成了对搜索引擎框架 Elasticsearch 的支持。
Spring Data Hazelcast集成了对 Hazelcast 的支持。
Spring Data Jest集成了对基于 Jest REST client 的 Elasticsearch 的支持。
Spring Data Neo4j集成了对 Neo4j 数据库的支持。
Spring Data Vault集成了对 Vault 的支持。

2.JPA

JPA(Java Persistence APl)是 Java 的持久化 API,用于对象的持久化。它是一个非常强大的 ORM 持久化的解决方案,免去了使用 JDBCTemplate 开发的编写脚本工作。JPA 通过简单约定好接口方法的规则自动生成相应的 JPQL 语句,然后映射成 POJO 对象。

JPA 是一个规范化接口,封装了 Hibernate 的操作作为默认实现,让用户不通过任何配置即可完成数据库的操作。JPA、Spring Data 和 Hibernate 的关系如下图所示。
在这里插入图片描述
Hibernate 主要通过 hibernate-annotationhibernate-entitymanagerhibernate-core 三个组件来操作数据。

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

如果要 JPA 创建《Java 的数据库连接模板:JDBCTemplate》中 “2.2 新建实体类” 里的实体,可使用以下代码来实现。

@Data
@Entity
public class User {
	private int id;
	@Id
	// id 的自增由数据库自动管理
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private String username;
	private String password;
}

对比 JPA 与 JDBCTemplate 创建实体的方式可以看出:JPA 的实现方式简单明了,不需要写映射(支持自定义映射),只需要设置好属性即可。id 的自增由数据库自动管理,也可以由程序管理,其他的工作 JPA 自动处理好了。

3.使用 JPA

要使用 JPA,只要加入它的 Starter 依赖,然后配置数据库连接信息。

3.1 添加 JPA 和 MySQL 数据库的依赖

下面以配置 JPA 和 MySQL 数据库的依赖为例,具体配置见以下代码:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>

3.2 配置数据库连接信息

Spring Boot 项目使用 MySQL 等关系型数据库,需要配置连接信息,可以在 application.properties 文件中进行配置。以下代码配置了与 MySQL 数据库的连接信息:

spring.datasource.url=jdbc:mysql://127.0.0.1/book?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql= true
  • spring.datasource.username:要填写的数据库用户名。
  • spring.datasource.password:要填写的数据库密码。
  • spring.jpa.show-sql:开发工具的控制台是否显示 SQL语句,建议打开。
  • spring.jpa.properties.hibernate.hbm2ddl.auto:hibernate 的配置属性,其主要作用是自动创建、更新、验证数据库表结构。该参数的几种配置如下表所示。
属性
说明
create每次加载 Hibernate 时都会删除上一次生成的表,然后根据 Model 类再重新生成新表,哪怕没有任何改变也会这样执行,这会导致数据库数据的丢失。
create-drop每次加载 Hibernate 时会根据 Model 类生成表,但是 sessionFactory 一旦关闭,表就会自动被删除。
update最常用的属性。第一次加载 Hibernate 时会根据 Model 类自动建立表的结构(前提是先建立好数据库)。以后加载 Hibernate 时,会根据 Model 类自动更新表结构,即使表结构改变了,但表中的数据仍然存在,不会被删除。要注意的是,当部署到服务器后,表结构是不会被马上建立起来的,要等应用程序第一次运行起来后才会建立。Update 表示如果 Entity 实体的字段发生了变化,那么直接在数据库中进行更新。
validate每次加载 Hibernate 时,会验证数据库的表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。

4.了解 JPA 注解和属性

4.1 常用注解

注解
说明
@Entity声明类为实体
@Table声明表名,@Entity 和 @Table 注解一般一块使用,如果表名和实体类名相同,那么 @Table 可以省略
@Basic指定非约束明确的各个字段
@Embedded用于注释属性,表示该属性的类是嵌入类(@embeddable 用于注释 Java 类的,表示类是嵌入类)
@Id指定的类的属性,一个表中的主键
@GeneratedValue指定如何标识属性可以被初始化,如 @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="repair_seq"),表示主键生成策略是 sequence,还有 Auto、Identity、Native 等
@Transient表示该属性并非一个数据库表的字段的映射,ORM 框架将忽略该属性。如果一个属性并非数据库表的字段映射,就务必将其标示为 @Transient,即它是不持久的,为虚拟字段
@Column指定持久属性,即字段名。如果字段名与列名相同,则可以省略。使用方法,如 @Column(length=11, name="phone", nullable=false, columnDefinition="varchar(11) unique comment '电话号码'")
@SequenceGenerator指定在 @GeneratedValue 注解中指定的属性的值。它创建一个序列
@TableGenerator在数据库生成一张表来管理主键生成策略
@AccessType这种类型的注释用于设置访问类型。如果设置 @AccessType(FIELD),则可以直接访问变量,并且不需要使用 Getter 和 Setter 方法,但必须为 public 属性。如果设置 @AccessType(PROPERTY),则通过 Getter 和 Setter 方法访问 Entity 的变量
@UniqueConstraint指定的字段和用于主要或辅助表的唯一约束
@ColumnResult可以参考使用 select 子句的 SQL 查询中的列名
@NamedQueries指定命名查询的列表
@NamedQuery指定使用静态名称的查询
@Basic指定实体属性的加载方式,如 @Basic(fetch=FetchType.LAZY)
@Jsonignore作用是 JSON 序列化时将 Java Bean 中的一些属性忽略掉,序列化和反序列化都受影响

4.2 映射关系的注解

注解
说明
@JoinColumn指定一个实体组织或实体集合。用在 多对一一对多 的关联中
@OneToOne定义表之间 一对一 的关系
@OneToMany定义表之间 一对多 的关系
@ManyToOne定义表之间 多对一 的关系
@ManyToMany定义表之间 多对多 的关系

4.3 映射关系的属性

属性名
说明
targetEntity表示默认关联的实体类型,默认为当前标注的实体类。
cascade表示与此实体一对一关联的实体的级联样式类型,以及当对实体进行操作时的策略。在定义关系时经常会涉及是否定义 Cascade(级联处理)属性,如果担心级联处理容易造成负面影响,则可以不定义。它的类型包括 CascadeType.PERSIST(级联新建)、CascadeType.REMOVE(级联删除)、CascadeType.REFRESH(级联刷新)、CascadeType.MERGE(级联更新)、CascadeType.ALL(级联新建、更新、删除、刷新)。
fetch该实体的加载方式,包含 LAZY 和 EAGER。
optional表示关联的实体是否能够存在 null 值。默认为 true,表示可以存在 null 值。如果为 false,则要同时配合使用 @JoinColumn 标记。
mappedBy双向关联实体时使用,标注在不保存关系的实体中。
JoinColumn关联指定列。该属性值可接收多个 @JoinColumn。用于配置连接表中外键列的信息。@JoinColumn 配置的外键列参照当前实体对应表的主键列。
JoinTable两张表通过中间的关联表建立联系时使用,即多对多关系。
PrimaryKeyJoinColumn主键关联。在关联的两个实体中直接使用注解 @PrimaryKeyJoinColumn 注释。

懒加载 LAZY 和实时加载 EAGER 的目的是,实现关联数据的选择性加载。

  • 懒加载 是一种延迟加载策略,即在真正需要访问对象的属性时,才从数据库中加载数据。当 Hibernate 在查询数据库时遇到关联对象(如一对多、多对一、多对多等关系),并不会立即加载关联对象的数据,而只会加载主键 ID。只有当程序真正需要访问关联对象的属性时,Hibernate 才会发出 SQL 语句去加载数据。这种策略的优点在于,如果程序并不需要访问关联对象的所有属性,那么就可以节省数据库访问的开销,提高程序性能。但是,如果在使用懒加载的对象后关闭了 Session,那么在访问其关联对象的属性时,就会抛出 LazyInitializationException 异常,因为 Hibernate 需要在 Session 的作用范围内才能发出 SQL 语句加载数据。
  • 实时加载 是一种积极加载策略,即在加载一个对象时,会立即加载与其关联的所有对象。当 Hibernate 在查询数据库时遇到关联对象,会立即发出 SQL 语句加载关联对象的数据,并将其全部加载到内存中。这种策略的优点在于,程序可以随时访问关联对象的属性,而无需担心 Session 是否已经关闭。但是,如果关联对象的数据量很大,那么就会消耗大量的内存,并可能导致性能下降。

在 Spring Data JPA 中,要控制 Session 的生命周期,否则会出现 could not initialize proxy [xxxx#18] - no Session 错误。可以在配置文件中配置以下代码来控制 Session 的生命周期:

spring.jpa.open-in-view=true
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true

5.用 JPA 构建实体数据表

下面通过实例来体验如何通过 JPA 构建对象/关系映射的实体模型。

package com.example.demo.entity;

import lombok.Data;

import javax.persistence.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;

@Entity
@Data
public class Article implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(nullable = false, unique = true)
    @NotEmpty(message = "标题不能为空")
    private String title;

    @Column(columnDefinition = "enum('图','图文','文')")
    private String type;

    private Boolean available = Boolean.FALSE;
    @Size(min = 0, max = 20)
    private String keyword;
    @Size(max = 255)
    private String description;
    @Column(nullable = false)
    private String body;

    @Transient
    private List keywordlists;

    public List getKeywordlists() {
        return Arrays.asList(this.keyword.trim().split("|"));
    }

    public void setKeywordlists(List keywordlists) {
        this.keywordlists = keywordlists;
    }
}

如果想创建虚拟字段,则通过在属性上加注解 @Transient 来解决。

运行项目后会自动生成数据表。完成后的数据表如下图所示。

在这里插入图片描述

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

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

相关文章

【Linux】多线程(一万六千字)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 文章目录 前言 线程的概念 线程的理解(Linux系统为例) 在Linux系统里如何保证让正文部分的代码可以并发的去跑呢&#xff1f; 为什么要有多进程呢&#xff1f; 为…

统计信号处理基础 习题解答11-13

题目 如果是一个2x1的随机矢量&#xff0c;具有PDF 证明的PDF是一个随机变量。提可以因式分解成&#xff0c;其中是一个在4.5节描述的白化变换。 解答 首先&#xff1a; 因此&#xff0c;存在&#xff1a; 也就是是Hermitian矩阵。详细的性质可以参考&#xff1a; https://z…

linux系统中的各种命令的解释和帮助(含内部命令、外部命令)

目录 一、说明 二、命令详解 1、帮助命令的种类 &#xff08;1&#xff09;help用法 &#xff08;2&#xff09;--help用法 2、如何区别linux内部命令和外部命令 三、help和—help 四、man 命令 1、概述 2、语法和命令格式 &#xff08;1&#xff09;man命令的格式&…

数据库组成及原理

属性&#xff1a; 把数据库中的一个表类比成一个公司&#xff0c;那么公司里的每个人都是一个“属性”&#xff08;表中的一个字段视为一个属性&#xff09;&#xff0c;不管老板还是员工&#xff0c;只要是公司里的人&#xff0c;就都是一个属性。 主键&#xff1a; 老板就是“…

带安全启动—Ubuntu系统—手动安装Nvidia驱动

教程1&#xff1a;在启用安全启动的 Fedora 中安装英伟达驱动 教程2&#xff1a;UEFI安全启动模式下安装Ubuntu的NVIDIA显卡驱动 1. 搜索合适的驱动 Nvidia驱动官网 选择这个 驱动(.run)链接 2. 安装必要的软件依赖 CUDA底层用C写的&#xff0c;因此导入编译器 sudo apt i…

智慧课堂基于YOLOv8的学生上课行为检测

数据集 学生上课行为检测&#xff0c;我们直接使用公开数据集 共三类行为&#xff1a;举手、读书、写字 数据集已经按照YOLO格式配置好&#xff0c;数据内容如下 模型训练 ​ 采用YOLOv8模型进行训练&#xff0c;官方代码 首先是划分数据集&#xff0c;分为训练集、验证&a…

Linux-gdb

目录 1.-g 生成含有debug信息的可执行文件 2.gdb开始以及gdb中的常用执行指令 3.断点的本质用法 4.快速跳出函数体 5.其他 1.-g 生成含有debug信息的可执行文件 2.gdb开始以及gdb中的常用执行指令 3.断点的本质用法 断点的本质是帮助我们缩小出问题的范围 比如&#xff0c;…

今天的A股,让人惊愕了,2个耐人寻味的重要信号,有望迎来下一个超级风口!

今天的A股&#xff0c;让人惊愕了&#xff0c;你知道是为什么吗&#xff1f;盘面上出现2个耐人寻味的重要信号&#xff0c;有望迎来下一个超级风口&#xff01; 1、今天两市低开低走&#xff0c;但大消费劲头十足&#xff0c;连中免这样的大体量都涨停了&#xff0c;另外消费茅…

Linux静态库的制作

Linux操作系统支持的函数库分为&#xff1a; 静态库&#xff0c;libxxx.a&#xff0c;在编译时就将库编译进可执行程序中。 优点&#xff1a;程序的运行环境中不需要外部的函数库。 缺点&#xff1a;可执行程序大 动态库&#xff0c;又称共享库&#xff0c;libxxx.so&a…

探索迁移学习:通过实例深入理解机器学习的强大方法

探索迁移学习&#xff1a;通过实例深入理解机器学习的强大方法 &#x1f341;1. 迁移学习的概念&#x1f341;2. 迁移学习的应用领域&#x1f341;2.1 计算机视觉&#x1f341;2.2 自然语言处理&#xff08;NLP&#xff09;&#x1f341;2.3 医学图像分析&#x1f341;2.4 语音…

上海站圆满结束!MongoDB Developer Day深圳站,周六见!

在过去两个周六的北京和上海 我们见证了两站热情高涨的 MongoDB Developer Day&#xff01; 近200位参会开发者相聚专业盛会 经过全天的动手实操和主题研讨会 MongoDB技能已是Next Level&#xff01; 最后一站Developer Day即将启程 期待本周六与各位在深圳相见&#xff0…

身边的故事(十三):阿文的故事:出现

如果他知道一件事情如果违背正常的市场规律就是骗局或者存在巨大的风险&#xff0c;比如市场正常投资回报率在5-6%已经算高回报&#xff0c;像股神巴菲特的投资回报率应该不会超过10%吧。那些说20-30%甚至更高回报率肯定是骗局。如果...哪有那么多如果&#xff0c;人生每一秒都…

3D一览通优化供应链协同,加速产品设计研发和上市

在现代企业管理中&#xff0c;供应链管理无疑占据着举足轻重的地位。它不仅是企业资源优化配置的基石&#xff0c;更是企业降低成本、提高效率、满足客户需求、保持市场竞争力的关键环节。对于工业企业来说&#xff0c;供应链的高效运作尤其重要。 然而&#xff0c;在实际操作…

使用ps给gif动图抠图

目录 导入gif图片 打开时间轴 选择图片 魔棒抠图-初步抠图 套索抠图-精准抠图 导入gif图片 打开时间轴 因为gif动图实际上多张图片实现的效果&#xff0c;所以如果要给gif抠图&#xff0c;就得挨个给每个时间线的图片抠图 点击窗口->时间轴 选择图片 在时间轴上选择要…

2024 年人工智能和数据科学的五个主要趋势

引言 2023年&#xff0c;人工智能和数据科学登上了新闻头条。生成性人工智能的兴起无疑是这一显著提升曝光度的驱动力。那么&#xff0c;在2024年&#xff0c;该领域将如何继续占据头条&#xff0c;并且这些趋势又将如何影响企业的发展呢&#xff1f; 在过去几个月&#xff0c;…

If you already have a 64-bit JDK installed ,defined a JAVA_HOME...的错误

今天感觉idea有点卡&#xff0c;修改了一下内存&#xff0c;结果就报这个错误了&#xff0c;网上的解决方案好多&#xff0c;都不行 以下是解决方案 打开 C:\Program Files\JetBrains\IntelliJ IDEA 2024.1.4\bin\jetbrains_client64.exe 把jihuo这个目录下所有的文件都删掉&…

[leetcode hot 150]第三题,无重复字符的最长子串

题目&#xff1a; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串的长度。 可以使用"滑动窗口"的方法来解决这个问题。基本思路如下: 使用两个指针(start和end)来定义一个窗口移动end指针来扩大窗口,直到遇到重复字符如果遇到重复字符,移动s…

FreeRTOS和UCOS操作系统使用笔记

FreeRTOS使用示例 UCOS使用示例 信号量使用 信号量访问共享资源区/ OS_SEMMY_SEM; //定义一个信号量&#xff0c;用于访问共享资源OSSemCreate ((OS_SEM* )&MY_SEM, //创建信号量&#xff0c;指向信号量(CPU_CHAR* )"MY_SEM", //信号量名字(OS_SEM_CTR )1, …

【C++】多态(详解)

前言&#xff1a;今天学习的内容可能是近段时间最难的一个部分的内容了&#xff0c;C的多态&#xff0c;这部分内容博主认为难度比较大&#xff0c;各位一起慢慢啃下来。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:高质量&#xff23…

绝地求生PUBG服务器延迟太高 购买领取响应时间长怎么解决

绝地求生PUBG是一款特别热门的射击类吃鸡游戏&#xff0c;游戏还有多张地图可供玩家选择&#xff0c;玩家们需要乘坐飞机空投跳伞至不同的各个角落&#xff0c;赤手空拳寻找武器&#xff0c;车辆以及物资&#xff0c;并在多种多样的地形中展开战斗。想要取得胜利&#xff0c;我…