TK-Mybatis的Example的一些用法
TK-Mybatis的Example的一些用法
背景
最近项目中使用tk-mybatis遇到了一些问题:
问题详情:
(A=A1 and B=B1) or (A=A2 and B=B2) and C IN (C1,C2)
抽象一点:
A or B and C
实际执行方式为:
A or (B and C)
实际期望:
(A or B ) and C
代码
有问题的代码为:
List<Map<String, String>> properties = new ArrayList<>();
Example example = new Example(Country.class);
properties.forEach(map -> {
Example.Criteria criteria = example.createCriteria();
map.forEach((key, value) -> criteria.andEqualTo(key, value));
example.or(criteria);
});
Example.Criteria criteria = example.createCriteria()
.andIn("countryname", Arrays.asList("CN", "US", "UK"));
example.and(criteria);
CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
mapper.selectByExample(example);
最终生成的sql为:
(A=A1 and B=B1) or (A=A2 and B=B2) and C IN (C1,C2)
每个粗体代表一个criteria
很明显不符合预期
解决方案
只能手写sql进行组装
// 这里组装sql
String sql = properties.stream()
.map(map ->
map.entrySet()
.stream()
.map(item -> String.format("`%s` = '%s'", item.getKey(), item.getValue()))
.collect(Collectors.joining(" and ", " ( ", " ) "))
).collect(Collectors.joining(" or "));
//这里只有一个criteria 就可以避免问题
example.createCriteria().andCondition(sql);
//其他一样的
Example.Criteria criteria1 = example.createCriteria()
.andIn("countryname", Arrays.asList("CN", "US", "UK"));
example.and(criteria1);
CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
mapper.selectByExample(example);
生成sql为:
((A=A1 and B=B1) or (A=A2 and B=B2)) and C IN (C1,C2)
每个粗体代表一个criteria
核心解决方案
让OR语句生成一个criteria,之后就不会影响后续的步骤了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构