Spring AI 学习指南(五)Jdbc持久化记忆实战|基于MySQL实现重启不丢失的多轮对话
统一环境:IDEA2026.1.1、JDK21、SpringBoot3.5.14、SpringAI1.1.6、智谱glm-4-flash、MySQL8.0
前置阅读:已掌握 Spring AI 分层记忆架构、InMemory内存记忆、MessageWindow滑动窗口机制
一、前言
上一篇我们彻底吃透了 Spring AI 官方标准记忆架构,基于内存存储实现了多轮上下文对话、会话隔离、消息窗口裁剪等核心能力。
但内存记忆存在致命短板:基于JVM内存存储,项目重启记忆全部丢失、不支持多实例集群共享,仅能用于本地开发测试,完全无法上线生产环境。
为了解决记忆持久化问题,Spring AI 官方提供了JdbcChatMemoryRepository 数据库存储方案,适配MySQL、PostgreSQL等主流关系型数据库。
本篇我们基于 MySQL + JDBC持久化记忆 + 滑动窗口策略 完成架构升级,实现:服务重启记忆不丢失、多实例集群共享、会话数据持久化归档,搭建稳定可靠的企业级对话记忆能力。
二、JdbcChatMemoryRepository 核心介绍
2.1 组件概念
JdbcChatMemoryRepository 是 Spring AI 官方提供的关系型数据库持久化仓库,实现了 ChatMemoryRepository 顶层存储接口,专门用于将对话消息持久化到数据库,替代临时的内存存储。
完美延续 Spring AI 策略与存储解耦的架构设计:上层记忆策略(MessageWindowChatMemory)完全不用改动,仅替换底层存储实现,即可完成持久化升级。
2.2 核心优势(对比内存存储)
-
持久化存储:对话数据落库,服务重启、宕机重启记忆永不丢失
-
集群共享:多实例部署共用同一数据库,实现多节点记忆数据同步
-
事务可靠:依托Spring事务机制,消息存取数据一致性有保障
-
多租户隔离:基于conversationId天然支持多用户、多会话隔离
-
可审计可归档:数据库留存完整对话数据,支持业务复盘、日志审计
2.3 适用场景
中小型AI对话系统、企业级智能客服、后台AI咨询功能、需要数据持久化的生产项目。
三、核心架构回顾
本次升级完全沿用原有架构体系,仅替换存储层实现,无侵入改造:
-
记忆策略层不变:继续使用 MessageWindowChatMemory 滑动窗口裁剪,控制消息数量,避免上下文膨胀
-
存储层升级:InMemoryChatMemoryRepository → JdbcChatMemoryRepository(MySQL)
-
自动装配不变:MessageChatMemoryAdvisor 自动完成消息存取、上下文拼接
这种解耦设计的最大优势:上层业务零改动,按需切换存储方案。
四、环境准备与依赖引入
4.1 引入核心Maven依赖
需要新增 Spring AI JDBC记忆仓库、MySQL驱动,pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.14</version>
<relativePath/>
</parent>
<groupId>demo.ai</groupId>
<artifactId>spring-ai-demo</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.ai.version>1.1.6</spring.ai.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring.ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-client-chat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-zhipuai</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
</project>
4.2 配置数据库连接
在 application.yml 中配置MySQL数据源,创建数据库spring_ai
spring:
ai:
zhipuai:
api-key: 4281feecb23exxxxxxx # 从智谱AI获取的 api-key
base-url: https://open.bigmodel.cn/api/paas
chat:
options:
model: glm-4-flash
temperature: 0.7 # 随机性 0-1 越低越严谨
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/spring_ai?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
username: root # 数据库用户名
password: 123456 #你的数据库密码
server:
servlet:
# 解决流式输出乱码
encoding:
charset: UTF-8 # UTF-8字符集
force: true # 强制使用UTF-8
enabled: true # 开启 Spring Boot 内置的编码过滤器
五、数据表自动初始化说明
注意:新版本Spring AI存在自动建表失效问题,不会自动生成spring_ai_chat_memory数据表,需要手动执行建表SQL,否则项目启动报错、记忆功能无法使用。下面提供可直接执行的标准建表语句:
CREATE TABLE IF NOT EXISTS spring_ai_chat_memory (
id BIGINT NOT NULL AUTO_INCREMENT,
conversation_id VARCHAR(36) NOT NULL,
content TEXT NOT NULL,
type VARCHAR(10) NOT NULL,
timestamp TIMESTAMP NOT NULL,
PRIMARY KEY (id),
INDEX idx_conv_ts (conversation_id, timestamp),
CONSTRAINT type_check CHECK (type IN ('USER', 'ASSISTANT', 'SYSTEM', 'TOOL'))
);
执行上述SQL后,会生成 spring_ai_chat_memory 数据表,用于存储会话ID、对话内容、消息类型、时间戳等全部记忆数据,完全适配JdbcChatMemoryRepository持久化规则。
六、全局配置类改造(核心代码)
仅修改存储层Bean,上层记忆策略、Advisor、ChatClient 配置完全复用,零业务侵入。
package demo.ai.conf;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.memory.repository.jdbc.JdbcChatMemoryRepository;
import org.springframework.ai.chat.memory.repository.jdbc.MysqlChatMemoryRepositoryDialect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
@Configuration
public class ChatMemoryConfig {
// /**
// * 1. 注册内存存储仓库(默认存储方案)
// */
// @Bean
// public InMemoryChatMemoryRepository chatMemoryRepository() {
// return new InMemoryChatMemoryRepository();
// }
/**
* 1. 升级为JDBC数据库持久化仓库(MySQL方言)
*/
@Bean
public JdbcChatMemoryRepository chatMemoryRepository(JdbcTemplate jdbcTemplate) {
// 指定MySQL方言,适配数据库语法
return JdbcChatMemoryRepository.builder()
.jdbcTemplate(jdbcTemplate)
.dialect(new MysqlChatMemoryRepositoryDialect())
.build();
}
// /**
// * 2. 注册滑动窗口记忆策略
// * maxMessages:最大保留消息条数,超出自动裁剪旧消息,保留系统消息
// */
// @Bean
// public MessageWindowChatMemory chatMemory(InMemoryChatMemoryRepository repository) {
// return MessageWindowChatMemory.builder()
// .chatMemoryRepository(repository)
// .maxMessages(10)
// .build();
// }
/**
* 2. 滑动窗口记忆策略(完全复用,无需改动)
* 最大保留10条消息,自动裁剪过期消息
*/
@Bean
public MessageWindowChatMemory chatMemory(JdbcChatMemoryRepository repository) {
return MessageWindowChatMemory.builder()
.chatMemoryRepository(repository)
.maxMessages(10)
.build();
}
/**
* 3. 构建自带记忆能力的ChatClient
* 自动装配记忆顾问,实现上下文自动拼接、自动存储
*/
@Bean
public ChatClient chatClient(ChatClient.Builder builder, MessageWindowChatMemory chatMemory) {
return builder
.defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())
.build();
}
}
七、控制器代码(完全复用)
得益于架构解耦,业务控制器无需一行代码改动,自动适配数据库持久化记忆。代码参考前一次教程。
八、核心原理与代码解析
8.1 方言适配机制
MysqlChatMemoryRepositoryDialect 是MySQL专属方言,用于适配MySQL的SQL语法、字段类型、主键规则,Spring AI 同时支持PostgreSQL、SQL Server等多种方言,切换数据库仅需替换方言类。
8.2 自动执行流程
-
请求触发:携带sessionId的用户提问
-
前置操作:Advisor从数据库查询该会话历史消息,拼接Prompt
-
模型调用:发送带上下文的请求,获取AI回复
-
后置操作:自动将本轮问答更新存入数据库
九、功能测试(核心验证:重启不丢失)
9.1 常规多轮记忆测试
1、首次请求:http://localhost:8080/memory/chat?sessionId=user001&msg=我想咨询内科挂号时间
2、重启系统
3、二次请求:http://localhost:8080/memory/chat?sessionId=user001&msg=我刚刚咨询的是什么科室?
结果:AI正常识别上下文,记忆生效,数据库可查询到对话记录。
9.2 核心持久化测试(重点)
1、停止SpringBoot项目,重启服务
2、再次调用上述上下文提问接口
测试结果:服务重启后,AI依然能记住历史对话,彻底解决内存记忆丢失问题!
9.3 会话隔离测试
不同sessionId完全隔离,各自记忆独立存储,无串台问题,支持多用户同时在线对话。
十、Jdbc持久化记忆优缺点
10.1 优势
-
数据持久化落库,服务重启、宕机记忆不丢失
-
支持集群多实例部署,多节点共享对话数据
-
依托数据库事务,数据安全可靠,支持审计归档
-
官方原生组件,无第三方依赖,适配Spring生态
-
架构解耦,上层业务无需改动,平滑升级
10.2 劣势
-
数据库读写性能有限,高并发场景QPS瓶颈明显
-
频繁读写数据库,会造成数据库IO压力
-
不适合超高并发、毫秒级响应的分布式AI对话场景
十一、本期踩坑总结
-
坑1:数据表不存在:未引入jdbc依赖、未配置数据源,未手动执行建表SQL、新版本自动建表失效,导致数据表不存在
-
坑2:方言不匹配:MySQL必须指定 MysqlChatMemoryRepositoryDialect,否则SQL语法报错
-
坑3:记忆不更新:未替换Bean,依然使用内存仓库,导致落库失效
-
坑4:上下文膨胀:未配置maxMessages,数据库消息数据持续累积,影响查询性能
十二、本篇学习总结
本期完成了 Spring AI 记忆体系的生产级升级,核心收获:
-
掌握 JdbcChatMemoryRepository 数据库持久化核心原理与实战
-
深刻体会 Spring AI 存储与策略解耦的优秀架构设计
-
实现可重启、可集群、可归档的企业级对话记忆
-
掌握多数据库方言适配、自动建表、窗口裁剪组合用法
-
区分内存存储与数据库存储的适用场景与性能差异
十三、结语
从内存临时记忆,到MySQL持久化记忆,我们一步步将AI对话能力从“测试Demo”打磨为“生产可用”。JDBC记忆方案足够满足中小型项目的生产需求,架构稳定、维护简单。
但对于大型平台、高并发AI对话系统,Redis分布式记忆才是最终的生产最优解,Spring AI 2.0.x将支持RedisChatMemoryRepository,因此后续不再手写RedisChatMemoryRepository。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)