📌 正文:
有时候我们项目底层是 JdbcTemplate
查询,没法像 MyBatisPlus 一样用 Wrapper
拼接条件,但我们又不想手撸字符串。那怎么办?我今天就给你整了个 SqlBuilder 工具类,支持 eq
、ne
、like
、in
、gt
、lt
、orderBy
、limit
,像 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
写法
📌 铁子们,点赞、收藏、转发,别白嫖!
有需要的直接拿走用,或者留言,我帮你继续扩展功能版本,比如 between
、or
、groupBy
、having
版本 🚀