当前位置: 首页 > news >正文

【Java实用工具类】手撸SqlBuilder工具类,优雅拼接动态SQL,MyBatisPlus同款风格!

📌 正文:

有时候我们项目底层是 JdbcTemplate 查询,没法像 MyBatisPlus 一样用 Wrapper 拼接条件,但我们又不想手撸字符串。那怎么办?我今天就给你整了个 SqlBuilder 工具类,支持 eqnelikeingtltorderBylimit,像 MyBatisPlus 一样链式调用,直接拼接最终 SQL!


📌 工具类源码:

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;/*** SQL 动态拼接工具类* <p>* 支持常用条件操作:eq(等于)、ne(不等于)、like(模糊匹配)、in(集合匹配)、gt(大于)、lt(小于),* 以及排序 orderBy 和结果数量限制 limit。* 采用链式调用方式,方便优雅地拼接 WHERE、ORDER BY、LIMIT 子句。* <p>* 示例:* <pre>* String sql = new SqlBuilder("SELECT * FROM user")*     .eq("status", 1)*     .like("name", "张三")*     .orderBy("create_time", false)*     .limit(10)*     .build();* </pre>* * @author lhj* @date 2025/06/03*/
public class SqlBuilder {private final String baseSql;  // 基础SQL语句,包含SELECT和FROM部分private final List<String> whereConditions = new ArrayList<>(); // 存放WHERE条件private String orderByClause = "";  // ORDER BY子句private String limitClause = "";    // LIMIT子句/*** 构造方法,传入基础SQL语句(通常包含SELECT和FROM)** @param baseSql 基础SQL语句*/public SqlBuilder(String baseSql) {this.baseSql = baseSql;}/*** 拼接等于条件* 仅当value不为空时,添加"column = 'value'"条件** @param column 列名* @param value  比较值* @return 当前SqlBuilder对象,支持链式调用*/public SqlBuilder eq(String column, Object value) {if (ObjectUtil.isNotEmpty(value)) {whereConditions.add(column + " = '" + value + "'");}return this;}/*** 拼接不等于条件* 仅当value不为空时,添加"column <> 'value'"条件** @param column 列名* @param value  比较值* @return 当前SqlBuilder对象,支持链式调用*/public SqlBuilder ne(String column, Object value) {if (ObjectUtil.isNotEmpty(value)) {whereConditions.add(column + " <> '" + value + "'");}return this;}/*** 拼接模糊匹配条件* 仅当value不为空时,添加"column LIKE '%value%'"条件** @param column 列名* @param value  模糊匹配的值* @return 当前SqlBuilder对象,支持链式调用*/public SqlBuilder like(String column, Object value) {if (ObjectUtil.isNotEmpty(value)) {whereConditions.add(column + " LIKE '%" + value + "%'");}return this;}/*** 拼接IN条件* 仅当values集合不为空时,添加"column IN ('value1','value2',...)"条件** @param column 列名* @param values 值集合* @return 当前SqlBuilder对象,支持链式调用*/public SqlBuilder in(String column, List<?> values) {if (CollUtil.isNotEmpty(values)) {String inValues = values.stream().map(v -> "'" + v + "'").collect(Collectors.joining(","));whereConditions.add(column + " IN (" + inValues + ")");}return this;}/*** 拼接大于条件* 仅当value不为空时,添加"column > 'value'"条件** @param column 列名* @param value  比较值* @return 当前SqlBuilder对象,支持链式调用*/public SqlBuilder gt(String column, Object value) {if (ObjectUtil.isNotEmpty(value)) {whereConditions.add(column + " > '" + value + "'");}return this;}/*** 拼接小于条件* 仅当value不为空时,添加"column < 'value'"条件** @param column 列名* @param value  比较值* @return 当前SqlBuilder对象,支持链式调用*/public SqlBuilder lt(String column, Object value) {if (ObjectUtil.isNotEmpty(value)) {whereConditions.add(column + " < '" + value + "'");}return this;}/*** 拼接排序子句* 仅当column不为空时,添加"ORDER BY column ASC|DESC"** @param column 排序字段* @param asc    是否升序(true升序,false降序)* @return 当前SqlBuilder对象,支持链式调用*/public SqlBuilder orderBy(String column, boolean asc) {if (ObjectUtil.isNotEmpty(column)) {orderByClause = " ORDER BY " + column + (asc ? " ASC" : " DESC");}return this;}/*** 拼接结果限制条数子句* 仅当size大于0时,添加"LIMIT size"** @param size 限制返回结果条数* @return 当前SqlBuilder对象,支持链式调用*/public SqlBuilder limit(int size) {if (size > 0) {limitClause = " LIMIT " + size;}return this;}/*** 构建最终完整SQL语句* 根据已拼接的条件、排序和限制,生成完整SQL字符串** @return 完整SQL字符串*/public String build() {StringBuilder finalSql = new StringBuilder(baseSql);if (!whereConditions.isEmpty()) {finalSql.append(" WHERE ").append(String.join(" AND ", whereConditions));}finalSql.append(orderByClause).append(limitClause);return finalSql.toString();}/*** 简单示例演示SqlBuilder用法*/public static void main(String[] args) {String sql = new SqlBuilder("SELECT * FROM user").eq("status", 1).eq("score", "") // 空字符串不拼接.like("name", "").in("type", Arrays.asList(1)).gt("create_time", "2024-01-01").orderBy("create_time", false).limit(50).build();System.out.println(sql);}
}

