在 Java 中使用 Blowfish 加密算法

1、概览 Blowfish 加密算法最初是作为 DES 加密算法的替代方案而设计的,是当今最流行的加密算法之一。Blowfish 是一种对称的分组加密算法,由 Bruce Schneier 于 1993 年设计 。该算法的块大小为 64 位,密钥长度为 446 位,优于 DES 和 3DES 算法。 本文将带你了解如何使用 Java Cryptography Architecture(JCA)中提供的 Blowfish 算法实现加密和解密。 2、生成密钥 由于 Blowfish 是一种对称加密算法,它在加密和解密过程中使用相同的密钥。所以,接下来我们要创建一个密钥来加密文本。这个密钥应该被安全地保存,不应该在公共场合分享。 定义密钥: // 定义密钥 String secretKey = "MyKey123"; byte[] keyData = secretKey.getBytes(); //使用 Blowfish 算法创建 SecretKeySpec SecretKeySpec secretKeySpec = new SecretKeySpec(keyData, "Blowfish"); 接下来,就可以通过加密模式构建 Cipher 了: // 使用 Blowfish 算法创建 Cipher Cipher cipher = Cipher.getInstance("Blowfish"); 然后,使用加密模式(Cipher.ENCRYPT_MODE)初始化 cipher,并指定 Secret Key: // 使用 Secret Key 在加密模式下初始化 cipher cipher.

从 Spring Security 5 迁移到 Spring Security 6/Spring Boot 3

1、概览 Spring Security 6 有几处重大变化,包括删除了一些类和已废弃的方法,并引入了一些新方法。 从 Spring Security 5 迁移到 Spring Security 6 可以在不破坏现有代码的情况下逐步完成。此外,还可以使用 OpenRewrite 等第三方插件来促进向最新版本的迁移。 本文将带你了解如何把 Spring Security 5 的现有应用迁移到 Spring Security 6(替换过时的方法,并利用 Lambda DSL 简化配置。此外,还利用 OpenRewrite 加快迁移速度)。 2、Spring Security 和 Spring Boot 版本 Spring Boot 基于 Spring 框架,各版本的 Spring Boot 使用最新版本的 Spring 框架。Spring Boot 2 默认使用 Spring Security 5,而 Spring Boot 3 使用 Spring Security 6。 要在 Spring Boot 应用中使用 Spring Security,首先需要在 pom.xml 中添加 spring-boot-starter-security 依赖。 可以在 pom.xml 的 properties 部分 指定所需的版本,从而覆盖默认的 Spring Security 版本 :

在 Spring Boot 中处理 Kafka Offset(偏移量)

本文将带你了解如何使用 Spring Boot 和 Spring Kafka 管理 Kafka 消费者偏移量(Offset)。 在之的一篇文章中,主要说明了应用处理 Kafka 消息的方式可能会影响系统的整体性能,并没有考虑消费者端的消息重复或消息丢失等问题。本文将会介绍这些话题。 1、源码 本文中的源码托管在 GitHub,你可以克隆它到本地,然后按照说明中的步骤操作即可。 2、简介 在开始之前,首先要说明一些与使用 Spring Kafka 提交偏移量有关的重要事项。首先,默认情况下,Spring Kafka 会将消费者的 enable.auto.commit 属性设置为 false。这意味着提交偏移量的责任在于框架,而非 Kafka。当然,我们可以通过将该属性设置为 true 来改变默认行为。顺便说一句,这也是 Spring Kafka 2.3 之前的默认做法。 禁用了 Kafka 自动提交(Auto Commit)后,我们就可以利用 Spring Kafka 提供的 7 种不同的提交策略。本文不会分析所有策略,只分析最重要的几种。默认策略是 BATCH。为了设置不同的策略,需要覆盖 AckMode,例如在 Spring Boot application.properties 中设置 spring.kafka.listener.ack-mode 属性的值。 首先来看看 BATCH 模式。 3、Spring Boot Kafka 应用示例 为了测试使用 Spring Kafka 进行的偏移提交,我们将创建两个简单的应用:producer (生产者)和 consumer(消费者)。生产者向 Topic 发送规定数量的消息,而消费者接收并处理这些消息。下面是生产者 @RestController 的实现。它允许我们按需向 transactions Topic 发送指定数量的消息: @RestController public class TransactionsController { private static final Logger LOG = LoggerFactory .

使用最新的Mistral AI API,在 Java 和 Spring AI 中进行函数调用

领先的开源大型语言模型开发商 Mistral AI 宣布,其尖端模型新增了 函数调用 支持。 函数调用 是一种便于 LLM 与外部工具和 API 集成的功能。它使语言模型能够请求执行客户端函数,从而访问必要的运行时信息或动态执行任务。 本文将带你了解如何将 Mistral AI 的新函数调用功能与 Java 特别是 Spring AI 结合使用。 如果你对底层的 Java 客户端的详细细节不感兴趣,不想浪费时间,可以直接看 使用 Spring AI 调用函数 章节。 1、使用 Java 调用函数 如果你想使用 Java 和 Spring AI 测试最新的 Mistral AI 功能,你会发现 Mistral 不支持 Java 客户端,也还没有发布函数调用 API。 因此,我不得不通过探索他们的 JavaScript/Python 客户端来解决这个问题。下面是一个类图,说明了 API 的各个组件及其相互联系。 熟悉 OpenAI API 的人会注意到,Mistral AI 的新 API 几乎与 OpenAI API 相同,只有一些细微差别。不过,还有一个重要的限制: 在撰写本文时,Mistral AI 不支持并行函数调用,这使它与 OpenAI、Azure OpenAI 和 Vertex AI Gemini 提供的最新 LLM 模型有所不同。

使用 JUnit 和 @DataJpaTest 测试 Spring Data Repository

1、简介 在使用 Spring Data JPA 进行数据持久化的 Spring Boot 应用中,测试与数据库交互的 Repository 至关重要。 本文将带你了解如何使用 Spring Boot 提供的 @DataJpaTest 注解和 JUnit 对 Spring Data JPA Repository 进行有效地测试。 2、了解 @DataJpaTest 和 Repository 类 本节主要介绍在 Spring Boot 应用中,@DataJpaTest 和 Repository 之间的交互。 2.1、@DataJpaTest @DataJpaTest 注解用于测试 Spring Boot 应用中的 JPA Repository。它是一个专门的测试注解,为测试持久层提供了一个最小的 Spring Context。该注解可与 @RunWith 和 @SpringBootTest 等其他测试注解结合使用。 此外,@DataJpaTest 的范围仅限于应用的 JPA Repository 层。它不会加载整个 Application Context,从而使测试更快、更集中。此注解还为测试 JPA 实体提供了预配置的 EntityManager 和 TestEntityManager。 2.2、Repository 在 Spring Data JPA 中,Repository 是 JPA 实体之上的一个抽象层。它为执行 CRUD(创建、读取、更新、删除)操作和执行自定义查询提供了一组方法。这些 Repository 通常从 JpaRepository 等接口继承而来,负责处理与特定实体类型相关的数据库交互。

Spring Data JPA 执行 INSERT 时跳过 SELECT

1、概览 在某些情况下,当使用 Spring Data JPA Repository 保存实体时,可能会在日志中遇到额外的 SELECT。这可能会因大量额外调用而导致性能问题。 本文将带你了解如何在 Spring Data JPA 中执行 INSERT 时跳过 SELECT,以提高性能。 2、设置 在深入 Spring Data JPA 并对其进行测试之前,先要做一些准备工作。 2.1、依赖 为了创建测试 Repository,需要使用 Spring Data JPA 依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> 使用 H2 数据库作为测试数据库: <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> 使用 Spring Context 进行集成测试。添加 spring-boot-starter-test 依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> 2.2、配置 本例中使用的 JPA 配置如下: spring.jpa.hibernate.dialect=org.hibernate.dialect.H2Dialect spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.hibernate.show_sql=true spring.jpa.hibernate.hbm2ddl.auto=create-drop 如上,让 Hibernate 生成 schema,并将所有 SQL 查询记录到日志中。 3、导致 SELECT 查询的原因 首先,创建一个 Task 实体:

Spring Data JPA Repository 和数据库视图

1、概览 数据库视图(Database View)是关系型数据库系统中的一种类似表的结构,其中的数据源来自一个或多个连接在一起的表。 Spring Data Repository 通常用于数据库表,但也可以有效地应用于数据库视图。本文将带你了解如何在 Spring Data JPA 中使用 Repository 从数据库视图检索数据。 2、数据库表设置 本文使用 H2 数据库系统进行数据定义,并使用 SHOP 和 SHOP_TRANSACTION 这两个示例表演示数据库视图概念。 SHOP 表存储商店信息: CREATE TABLE SHOP ( shop_id int AUTO_INCREMENT, shop_location varchar(100) NOT NULL UNIQUE, PRIMARY KEY(shop_id) ); SHOP_TRANSACTION 表存储与商店相关的交易记录,并通过 shop_id 对 SHOP 表进行引用: CREATE TABLE SHOP_TRANSACTION ( transaction_id bigint AUTO_INCREMENT, transaction_date date NOT NULL, shop_id int NOT NULL, amount decimal(8,2) NOT NULL, PRIMARY KEY(transaction_id), FOREIGN KEY(shop_id) REFERENCES SHOP(shop_id) ); 在实体-关系(ER)模型中,可以将其说明为 “一对多” 的关系,即一个商店可以有多笔交易。但是,每笔交易只与一家商店相关联。可以用 ER 图直观地表示这一点:

Spring Data Jpa 中的 Query Hint

1、简介 本文将带你了解 Spring Data JPA 中 Query Hint (查询提示)的功能、基本原理以及如何有效地应用它们。 这些提示有助于优化数据库查询,并通过影响优化器的决策过程来改善应用性能。 2、理解 Query Hint Spring Data JPA 中的 Query Hint 是一种强大的工具,可帮助优化数据库查询并提高应用性能。与直接控制执行不同,Query Hint 会影响优化器(Optimizer)的决策过程。 在 Spring Data JPA 中,可以在 org.hibernate.annotations 包中找到这些 Hint,同时还有与 Hibernate 相关的各种注解和类。需要注意的是,这些 Hint 的解释和执行通常取决于底层持久化层实现(Persistence Provider),如 Hibernate 或 EclipseLink,因此它们是特定于厂商的。 3、使用 Query Hint Spring Data JPA 提供了多种利用 Query Hint 优化数据库查询的方法。 3.1、基于注解的配置 Spring Data JPA 提供了一种使用注解为 JPA 查询添加 Query Hint 的简便方法。通过 @QueryHints 注解,可以指定用于生成 SQL 查询的 JPA @QueryHint 数组。 示例如下,设置了 JDBC fetch size Hint,以限制结果返回的大小:

在 Spring Boot 中使用 JPA 调用自定义数据库函数

1、概览 数据库函数是数据库管理系统的重要组成部分,可将逻辑和执行封装在数据库中。它们有助于高效的数据处理和操作。 本文将带你了解在 Spring Boot 应用中使用 Spring Data JPA 调用自定义数据库函数的各种方法。 2、项目设置 为了简单,本文使用 H2 数据库。 首先在 pom.xml 中加入 Spring Boot Data JPA 和 H2 依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>3.2.2</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>2.2.224</version> </dependency> 3、数据库函数 数据库函数是通过在数据库中执行一组 SQL 语句或操作来执行特定任务的数据库对象。当逻辑是数据密集型的时候,这可以提高性能。虽然数据库函数和存储过程的操作类似,但它们也有不同之处。 3.1、函数与存储过程 虽然不同的数据库系统之间可能会有具体的差异,但它们之间的主要差异可归纳在下表中: 特点 数据库函数 存储过程 执行 可在查询中调用 必须明确调用 返回值 始终返回一个值 可返回无值、单值或多值 参数 仅支持输入参数 支持输入和输出参数 调用 无法使用函数调用存储过程 可使用存储过程调用函数 用途 通常执行计算或数据转换 通常用于复杂的业务逻辑 3.2、H2 函数 为了说明如何从 JPA 调用数据库函数,我们将创建一个在 H2 数据库中的数据库函数来说明如何从 JPA 中调用它。 H2 数据库函数只是一个嵌入的 Java 源代码,它将被编译和执行:

Spring Data JPA 使用 findby 定义多个条件列

1、简介 Spring Data JPA 提供了查询推导功能(派生查询),只需遵循方法名称约定就能自动推导出查询。 本文将带你了解如何使用查询推到功能,通过一列或多列查找实体。 2、设置 定义一个 Account 实体,其中包含与用户账户相关的属性: @Entity @Table(name = "ACCOUNTS") public class Account { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "accounts_seq") @SequenceGenerator(name = "accounts_seq", sequenceName = "accounts_seq", allocationSize = 1) @Column(name = "user_id") private int userId; private String username; private String password; private String email; private Timestamp createdOn; private Timestamp lastLogin; @OneToOne @JoinColumn(name = "permissions_id") private Permission permission; // getter / setter } 为了演示,在 ACCOUNTS 表中添加一些示例数据: