1、简介 本文将带你了解 SessionFactory 和 EntityManagerFactory 之间的异同。
顾名思义,这两个类都是用于创建数据库通信对象的工厂类。除了创建对象,它们还提供了其他功能,帮助我们与数据库进行交互。
2、EntityManagerFactory 是什么? Java 持久化 API(JPA)是 Java 应用管理持久化数据的规范。它提供了一种与关系数据库交互的标准方式。EntityManager(实体管理器)作为 JPA 的核心接口,用于与持久化上下文交互并管理实体的生命周期。它为基本的 CRUD 操作提供了具有方法的轻量级实例。
EntityManagerFactory 是一个 JPA 接口,用于创建 EntityManager 实例,以线程安全的方式与持久化上下文(Persistence Context)交互。
2.1、示例 首先,先定义实体:
@Entity(name = "persons") public class Person { @Id @GeneratedValue(strategy= GenerationType.IDENTITY) private Integer id; private String name; private String email; // Getter / Setter 省略 } 设置配置有多种方法,这里使用 persistence.xml 配置文件的方法。首先,需要在 resource/META-INF 文件夹中创建该配置文件,并定义连接配置:
<persistence-unit name="com.baeldung.sfvsemf.persistence_unit" transaction-type="RESOURCE_LOCAL"> <description>Persistence Unit for SessionFactory vs EntityManagerFactory code example</description> <class>com.baeldung.sfvsemf.entity.Person</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="hibernate.
1、概览 Oracle 数据库是最流行的关系数据库之一。本文将带你了解如何使用 JDBC 驱动连接到 Oracle 数据库。
2、数据库 首先,我们需要一个数据库。如果没有,则可以从 Oracle Database Software Downloads 下载并安装免费版本,或者使用 Oracle Database Container Images 上的 Docker 镜像。
本文中使用的是 Oracle Database 23ai (23.5.0) 的 Docker 镜像。
3、Maven 依赖 数据库就绪后,在项目中添加 Oracle 的 JDBC 驱动依赖,本文使用 ojdbc11 连接 Oracle 23ai:
<dependency> <groupId>com.oracle.database.jdbc</groupId> <artifactId>ojdbc11</artifactId> <version>23.5.0.24.07</version> </dependency> ojdbc11 的最新版本可在 Central Maven Repository 中找到。该依赖项要求 Java 11 或更高版本,是较新版本 Java 的推荐驱动。
为了向后兼容,ojdbc8 可用于 Java 8。也推荐使用 ojdbc10 作为 Oracle 19c 的驱动程序。
4、连接到数据库 首先,创建一个 OracleDataSource(Oracle 数据源接口的实现)。这比使用 DriverManager 更好,因为 DataSource 更具可扩展性,也更易于设置。
1、简介 Spring 为程序员简化 Java 应用程序中的数据库交互提供了一个最强大的框架,那就是 Spring JPA(Java Persistence API)。它为 JPA 提供了一个稳定的抽象。
然而,尽管使用方便,开发人员还是经常会遇到一些错误,而这些错误的排查和解决都非常具有迷惑性。其中一个常见问题就是 “Unable to Locate Attribute with the Given Name” 错误。
本文将带你了解 Spring JPA 出现 “Unable to Locate Attribute with the Given Name” 异常的原因以及解决办法。
2、案例 我们生产了一个可穿戴的小工具。经过最近的一项调查,我们的营销团队发现,在我们的平台上按传感器类型、价格和受欢迎程度对产品进行分类,可以突出最受欢迎的产品,从而帮助客户做出更好的购买决策。
3、添加 Maven 依赖 我们使用 H2 内存数据库在项目中创建一个可穿戴设备表,并将样本数据填充到该表中,以便在接下来的测试中使用。
首先,添加以下 Maven 依赖:
<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>2.2.224</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>2.7.11</version> </dependency> 4、应用配置 在 src/main/resources 文件夹中,创建包含以下配置内容的 application-h2.properties:
# H2 配置 hibernate.dialect=org.hibernate.dialect.H2Dialect hibernate.hbm2ddl.auto=create-drop # Spring Datasource URL spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1 在 src/main/resources 文件夹中创建名为 testdata.
1、概览 在 Spring Data 中,使用基于方法名称的派生查询来查询实体是很常见的。在处理实体之间的关系(如嵌套对象)时,Spring Data 提供了各种机制来检索这些嵌套对象中的数据。
本文将带你了解如何使用查询派生和 JPQL(Java 持久性查询语言)通过嵌套对象的属性进行查询。
2、场景概述 考虑一个有两个实体的简单场景:Customer 和 Order。每个 Order 都通过 ManyToOne(多对一)关系关联到一个 Customer。
我们要查找属于某个 Customer 的所有 Order,该 Customer 有特定的 email。在这种情况下,email 是 Customer 实体的属性,而我们的主要查询将在 Order 实体上执行。
实体示例如下:
@Entity @Table(name = "customers") public class Customer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; // Getter / Setter 省略 } @Entity @Table(name = "orders") public class Order { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private Date orderDate; @ManyToOne @JoinColumn(name = "customer_id") private Customer customer; // Getter / Setter 省略 } 3、使用派生查询 Spring Data JPA 允许开发者从 Repository 接口中的方法签名派生查询,从而简化了查询创建:
1、简介 虚拟线程是 JDK 21 中正式引入的一项杀手锏级别的功能,是提高应用程序性能、吞吐量的一种解决方案。
但是,JDK 没有内置的使用虚拟线程的任务调度器。因此,我们得自己编写使用虚拟线程运行的任务调度器。
本文将带你了解如何使用 Thread.sleep() 方法和 ScheduledExecutorService 类为虚拟线程创建自定义调度器。
2、虚拟线程是什么? JEP-444 中引入了虚拟线程,作为线程类的轻量级版本,提高了应用程序的并发性和吞吐量。
虚拟线程占用的空间比通常的操作系统线程(或平台线程)要少得多。因此,我们可以在应用程序中同时产生比平台线程更多的虚拟线程。毫无疑问,这增加了并发单元的最大数量,也提高了应用程序的吞吐量。
关键的一点是,虚拟线程并不比平台线程更快(任务的耗时不会有改变)。在我们的应用中,虚拟线程的数量只比平台线程多,这样它们就能执行更多的并行工作。
虚拟线程的成本很低,因此我们不需要使用资源池等技术来为数量有限的线程安排任务。相反,我们可以在现代计算机中几乎无限地生成虚拟线程,而不会出现内存问题。
最后,虚拟线程是动态的,而平台线程的大小是固定的。因此,虚拟线程比平台线程更适合小型任务,如简单的 HTTP 或数据库调用。
3、虚拟线程调度 如上所述,虚拟线程的一大优势是体积小、成本低。我们可以在一个简单的机器中有效地生成数百万个虚拟线程,而不会出现内存不足的错误。因此,像使用平台线程、网络或数据库连接等更昂贵的资源那样池化虚拟线程并没有太大意义。
如果使用线程池,就会产生另一种开销,即为池中可用的线程调度任务,这将更加复杂,速度也可能更慢。此外,Java 中的大多数线程池都受到平台线程数的限制,而平台线程数总是小于程序中可能存在的虚拟线程数。
因此,我们必须避免使用带有线程池 API(如 ForkJoinPool 或 ThreadPoolExecutor)的虚拟线程。相反,我们应该始终为每个任务创建一个新的虚拟线程。
目前,Java 并没有提供使用虚拟线程进行调度的标准 API,就像我们使用其他并发 API(如 ScheduledExecutorService 的 schedule() 方法)一样。因此,为了有效地让虚拟线程运行计划任务,我们需要编写自己的 Scheduler(调度器)。
3.1、使用 Thread.sleep() 调度虚拟线程 创建自定义 Scheduler 的最直接方法是使用 Thread.sleep() 方法,让程序在当前线程执行时等待:
static Future<?> schedule(Runnable task, int delay, TemporalUnit unit, ExecutorService executorService) { return executorService.submit(() -> { try { Thread.sleep(Duration.of(delay, unit)); } catch (InterruptedException e) { Thread.
1、概览 处理 Date(日期)和 Time(时间)是许多 Java 应用程序的基本组成部分。多年来,Java 在处理日期方面不断发展,引入了更好的解决方案来简化开发者的工作。
2、传统的日期和时间处理类 在 java.time 包出现之前,Java 主要使用 Date 和 Calendar 类来处理日期。尽管它们现在也可以使用,但是有一些缺陷。
2.1、java.util.Date 类 java.util.Date 类是 Java 最初处理日期的解决方案,但它有一些缺点:
它是可变的,这意味着可能会遇到 线程安全 问题。 不支持时区。 它使用了令人困惑的方法名称和返回值,比如 getYear(),它返回的是自 1900 年以来的年数。 许多方法已废弃。 使用无参数构造函数创建 Date 对象,表示当前日期和时间(对象创建时)。
如下,实例化一个 Date 对象并打印其值:
Date now = new Date(); logger.info("Current date and time: {}", now); 这将输出当前日期和时间,如 Wed Sep 24 10:30:45 PDT 2024。虽然该构造函数仍然有效,但由于上述原因,这里不再建议新项目使用该构造函数。
2.2、java.util.Calendar 类 由于 Date 的局限性,Java 引入了 Calendar 类,对其进行了改进:
支持各种日历系统。 时区管理。 更加直观的日期操作方法。 我们可以使用 Calendar 操作日期。
Calendar cal = Calendar.
1、简介 Jakarta Persistence(前身为 JPA)是 Java 中对象关系映射的标准 API。它使开发人员能够在 Java 应用中管理关系数据,并通过使用注解和实体类将 Java 对象映射到数据库表来简化数据库交互。
本文将带你了解 Jakarta Persistence 3.2 中引入的一些关键新功能,重点介绍在配置、性能和可用性方面的改进。
2、Jakarta Persistence 3.2 是什么? Jakarta Persistence 3.2 是 Jakarta Persistence API 的最新版本,它为 Java 应用中的对象关系映射(ORM)提供了一种标准化方法。
该版本改进了查询功能、性能和可用性,并增强了对现代数据库功能的支持。
要添加对 Jakarta Persistence 3.2 的支持,必须在 pom.xml 中添加以下 Maven 依赖:
<dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>3.2.0</version> </dependency> 此外,还需要支持该 API 的最新 Hibernate 7 版本:
<dependency> <groupId>org.hibernate.orm</groupId> <artifactId>hibernate-core</artifactId> <version>7.0.0.Beta1</version> </dependency> 3、关键的新功能 Jakarta Persistence 3.2 引入了一些新功能,以改进数据库连接处理、模式配置和事务管理。
3.1、持久化配置 最新的 Jakarta Persistence 3.2 版本添加了编程式 API,可使用 PersistenceConfiguration 类而不是传统的 persistence.
1、简介 尽管 OpenAPI 3.x 规范自 2017 年起就已发布,并经历了多次更新,但目前许多 API 仍在继续使用旧版本。
本文将带你了解 OpenAPI 2.0 和 OpenAPI 3.0 规范之间的主要区别,以及如何将 OpenAPI 2.0 规范转换为 OpenAPI 3.0。
2、OpenAPI 2.0 和 OpenAPI 3.0 简单回顾一下,OpenAPI 提供了一种标准格式,用于描述人类和机器都能读懂的 HTTP API。在 3.0 版之前,OpenAPI 被称为 Swagger 规范和 Swagger 工具包的一部分。从那时起,它已成为行业标准,并经过多次更新,带来了更多改进和功能。
与 2.0 相比,OpenAPI 3.0 引入了几项根本性变化。
首先,对整体结构进行了重构,以提高可重用性。添加了一个 components(组件)块来组织现有元素(如 schemas、responses、parameters)和新元素(请求 requestBody、examples 和 headers)。一些元素被重新命名 - definitions 现在被称为 schemas,securityDefinitions 被称为 securitySchemes。
此外,OpenAPI 3.0 还进一步扩展了 JSON Schema 功能。添加了 oneOf、anyOf 和 not 等关键字,以便对复杂的数据格式进行描述和灵活验证。
3.0 版本还引入了对 cookie 参数、内容类型协商和回调机制的支持。它还扩展了安全定义并简化了现有流程。
最后,你可以在官方 更新日志 中查看完整的变更列表。
1、概览 Secure Shell(SSH)允许我们安全地访问和管理远程系统,包括执行命令、传输文件和隧道服务。
我们可以通过 SSH 会话建立与远程 MySQL 数据库的连接。Java 有多个 SSH 客户端,其中最常见的是 Java Secure Channel(JSch)。
本文将带你了解如何通过 SSH 会话连接到运行在远程服务器上的 MySQL 数据库。
2、了解 SSH 端口转发 端口转发允许通过在 SSH 连接上将流量从本地端口重定向到远程服务器上的端口,从而实现客户系统和远程服务器之间的数据传输。
当防火墙或其他限制阻止直接连接远程服务器的 IP 和端口时,这一点尤其有用。
在本例中,MySQL 服务器运行在远程服务器的 localhost 上,通常使用 3306 端口。虽然从技术上讲,可以直接连接到远程服务器的 IP 和 MySQL 端口,但出于安全考虑,这通常会受到限制(3306 端口未开放)。相反,我们可以通过 SSH 使用本地端口转发来建立与数据库的安全连接。
在本地端口转发中,我们在本地机器上分配一个可用端口,并将其与远程运行的 MySQL 服务器端口绑定,以允许我们的程序与远程服务器之间进行数据通信。
3、Maven 依赖 首先,在 pom.xml 中添加 JSch 和 MySQL 驱动依赖:
<dependency> <groupId>com.github.mwiede</groupId> <artifactId>jsch</artifactId> <version>0.2.20</version> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>9.0.0</version> </dependency> JSch 提供了 Session 等类,这些类对于建立与远程服务器的 SSH 连接至关重要。此外,MySQL 驱动允许我们与运行中的 MySQL 服务器建立连接。
1、概览 Java 数据库连接(JDBC)应用编程接口(API)提供了一系列类和接口。我们可以使用它们连接关系数据库等数据源并运行 SQL 语句。
以流行的 MYSQL 为例,当我们需要连接到 MySQL 时,就需要使用 MySQL 数据库的专用 JDBC 驱动程序: com.mysql.cj.jdbc.Driver,该驱动实现了 JDBC API。
在运行 SQL 语句时,我们可能会遇到异常:“com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Data too long for column”。
本文将带你了解出现此异常的原因,以及解决办法。
2、Schema 设置 首先,创建如下关系表 department:
DESC department; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int | NO | PRI | NULL | | | name | varchar(50) | YES | | NULL | | | code | varchar(4) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 注意,code 列定义只允许使用大小为 4 或更小的 varchar。