1、概览 MyBatis 是一个开源 Java 持久层框架,可作为 JDBC 和 Hibernate 的替代品。它能简化持久层的代码,并自动封装结果集,开发者只需专注于编写自定义 SQL 查询或存储过程。
本文将带你了解如何在 Spring 中使用 MyBatis 插入(INSERT)数据时返回自动生成的 ID。
2、依赖设置 首先在 pom.xml 中添加 mybatis-spring-boot-starter 依赖:
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.0.3</version> </dependency> 3、示例 先创建一个简单的示例,在整个文章中都会用到。
3.1、定义实体 首先,创建一个代表汽车的简单实体类 Car:
public class Car { private Long id; private String model; // Getter / Setter 方法省略 } 其次,定义一条创建表的 SQL 语句,并将其放入 car-schema.sql 文件中:
CREATE TABLE IF NOT EXISTS CAR ( ID INTEGER PRIMARY KEY AUTO_INCREMENT, MODEL VARCHAR(100) NOT NULL ); 如上,ID 列是自增自主键(AUTO_INCREMENT)。
Spring Boot 3.3.0 已经发布,其中包含对 SBOM 的支持。SBOM 是 “Software Bill of Materials”(软件物料清单)的缩写,描述了用于构建软件构件的组件。在本文中,这些组件就是你的 Spring Boot 应用。SBOM 非常有用,因为它们准确地描述了你的应用包含的内容。有了这些信息,你可以评估安全漏洞是否影响你的应用,或者使用自动化安全工具扫描你的应用程序并提醒你存在的安全漏洞。
目前有多种 SBOM 格式,使用最广泛的是 CycloneDX、SPDX 和 Syft。Spring Boot 3.3.0 开箱即支持 CycloneDX。这种支持包括以下三个方面:
配置 CycloneDX 插件,以便在构建应用时生成 SBOM。 将生成的 SBOM 文件打包到 uber jar 中。 Actuator 端点,用于显示生成的 SBOM(如果启用)。 来看看如何进行实际操作:
首先,在 start.springboot.io 上生成一个新项目(确保选择 Spring Boot 3.3.0),并添加以下依赖:
Spring Web Actuator 然后,在 IDE 中打开生成的项目,如果使用的是 Gradle,将以下内容添加到你的 build.gradle 文件中:
plugins { id 'org.cyclonedx.bom' version '1.8.2' } 这将在构建中应用 CycloneDX Gradle plugin。Spring Boot 会检测到这一点,并负责插件的配置,你无需再做任何更改。
如果使用的是 Maven,则在 pom.xml 中加入以下内容:
1、概览 在使用 Spring Data JPA 时,我们经常会利用派生和自定义查询,以我们喜欢的格式返回结果。一个典型的例子就是 DTO 投影,它提供了一种只 SELECT 某些特定列以减少不必要数据开销的好方法。
然而,DTO 投影并不总是那么容易,如果实现不当,可能会导致 ConverterNotFoundException 异常。本文将带你了解 ConverterNotFoundException 异常出现的原因,以及如何在使用 Spring Data JPA 时避免 ConverterNotFoundException 异常。
2、在实践中理解异常 通过一个实际例子来理解异常。
为了简单起见,使用 H2 数据库。首先,在 pom.xml 文件中添加其依赖:
<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>2.2.224</version> </dependency> 2.1、H2 配置 Spring Boot 提供了对 H2 嵌入式数据库的支持。默认情况下,它会配置应用使用用户名 sa 和空密码连接到 H2。
将数据库连接凭证添加到 application.properties 文件中:
spring.datasource.url=jdbc:h2:mem:mydb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= 如上就是使用 Spring Boot 设置 H2 配置所需的全部内容。
2.2、Entity 类 们定义一个 JPA 实体类 Employee:
@Entity public class Employee { @Id private int id; @Column private String firstName; @Column private String lastName; @Column private double salary; // Getter/Setter 方法省略 } 如上,员工类(Employee)定义了 id、firstName、lastName 和 salary 属性。
1、概览 随着生成式 AI 和 ChatGPT 的广泛应用,许多语言都开始提供与 OpenAI API 交互的库。Java 也不例外。
本文将带你了解 openai-java 库,它是一个开源的 OpenAI API 客户端,可以很方便地与 OpenAI API 通信。
2、依赖 首先,导入项目所需的 依赖,以下这三个模块专门用于交互的不同方面:
<dependency> <groupId>com.theokanning.openai-gpt3-java</groupId> <artifactId>service</artifactId> <version>0.18.2</version> </dependency> <dependency> <groupId>com.theokanning.openai-gpt3-java</groupId> <artifactId>api</artifactId> <version>0.18.2</version> </dependency> <dependency> <groupId>com.theokanning.openai-gpt3-java</groupId> <artifactId>client</artifactId> <version>0.18.2</version> </dependency> 请注意,依赖名称中明确提到了 GPT3,但它 也适用于 GPT4。
3、Baeldung 辅导员 接下来,我们要构建一个工具,尝试根据我们最喜欢的学习平台上的文章和教程来创建课程表。虽然互联网为我们提供了无限的资源,我们几乎可以在线找到任何东西,但筛选信息却很困难。
4. OpenAI API Token 第一步是将应用连接到 OpenAI API。为此,需要提供一个 OpenAI Token,该 Token 可在 OpenAI 网站 上生成:
注意,要小心保存你的 Token,避免暴露它。为此,openai-java 示例使用了环境变量。这可能不是用于生产的最佳解决方案,但在小型实验中完全可行。
在运行时,不一定需要为机器配置环境变量;大多数 IDE 都支持在运行时为应用单独设置环境变量,例如 IntelliJ IDEA。
我们可以生成两种 Token:个人(Personal)和服务账户(Service Account)。个人 Token 不言自明。服务账户 Token 用于连接到 OpenAI 项目的机器人或应用。虽然两者都可以使用,但对于我们的目的来说,个人 Token 已经足够了。
1、概览 在软件开发这个要求严苛的领域中,确保应用在在部署到生产环境后能够以最佳性能和可靠性运行是至关重要的。
本文将带你了解如何在 Spring Boot 应该中整合 Prometheus,以及如何通过基本配置和复杂配置丰富我们的监控策略。
2、Prometheus 是什么? Prometheus 是一个开源项目,旨在深入挖掘我们的应用程序数据,通过创建过滤层来收集和分析从最简单到最复杂的所有内容。它不仅仅关乎数字和图表,而且通过其高级查询语言和时间序列数据能力,帮助我们理解应用程序的运行状况。
集成 Prometheus 使我们能够在问题发生之前就发现问题,对系统进行微调,确保应用程序以最佳性能运行,最终为用户带来更好的体验 - 方便、快捷、可靠。
3、开始在 Spring Boot 中使用 Prometheus 将 Prometheus 与 Spring Boot 应用程序整合后,就能以 Prometheus 可以理解和抓取的格式公开应用指标,从而有效地进行监控。这一过程包括两个主要步骤:向项目添加必要的依赖项,以及配置应用以公开指标。
3.1、添加依赖 首先,将 Spring Boot Actuator 和 Micrometer Prometheus Registry 添加到项目的依赖中。Actuator 提供了一系列内置端点,用于显示运行应用的性能信息,如健康状况、指标等。Micrometer Prometheus registry 会将这些指标格式化为 Prometheus 可读格式。
将依赖添加到 Maven 项目的 pom.xml 文件中:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency> 如果使用的是 Gradle,则应在 build.gradle 文件中添加如下内容:
implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'io.micrometer:micrometer-registry-prometheus' 3.2、配置应用 添加依赖后,下一步就是配置 Spring Boot 应用,使其暴露 Prometheus 指标端点。这需要更新项目中的 application.
1、概览 本文将带你了解 JPA 是如何托管实体的,以及 Persistence Context(持久化上下文)由于外部变化而无法返回最新数据的情况。
2、Persistence Context 每个 EntityManager 都与一个 Persistence Context 相关联,该上下文在内存中存储所管理的实体。每当通过 EntityManager 对实体执行任何数据操作时,该实体就会变成由 Persistence Context 管理的实体。
当再次检索实体时,JPA 会从 Persistence Context 返回托管实体,而不是从数据库中获取。这种缓存机制有助于提高性能,而无需从数据库中重复获取相同的数据。
Persistence Context 在 JPA 中也被称为一级(first-level,L1)缓存。
3、Demo 设置 首先,创建一个简单的实体类:
@Entity @Table(name = "person") public class Person { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; // 构造函数、Getter、Setter 方法省略 } 接下来,创建一个 Person 实体并将其持久化到数据库中:
EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); Person person = new Person(); person.setName("David Jones"); entityManager.persist(person); transaction.
1、简介 继承(Inheritance)和组合(Composition)是面向对象编程(OOP)中的两个基本概念,我们也可以在 JPA 中利用它们进行数据建模。在 JPA 中,继承和组合都是对实体间关系进行建模的技术,但它们代表的是不同类型的关系。本文将带你了解这两种方法及其影响。
2、JPA 中的继承 继承是一种 “is-a” 关系,即子类继承超类的属性和行为。这允许子类从超类继承属性和方法,从而促进了代码的重用。JPA 提供了几种策略来模拟实体与其对应的数据库表之间的继承关系。
2.1、单表继承(STI) 单表继承(Single Table Inheritance,STI)将所有子类映射到单个数据库表中。通过利用 区分列 来区分子类实例,这简化了 Schema 管理和查询执行过程。
首先,使用 @Entity 注解将 Employee 实体类定义为超类。接下来,将继承策略设置为 InheritanceType.SINGLE_TABLE,这样所有子类都会映射到同一个数据库表*。
然后,使用 @DiscriminatorColumn 注解来指定 Employee 类中的 区分列。该列用于区分单个表中不同类型的实体。
示例如下,使用 name = "employee_type" 将列名称指定为 employee_type,并使用 discriminatorType = DiscriminatorType.STRING 表示列包含字符串值:
@Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "employee_type", discriminatorType = DiscriminatorType.STRING) public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; // Get / Set 方法省略 } 对于每个子类,使用 @DiscriminatorValue 注解来指定与该子类相对应的 区别列 的值。在本例中,我们使用 manager 和 developer 分别作为 Manager 和 Developer 子类的 区别值:
1、概览 本文将带你了解 JPA 如何自动保存复杂的实体模型(即由父实体和子实体元素组成的复杂模型)以及常见的问题。
2、缺失关系注解 我们可能会忽略的第一件事就是添加关系注解。
创建一个子实体:
@Entity public class BidirectionalChild { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; //Get/Set 方法省略 } 创建一个包含 List<BidirectionalChild> 的父实体:
@Entity public class ParentWithoutSpecifiedRelationship { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private List<BidirectionalChild> bidirectionalChildren; //Get/Set 方法省略 } 如上,bidirectionalChildren 字段上没有注解。尝试用这些实体创建一个 EntityManagerFactory:
@Test void givenParentWithMissedAnnotation_whenCreateEntityManagerFactory_thenPersistenceExceptionExceptionThrown() { PersistenceException exception = assertThrows(PersistenceException.class, () -> createEntityManagerFactory("jpa-savechildobjects-parent-without-relationship")); assertThat(exception) .hasMessage("Could not determine recommended JdbcType for Java type 'com.baeldung.BidirectionalChild'"); } 运行测试,出现了异常,无法确定子实体的 JdbcType。单向和双向关系都会出现类似的异常,其根本原因是父实体中缺失 @OneToMany 注解。
1、概览 本文将带你了解如何在 Spring Boot 应用中格式化 JSON Date 字段。
Spring Boot 默认使用 Jackson 作为 JSON 的序列化/反序列化框架。
2、在 Date 字段上使用 @JsonFormat 2.1、设置格式化 我们可以使用 @JsonFormat 注解来格式化特定字段:
public class Contact { // 其他字段 @JsonFormat(pattern="yyyy-MM-dd") private LocalDate birthday; @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") private LocalDateTime lastUpdate; // getter/setter 方法省略 } 如上,用了 Java 8 的日期类型,它在处理时间类型时非常方便。birthday 字段只显示日期,而 lastUpdate 字段则包括了时间。
当然,如果需要使用 java.util.Date 等传统类型,也可以同样的方式使用注解:
public class ContactWithJavaUtilDate { // 其他字段 @JsonFormat(pattern="yyyy-MM-dd") private Date birthday; @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date lastUpdate; // getter/setter 方法省略 } 最后,来看看使用 @JsonFormat 格式化日期字段后的输出:
1、概览 MyBatis 是 Java 界流行的持久化框架,它通过将 SQL 查询映射到 Java 方法来简化数据库操作。
在使用 MyBatis 开发应用时,查看正在执行的 SQL 查询通常对调试很有用,本文将带你了解如何在 MyBatis 中将 SQL 查询日志输出到控制台。
2、支持的日志实现 MyBatis 是一个灵活的框架,可以与各种日志框架集成,包括 SLF4J、Apache Commons Logging、Log4j 2 和 JDK Logging。本文主要关注 Stdout (标准输出,即控制台)日志和 SLF4J。
Stdout 日志在本地功能开发过程中非常有用,它提供了一种简单的调试方法。而 SLF4J 更适合生产应用,它提供了更高级的抽象,可与其他的日志框架无缝集成。
3、在 MyBatis 中配置 Stdout 日志 使用 stdout 记录 MyBatis SQL,可以直接在控制台上查看执行的 SQL 语句。这种方法在开发和调试过程中非常方便。
要启用 MyBatis SQL 的 stdout 日志,需要在应用的 mybatis-config 文件中添加日志设置:
<configuration> <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> </configuration> 将 logImpl 属性配置为 STDOUT_LOGGING 后,MyBatis 将在执行 SQL 查询时输出原始 SQL 语句、查询参数和查询结果。输出通常包括执行的 SQL、绑定的参数和返回的结果集等详细信息: