Dynamic‑SQL2 查询篇:MyBatis 增强利器,让 SQL 像写 Java 一样丝滑
dynamic‑sql2 的查询能力设计目标: 写 SQL 要像写 Java 一样自然;复杂查询要像搭积木一样组合;结果映射要像操作集合一样顺滑。
本篇简述了:
- 基础查询
- 结果映射
- 分组 / Map / 分页
- Join / 子查询 / JSON 表
- 动态列引用
- 排序与 SQL 注入防御
- 忽略列
- 函数查询
- 正则匹配条件
- 动态库表名称(schema/table)机制
- 分页体系(dynamic‑sql2 / MyBatis / 逻辑分页)
引入依赖
截止至2026-01-21,最新版是0.1.8,项目地址:https://github.com/pengweizhong/dynamic-sql2
com.dynamic-sql
dynamic-sql2-spring-boot-starter
0.1.8
com.dynamic-sql
dynamic-sql2-spring-boot3-starter
0.1.8
在repository层注入SqlContext 增删改查都和此对象交互:
@Resource
private SqlContext sqlContext;
1. 基础查询与结果映射
1.1 查询列表
List list = sqlContext.select()
.allColumn()
.from(Product.class)
.fetch()
.toList();
1.2 查询单列(标量)
LocalDate one = sqlContext.select()
.column(Product::getCreatedAt)
.from(Product.class)
.limit(1)
.fetch(LocalDate.class)
.toOne();
1.3 查询单条记录
Product product = sqlContext.select()
.allColumn()
.from(Product.class)
.where(c -> c.andEqualTo(Product::getProductId, 7))
.fetch()
.toOne();
或使用主键快捷方式:
Product product2 = sqlContext.selectByPrimaryKey(Product.class, 7);
2. toList / toOne / toMap / toGroupingBy
2.1 分组 toGroupingBy
Map> groupingBy = sqlContext.select()
.distinct()
.allColumn()
.from(User.class)
.fetch()
.toGroupingBy(
User::getUserId,
user -> user.getName() + "_hello",
HashSet::new,
ConcurrentHashMap::new
);
2.2 分组(带 DTO)
LinkedHashMap> groupingBy = sqlContext.select()
.allColumn()
.from(User.class)
.limit(10)
.fetch(User.class)
.toGroupingBy(
User::getName,
User::getUserId,
HashSet::new,
LinkedHashMap::new
);
2.3 toMap(含重复 key 处理)
Map map = sqlContext.select()
.distinct()
.allColumn()
.from(User.class)
.fetch()
.toMap(
user -> 123,
user -> user.getName() + "_hello"
);
重复 key 会抛异常,可自定义合并策略:
.toMap(
ProductView::getProductName,
v -> v,
(v1, v2) -> v1
);
3. Join / 子查询 / JSON 表
3.1 多级 join + 别名 (自关联)
List
3.2 子查询 join
List
3.3 JSON 表展开(JsonTable)
List