📌 使用效果:

控制台输出👇

SELECT * FROM user WHERE status = '1' AND type IN ('1') AND create_time > '2024-01-01' ORDER BY create_time DESC LIMIT 50

📌 总结:

✔️ 支持链式调用
✔️ 条件判空自动过滤
✔️ 格式统一规范
✔️ 灵感来自 MyBatisPlus 的 Wrapper 写法


📌 铁子们,点赞、收藏、转发,别白嫖!

有需要的直接拿走用,或者留言,我帮你继续扩展功能版本,比如 betweenorgroupByhaving 版本 🚀



文章转载自:

http://2izE0nvB.yqtry.cn
http://3jc16E1j.yqtry.cn
http://2oaAQCtZ.yqtry.cn
http://ZWxWAu4x.yqtry.cn
http://k8tNt7b0.yqtry.cn
http://uxtYschH.yqtry.cn
http://vRcDTVFc.yqtry.cn
http://srwN33AH.yqtry.cn
http://pgIxVeVZ.yqtry.cn
http://3cR9ZJd1.yqtry.cn
http://w2SV25fO.yqtry.cn
http://VuNJJLOf.yqtry.cn
http://b88ES417.yqtry.cn
http://JwVHupVl.yqtry.cn
http://0uKcQGib.yqtry.cn
http://0e0FRZAv.yqtry.cn
http://q6K4q8uD.yqtry.cn
http://6Gu4nQZb.yqtry.cn
http://suYlC6f1.yqtry.cn
http://TAjffmya.yqtry.cn
http://Fnvs0cX9.yqtry.cn
http://GbkodTGF.yqtry.cn
http://aqSgujh0.yqtry.cn
http://b4KsQsrv.yqtry.cn
http://KSZsuueh.yqtry.cn
http://7l02DAlr.yqtry.cn
http://WgcJiStr.yqtry.cn
http://Cy3wNUUK.yqtry.cn
http://Rdg3BeZp.yqtry.cn
http://L7B9vqUC.yqtry.cn
http://www.dtcms.com/a/228878.html

相关文章:

  • mybatis打印完整的SQL,p6spy
  • LeetCode 高频 SQL 50 题(基础版) 之 【高级查询和连接】· 下
  • SQL思路解析:窗口滑动的应用
  • 剑指offer15_数值的整数次方
  • JavaScript性能优化实战:从核心原理到工程实践的全流程解析
  • java反序列化:CC5利用链解析
  • 【Python进阶】装饰器
  • SpringBoot接入Kimi实践记录轻松上手
  • 九(5).引用和指针的区别
  • 基于大模型的短暂性脑缺血发作(TIA)全流程预测与诊疗辅助系统详细技术方案
  • UVa12298 Super Joker II
  • 手摸手还原vue3中reactive的get陷阱以及receiver的作用
  • 使用 C++/OpenCV 制作跳动的爱心动画
  • 实验设计与分析(第6版,Montgomery著,傅珏生译) 第10章拟合回归模型10.9节思考题10.1 R语言解题
  • OSCP备战-BSides-Vancouver-2018-Workshop靶机详细步骤
  • 软考 系统架构设计师系列知识点之杂项集萃(78)
  • 15个基于场景的 DevOps 面试问题及答案
  • Ansys Zemax | 手机镜头设计 - 第 4 部分:用 LS-DYNA 进行冲击性能分析
  • 十.显式类型转换
  • 太阳敏感器:卫星姿态控制的“指南针
  • 报表/报告组件(二)-实例与实现解释
  • java-spring
  • Linux下使用nmcli连接网络
  • Python 数据分析与可视化实战:从数据清洗到图表呈现
  • DApp 开发:开启去中心化应用新时代
  • IP查询与网络风险的关系
  • 基于 ThreadContext 封装多个“业务上下文类”以实现可复用、易拓展
  • PH热榜 | 2025-06-03
  • 从0到1认识EFK
  • MATLAB实战:四旋翼姿态控制仿真方案