dbVisitor 利用 queryForPairs 让键值查询一步到位

在日常开发中,"查两列,组成 Map"是一个高频操作:ID 到名称的映射、编码到描述的映射、配置键到值的映射...... 以往你需要查出列表再手动遍历构建 Map。

dbVisitor 6.7.0 新增的 queryForPairs 方法,一行代码直接拿到 Map<K, V>

痛点:重复的样板代码

之前的写法:

java 复制代码
// 查出 ID → Name 映射
List<UserInfo> users = lambda.query(UserInfo.class)
      .between(UserInfo::getId, 1001, 1003)
      .queryForList();

Map<Integer, String> idToName = new LinkedHashMap<>();
for (UserInfo u : users) {
    idToName.put(u.getId(), u.getName());
}

先查列表,再遍历填充。如果只需要两列数据,却要查出整个实体,浪费资源。

新写法:一行搞定

Fluent API --- Lambda 方式

java 复制代码
Map<Integer, String> idToName = lambda.query(UserInfo.class)
      .between(UserInfo::getId, 1001, 1003)
      .queryForPairs(UserInfo::getId, UserInfo::getName, Integer.class, String.class);

// {1001="Alice", 1002="Bob", 1003="Charlie"}

框架自动将 SELECT 收窄为指定的两列,然后将第一列作为 Key、第二列作为 Value 构建 Map

Fluent API --- 字符串方式

java 复制代码
Map<Integer, String> idToName = lambda.query(UserInfo.class)
      .between("id", 1001, 1003)
      .queryForPairs("id", "name", Integer.class, String.class);

JdbcTemplate --- 原生 SQL

queryForPairs 同时下沉到了 JdbcTemplate 层,支持多种参数传递方式:

java 复制代码
// 1. 无参数
Map<Integer, String> result = jdbcTemplate.queryForPairs(
    "SELECT id, name FROM user_info WHERE id BETWEEN 1001 AND 1003",
    Integer.class, String.class
);

// 2. 位置参数
Map<String, Integer> nameToAge = jdbcTemplate.queryForPairs(
    "SELECT name, age FROM user_info WHERE id >= ? AND id <= ?",
    String.class, Integer.class,
    new Object[] { 1001, 1003 }
);

// 3. 命名参数
Map<String, Object> params = new HashMap<>();
params.put("minId", 1001);
params.put("maxId", 1003);

Map<Integer, String> idToEmail = jdbcTemplate.queryForPairs(
    "SELECT id, email FROM user_info WHERE id >= :minId AND id <= :maxId",
    Integer.class, String.class,
    params
);

设计细节

自动类型转换

queryForPairs 内部使用 PairsResultSetExtractor,根据指定的 Key/Value 类型自动选择对应的 TypeHandler 进行类型转换:

java 复制代码
// Long Key + Date Value --- 自动处理类型转换
Map<Long, Date> idToDate = jdbcTemplate.queryForPairs(
    "SELECT CAST(id AS BIGINT), create_time FROM user_info",
    Long.class, Date.class
);

单列场景

如果 SELECT 只有一列,Value 自动为 null

java 复制代码
Map<Integer, Object> ids = jdbcTemplate.queryForPairs(
    "SELECT id FROM user_info",
    Integer.class, Object.class
);
// {1001=null, 1002=null, 1003=null}

Key 冲突

当多行的 Key 值相同时,后出现的值会覆盖先出现的,这与 Java 的 Map.put() 行为一致。

适用场景

  • 下拉选项加载SELECT code, label FROM dict_item WHERE type = ?

  • 批量 ID 转名称SELECT id, name FROM user WHERE id IN (...)

  • 配置读取SELECT key, value FROM app_config WHERE group = ?

  • 关联预查询:替代 N+1 查询中的关联表预加载

  • 项目首页:www.dbvisitor.net/

  • 项目源码:gitee.com/zycgit/dbvi...

  • 原文:www.dbvisitor.net/blog/v670-q...

相关推荐
xieliyu.31 分钟前
Java算法精讲:双指针(三)
java·开发语言·算法
love530love33 分钟前
LiveTalking 数字人项目 Windows 部署完全指南(EPGF 架构)
人工智能·windows·python·架构·livetalking·epgf
星辰徐哥44 分钟前
Spring Boot 微服务架构设计与实现
spring boot·后端·微服务
星辰徐哥44 分钟前
Spring Boot 数据导入导出与报表生成
spring boot·后端·ui
明夜之约1 小时前
Spring Boot 自动装配源码
java·spring boot·后端
Leaton Lee1 小时前
Spring Boot分层架构详解:从Controller到Service再到Mapper的完整流程
java·spring boot·后端·架构
Micro麦可乐1 小时前
Spring Boot 实战:从零设计一个短链系统(含完整代码与数据库设计)
数据库·spring boot·后端·哈希算法·雪花算法·短链系统
Jinkxs1 小时前
Resilience4j- 与 Spring Boot 快速集成:自动配置与基础注解使用
java·spring boot·后端
毕设源码_郑学姐1 小时前
计算机毕业设计springboot网络相册设计与实现 基于Spring Boot框架的在线相册管理系统开发与应用 Spring Boot驱动的网络影集设计与实践
spring boot·后端·课程设计
辣机小司1 小时前
【踩坑记录:Spring Boot 配置文件读取值不一致?警惕 YAML 的“八进制陷阱”与 SnakeYAML 版本之谜】
java·spring boot·后端·yaml·踩坑记录