AI 时代,使用 dbVisitor 读写向量化数据

AI 时代的数据库应用越来越多地需要存储和检索向量数据。PostgreSQL 的 pgvector 扩展提供了高效的向量存储和相似性搜索能力,但在 Java 侧一直缺少优雅的映射方案。

dbVisitor 6.7.0 新增的 PgVectorTypeHandler 让你可以用 List<Float> 直接映射 pgvector 的 vector 类型,配合 Fluent API 实现完整的向量 CRUD 和 KNN 检索。

pgvector 是什么?

pgvector 是 PostgreSQL 的向量扩展,支持:

  • 存储高维向量(如 embedding)
  • L2 距离、余弦相似度、内积等相似性搜索
  • IVFFLAT 和 HNSW 索引加速

在 AI 应用中,文本 embedding、图片特征向量、推荐系统的用户向量等都需要存入数据库并执行最近邻搜索。

PgVectorTypeHandler 的使用

映射定义

java 复制代码
@Table("product_vector")
public class ProductVector {
    @Column(primary = true)
    private Integer id;
    private String name;
    
    @Column(typeHandler = PgVectorTypeHandler.class)
    private List<Float> embedding;
    
    // getters/setters...
}

只需在 @Column 注解上指定 typeHandler = PgVectorTypeHandler.class,即可实现 List<Float> 与 pgvector vector 类型的自动互转。

基本 CRUD

java 复制代码
LambdaTemplate lambda = new LambdaTemplate(dataSource);

// 插入向量数据
ProductVector product = new ProductVector();
product.setId(1);
product.setName("iPhone");
product.setEmbedding(Arrays.asList(0.1f, 0.2f, 0.3f));

lambda.insert(ProductVector.class)
      .applyEntity(product)
      .executeSumResult();

// 查询并获取向量
ProductVector loaded = lambda.query(ProductVector.class)
      .eq(ProductVector::getId, 1)
      .queryForObject();

List<Float> embedding = loaded.getEmbedding();
// [0.1, 0.2, 0.3]

KNN 相似性检索

dbVisitor 的 Fluent API 原生支持向量排序方法:

java 复制代码
// 查询向量
List<Float> queryVector = Arrays.asList(0.15f, 0.25f, 0.35f);

// L2 距离排序(欧氏距离)
List<ProductVector> nearest = lambda.query(ProductVector.class)
      .orderByL2("embedding", queryVector)  // 按 L2 距离升序
      .limit(5)
      .queryForList();

// 余弦相似度排序
List<ProductVector> similar = lambda.query(ProductVector.class)
      .orderByCosine("embedding", queryVector)
      .limit(5)
      .queryForList();

// 内积排序
List<ProductVector> ipResults = lambda.query(ProductVector.class)
      .orderByIP("embedding", queryVector)
      .limit(5)
      .queryForList();

// 通用接口 --- 枚举驱动
List<ProductVector> results = lambda.query(ProductVector.class)
      .orderByMetric("embedding", queryVector, VectorMetric.L2)
      .limit(10)
      .queryForList();

向量 + 标量联合查询

java 复制代码
// 在价格范围内搜索最相似的商品
List<ProductVector> results = lambda.query(ProductVector.class)
      .between("price", 100, 500)
      .eq("category", "electronics")
      .orderByL2("embedding", queryVector)
      .limit(10)
      .queryForList();

实现原理

PgVectorTypeHandler 的实现非常简洁:

  • 写入 :将 List<Float> 序列化为 pgvector 文本格式 [0.1,0.2,0.3],以 Types.OTHER 传入 PreparedStatement
  • 读取 :将 pgvector 返回的字符串 [0.1,0.2,0.3] 解析为 List<Float>
java 复制代码
// 写入
ps.setObject(i, "[0.1,0.2,0.3]", Types.OTHER);

// 读取
String val = rs.getString(columnName);  // "[0.1,0.2,0.3]"
List<Float> vector = parseVector(val);  // [0.1f, 0.2f, 0.3f]

这种基于文本格式的方案与 pgvector 的官方协议一致,不依赖任何额外的 Java 客户端库。

相关推荐
9i编程1 分钟前
9. 教 AI 上班:带出我的数字同事 —— 部署到本机再大回归:组织架构又错,被我叫停先改树
人工智能·openai·ai编程
遇码3 分钟前
system prompt 里拼了时间和知识大纲,每轮缓存都被击穿:静态/动态分离的提示词装配方法
人工智能·ai·大模型
a93207 分钟前
基准真值也会错:我的 AI 审计管线漏报 12 题,先别急着调模型
人工智能
俊哥V7 分钟前
每日 AI 研究简报 · 2026-10-10
人工智能·ai
程序人生8889 分钟前
PDF 转 Word 版式错乱、表格丢失?DocConverter Web 格式互转引擎的保真实践
前端·人工智能·opencv·机器学习·pdf·word
我不会插花弄玉11 分钟前
4.string类型【由浅入深-redis】
数据库·redis·缓存
Dawson Zhu13 分钟前
《Agentic Design Patterns》第 8 章导读:记忆管理(Memory Management)
人工智能·语言模型·架构·aigc·agi
m4Rk_14 分钟前
【论文阅读】Agent 记忆机制(96):M3-Agent——让 Agent 从视听经历中持续形成情景与语义长期记忆
论文阅读·人工智能·学习·开源·github
PHP实战开发录19 分钟前
MySQL数字排序为什么乱
数据库·mysql·php
xiami_world24 分钟前
Xmind、Miro、博思白板AI怎么选?思维导图/流程图自动生成
人工智能·ai·信息可视化·流程图·xmind