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

发布于:2025-06-06 ⋅ 阅读:(25) ⋅ 点赞:(0)

📌 正文:

有时候我们项目底层是 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 版本 🚀