package org.ssssssss.magicapi.modules.table; import org.apache.commons.lang3.StringUtils; import org.ssssssss.script.annotation.Comment; import org.ssssssss.script.functions.StreamExtension; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.Function; public class Where { private final List tokens = new ArrayList<>(); private final List params = new ArrayList<>(); private final NamedTable namedTable; private final boolean needWhere; public Where(NamedTable namedTable) { this(namedTable, true); } public Where(NamedTable namedTable, boolean needWhere) { this.namedTable = namedTable; this.needWhere = needWhere; } void appendAnd() { remove(); tokens.add("and"); } void appendOr() { remove(); tokens.add("or"); } List getParams() { return params; } void remove() { int size = tokens.size(); while (size > 0) { String token = tokens.get(size - 1); if ("and".equalsIgnoreCase(token) || "or".equalsIgnoreCase(token)) { tokens.remove(size - 1); size--; }else { break; } } while(size > 0){ String token = tokens.get(0); if ("and".equalsIgnoreCase(token) || "or".equalsIgnoreCase(token)) { tokens.remove(0); size--; }else { break; } } } boolean isEmpty() { return tokens.isEmpty(); } void append(String value) { tokens.add(value); } String getSql() { remove(); if (isEmpty()) { return ""; } return (needWhere ? " where " : "") + StringUtils.join(tokens, " "); } @Comment("等于`=`,如:`eq('name', '老王') ---> name = '老王'`") public Where eq(@Comment("数据库中的列名") String column, @Comment("值")Object value) { return eq(true, column, value); } @Comment("等于`=`,如:`eq('name', '老王') ---> name = '老王'`") public Where eq(@Comment("判断表达式,当为true时拼接条件") boolean condition, @Comment("数据库中的列名") String column, @Comment("值")Object value) { if (condition) { tokens.add(column); if (value == null) { append(" is null"); } else { params.add(value); append(" = ?"); } appendAnd(); } return this; } @Comment("不等于`<>`,如:`ne('name', '老王') ---> name <> '老王'`") public Where ne(@Comment("数据库中的列名") String column, @Comment("值")Object value) { return ne(true, column, value); } @Comment("不等于`<>`,如:`ne('name', '老王') ---> name <> '老王'`") public Where ne(@Comment("判断表达式,当为true时拼接条件") boolean condition, @Comment("数据库中的列名") String column, @Comment("值")Object value) { if (condition) { append(column); if (value == null) { append("is not null"); } else { params.add(value); append("<> ?"); } appendAnd(); } return this; } private Where append(boolean append, String column, String condition, Object value) { if (append) { append(column); append(condition); appendAnd(); params.add(value); } return this; } @Comment("小于`<`,如:`lt('age', 18) ---> age < 18") public Where lt(@Comment("数据库中的列名") String column, @Comment("值")Object value) { return lt(true, column, value); } @Comment("小于`<`,如:`lt('age', 18) ---> age < 18") public Where lt(@Comment("判断表达式,当为true时拼接条件") boolean condition, @Comment("数据库中的列名") String column, @Comment("值")Object value) { return append(condition, column, " < ?", value); } @Comment("小于等于`<=`,如:`lte('age', 18) ---> age <= 18") public Where lte(@Comment("数据库中的列名") String column, @Comment("值")Object value) { return lte(true, column, value); } @Comment("小于等于`<=`,如:`lte('age', 18) ---> age <= 18") public Where lte(@Comment("判断表达式,当为true时拼接条件") boolean condition, @Comment("数据库中的列名") String column, @Comment("值")Object value) { return append(condition, column, " <= ?", value); } @Comment("大于`>`,如:`get('age', 18) ---> age > 18") public Where gt(@Comment("数据库中的列名") String column, @Comment("值")Object value) { return gt(true, column, value); } @Comment("大于`>`,如:`get('age', 18) ---> age > 18") public Where gt(@Comment("判断表达式,当为true时拼接条件") boolean condition, @Comment("数据库中的列名") String column, @Comment("值")Object value) { return append(condition, column, " > ?", value); } @Comment("大于等于`>=`,如:`get('age', 18) ---> age >= 18") public Where gte(@Comment("数据库中的列名") String column, @Comment("值")Object value) { return gte(true, column, value); } @Comment("大于等于`>=`,如:`get('age', 18) ---> age >= 18") public Where gte(@Comment("判断表达式,当为true时拼接条件") boolean condition, @Comment("数据库中的列名") String column, @Comment("值")Object value) { return append(condition, column, " >= ?", value); } @Comment("`in`,如:`in('age', [1,2,3]) ---> age in (1,2,3)") public Where in(@Comment("数据库中的列名") String column, @Comment("值")Object value) { return in(true, column, value); } @Comment("`in`,如:`in('age', [1,2,3]) ---> age in (1,2,3)") public Where in(@Comment("判断表达式,当为true时拼接条件") boolean condition, @Comment("数据库中的列名") String column, @Comment("值")Object value) { if (condition && value != null) { List objects = StreamExtension.arrayLikeToList(value); if (objects.size() > 0) { append(column); append(" in ("); append(StringUtils.join(",", Collections.nCopies(objects.size(), "?"))); append(")"); appendAnd(); params.addAll(objects); } } return this; } @Comment("`not in`,如:`notIn('age', [1,2,3]) ---> age not in (1,2,3)") public Where notIn(@Comment("数据库中的列名") String column, @Comment("值")Object value) { return notIn(true, column, value); } @Comment("`not in`,如:`notIn('age', [1,2,3]) ---> age not in (1,2,3)") public Where notIn(@Comment("判断表达式,当为true时拼接条件") boolean condition, @Comment("数据库中的列名") String column, @Comment("值")Object value) { if (condition && value != null) { List objects = StreamExtension.arrayLikeToList(value); if (objects.size() > 0) { append(column); append("not in ("); append(StringUtils.join(",", Collections.nCopies(objects.size(), "?"))); append(")"); appendAnd(); params.addAll(objects); } } return this; } @Comment("`like`,如:`like('name', '%王%') ---> name like '%王%'") public Where like(@Comment("数据库中的列名") String column, @Comment("值")Object value) { return like(true, column, value); } @Comment("`like`,如:`like('name', '%王%') ---> name like '%王%'") public Where like(@Comment("判断表达式,当为true时拼接条件") boolean condition, @Comment("数据库中的列名") String column, @Comment("值")Object value) { return append(condition, column, "like ?", value); } @Comment("`not like`,如:`notLike('name', '%王%') ---> name not like '%王%'") public Where notLike(@Comment("数据库中的列名") String column, @Comment("值")Object value) { return notLike(true, column, value); } @Comment("`not like` ,如:`notLike('name', '%王%') ---> name not like '%王%'") public Where notLike(@Comment("判断表达式,当为true时拼接条件") boolean condition, @Comment("数据库中的列名") String column, @Comment("值")Object value) { return append(condition, column, "not like ?", value); } @Comment("`is null`,如:`isNull('name') ---> name is null") public Where isNull(@Comment("数据库中的列名") String column) { return isNull(true, column); } @Comment("`is null`,如:`isNull('name') ---> name is null") public Where isNull(@Comment("判断表达式,当为true时拼接条件") boolean condition, @Comment("数据库中的列名") String column) { if (condition) { append(column); append("is null"); appendAnd(); } return this; } @Comment("`is not null`,如:`isNotNull('name') ---> name is not null") public Where isNotNull(@Comment("数据库中的列名") String column) { return isNotNull(true, column); } @Comment("`is not null`,如:`isNotNull('name') ---> name is not null") public Where isNotNull(@Comment("判断表达式,当为true时拼接条件") boolean condition, @Comment("数据库中的列名") String column) { if (condition) { append(column); append("is not null"); appendAnd(); } return this; } @Comment("拼接`or`") public Where or() { appendOr(); return this; } @Comment("拼接`and`") public Where and() { appendAnd(); return this; } @Comment("`and`嵌套,如and(it => it.eq('name','李白').ne('status','正常') --> and (name = '李白' and status <> '正常')") public Where and(Function function) { return and(true, function); } @Comment("`and`嵌套,如and(it => it.eq('name','李白').ne('status','正常') --> and (name = '李白' and status <> '正常')") public Where and(@Comment("判断表达式,当为true时拼接条件") boolean condition, Function function) { if (condition) { Where expr = function.apply(new Object[]{new Where(this.namedTable, false)}); this.params.addAll(expr.params); append("("); append(expr.getSql()); append(")"); appendAnd(); } return this; } @Comment("保存到表中,当主键有值时则修改,否则插入") public Object save() { return namedTable.save(); } @Comment("保存到表中,当主键有值时则修改,否则插入") public Object save(@Comment("各项列和值") Map data) { return namedTable.save(data); } @Comment("执行插入语句,返回主键") public Object insert() { return namedTable.insert(); } @Comment("执行插入语句,返回主键") public Object insert(@Comment("各项列和值") Map data) { return namedTable.insert(data); } @Comment("执行update语句") public int update() { return namedTable.update(); } @Comment("执行update语句") public int update(@Comment("各项列和值") Map data) { return namedTable.update(data); } @Comment("执行分页查询") public Object page() { return namedTable.page(); } @Comment("执行select查询") public List> select() { return namedTable.select(); } @Comment("执行selectOne查询") public Map selectOne() { return namedTable.selectOne(); } }