📌 正文:
有時候我們項目底層是 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
版本 🚀