当前位置: 首页 > 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 版本 🚀


相关文章:

  • 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 进行冲击性能分析
  • 十.显式类型转换
  • 太阳敏感器:卫星姿态控制的“指南针
  • wordpress模板站/网站设计服务企业
  • 商会网站的建设/营销云
  • 离退休干部网站建设/无锡百度快速优化排名
  • 网站更换服务器要重新备案吗/旅游网络营销的渠道有哪些
  • 携程网网站做的怎么样/windows10优化工具
  • 新疆建设兵团职改办网站/seo产品推广