Browse Source

新增单表操作API

mxd 4 years ago
parent
commit
76d0705461

+ 12 - 4
src/main/java/org/ssssssss/magicapi/modules/BoundSql.java

@@ -35,6 +35,14 @@ public class BoundSql {
 
 	private long ttl;
 
+	public BoundSql(String sql, List<Object> parameters, SQLModule sqlModule) {
+		this.sql = sql;
+		this.parameters = parameters;
+		this.sqlCache = sqlModule.getSqlCache();
+		this.cacheName = sqlModule.getCacheName();
+		this.ttl = sqlModule.getTtl();
+	}
+
 	BoundSql(String sql) {
 		MagicScriptContext context = MagicScriptContext.get();
 		// 处理?{}参数
@@ -78,11 +86,11 @@ public class BoundSql {
 		this.sql = this.sql == null ? null : REPLACE_MULTI_WHITE_LINE.matcher(this.sql.trim()).replaceAll("\r\n");
 	}
 
-	BoundSql(String sql, SqlCache sqlCache, String cacheName, long ttl) {
+	BoundSql(String sql, SQLModule sqlModule) {
 		this(sql);
-		this.sqlCache = sqlCache;
-		this.cacheName = cacheName;
-		this.ttl = ttl;
+		this.sqlCache = sqlModule.getSqlCache();
+		this.cacheName = sqlModule.getCacheName();
+		this.ttl = sqlModule.getTtl();
 	}
 
 	private BoundSql() {

+ 0 - 205
src/main/java/org/ssssssss/magicapi/modules/NamedTable.java

@@ -1,205 +0,0 @@
-package org.ssssssss.magicapi.modules;
-
-import org.apache.commons.lang3.StringUtils;
-import org.ssssssss.magicapi.config.MagicDynamicDataSource.DataSourceNode;
-import org.ssssssss.magicapi.exception.MagicAPIException;
-import org.ssssssss.script.annotation.UnableCall;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class NamedTable {
-
-    @UnableCall
-    private String tableName;
-
-    @UnableCall
-	private DataSourceNode dataSourceNode;
-
-    @UnableCall
-    StringBuilder sqlBuilder;
-
-    @UnableCall
-    String primary;
-
-    @UnableCall
-    Map<String,Object> params = new HashMap<>();
-
-    @UnableCall
-    List<Where> wheres = new ArrayList<>();
-
-    public NamedTable(){
-
-    }
-
-    public NamedTable(String tableName, DataSourceNode dataSourceNode){
-        this.tableName = tableName;
-        this.dataSourceNode = dataSourceNode;
-    }
-
-    public NamedTable primary(String primary){
-        this.primary = primary;
-        return this;
-    }
-
-    public NamedTable column(String key,Object value){
-        this.params.put(key,value);
-        return this;
-    }
-
-    public int insert(Map<String,Object> data){
-        this.params.putAll(data);
-        if(this.params.size() == 0){
-            throw new MagicAPIException("参数不能为空");
-        }
-        try {
-            List<Object> values = new ArrayList<>();
-            List<String> fields = new ArrayList<>();
-            List<String> valuePlaceholders = new ArrayList<>();
-            StringBuffer sb = new StringBuffer();
-            sb.append("insert into ");
-            sb.append(tableName);
-            for(Map.Entry<String, Object> entry : this.params.entrySet()){
-                String key = entry.getKey();
-                fields.add(key);
-                valuePlaceholders.add("?");
-                values.add(entry.getValue());
-            }
-            sb.append("("+ StringUtils.join(fields,",") +")");
-            sb.append(" values("+StringUtils.join(valuePlaceholders,",")+")");
-            return dataSourceNode.getJdbcTemplate().update(sb.toString(),values.toArray());
-        }catch (Exception e){
-            throw new MagicAPIException("执行插入报错:"+e.getMessage());
-        }
-    }
-
-    public int update(){
-        return update(null);
-    }
-
-    public int update(Map<String,Object> data){
-        if(null != data){
-            this.params.putAll(data);
-        }
-        if((null != this.primary && !"".equals(this.primary)) || (null != wheres && wheres.size() != 0)){
-            if(this.params.size() == 0){
-                throw new MagicAPIException("参数不能为空");
-            }
-            try {
-                Map<String, Object> wheresMap = buildWheres();
-                String whereSql = (null == wheresMap.get("where")) ? "" : wheresMap.get("where").toString();
-                StringBuffer sb = new StringBuffer();
-                sb.append("update ");
-                sb.append(tableName);
-                sb.append(" set ");
-                List<Object> params = new ArrayList<>();
-                for(Map.Entry<String, Object> entry : this.params.entrySet()){
-                    String key = entry.getKey();
-                    if(StringUtils.isNotBlank(whereSql)){
-                        sb.append(key + "=" + "?,");
-                        params.add(entry.getValue());
-                    }else{
-                        if(!key.equals(this.primary)){
-                            sb.append(key + "=" + "?,");
-                            params.add(entry.getValue());
-                        }
-                    }
-                }
-                if(StringUtils.isNotBlank(whereSql)){
-                    sb.append(whereSql);
-                    List<Object> values = (List<Object>) wheresMap.get("values");
-                    params.addAll(values);
-                }else{
-                    String primaryValue = this.params.get(this.primary).toString();
-                    if(StringUtils.isBlank(primaryValue)){
-                        throw new MagicAPIException("主键值不能为空");
-                    }
-                    sb.append(" where ");
-                    sb.append(this.primary);
-                    sb.append("=?");
-                    params.add(primaryValue);
-                }
-                return dataSourceNode.getJdbcTemplate().update(sb.toString().replace("?, ","? "),params.toArray());
-            }catch (Exception e){
-                throw new MagicAPIException("执行更新报错:"+e.getMessage());
-            }
-        }else{
-            throw new MagicAPIException("设置主键或者设置条件");
-        }
-    }
-
-    public Map<String,Object> buildWheres(){
-        List<Object> values = new ArrayList<>();
-        StringBuilder sb = new StringBuilder();
-        sb.append(" where 1=1 ");
-        for(Where where : wheres){
-            String relation = where.getRelation();
-            String column = where.getColumn();
-            Object value = where.getValue();
-            relation = relation.equals("eq") ? "=" : relation;
-            sb.append(" and ");
-            sb.append(column);
-            sb.append(relation);
-            sb.append("?");
-            values.add(value);
-        }
-        Map<String,Object> map = new HashMap<>();
-        map.put("values",values);
-        map.put("where", sb.toString());
-        return map;
-    }
-
-    public NamedTable eq(String key,Object value){
-        wheres.add(new Where(Where.EQ,key,value));
-        return this;
-    }
-
-    public class Where{
-
-        public static final String EQ = "eq";
-
-        private String relation;
-
-        private String column;
-
-	    private Object value;
-
-	    public Where(){
-
-        }
-
-        public Where(String relation,String column,Object value){
-	        this.relation = relation;
-	        this.column = column;
-	        this.value = value;
-        }
-
-        public String getRelation() {
-            return relation;
-        }
-
-        public void setRelation(String relation) {
-            this.relation = relation;
-        }
-
-        public String getColumn() {
-            return column;
-        }
-
-        public void setColumn(String column) {
-            this.column = column;
-        }
-
-        public Object getValue() {
-            return value;
-        }
-
-        public void setValue(Object value) {
-            this.value = value;
-        }
-
-    }
-
-}

+ 44 - 10
src/main/java/org/ssssssss/magicapi/modules/SQLModule.java

@@ -13,6 +13,7 @@ import org.ssssssss.magicapi.config.MagicModule;
 import org.ssssssss.magicapi.dialect.Dialect;
 import org.ssssssss.magicapi.interceptor.SQLInterceptor;
 import org.ssssssss.magicapi.model.Page;
+import org.ssssssss.magicapi.modules.table.NamedTable;
 import org.ssssssss.magicapi.provider.PageProvider;
 import org.ssssssss.magicapi.provider.ResultProvider;
 import org.ssssssss.script.MagicScriptContext;
@@ -120,6 +121,18 @@ public class SQLModule extends HashMap<String, SQLModule> implements MagicModule
 		this.ttl = ttl;
 	}
 
+	protected String getCacheName() {
+		return cacheName;
+	}
+
+	protected long getTtl() {
+		return ttl;
+	}
+
+	protected SqlCache getSqlCache() {
+		return sqlCache;
+	}
+
 	@UnableCall
 	private SQLModule cloneSQLModule() {
 		SQLModule sqlModule = new SQLModule();
@@ -243,7 +256,11 @@ public class SQLModule extends HashMap<String, SQLModule> implements MagicModule
 	 */
 	@Comment("查询SQL,返回List类型结果")
 	public List<Map<String, Object>> select(@Comment("`SQL`语句") String sql) {
-		BoundSql boundSql = new BoundSql(sql, this.sqlCache, this.cacheName, this.ttl);
+		return select(new BoundSql(sql, this));
+	}
+
+	@UnableCall
+	public List<Map<String, Object>> select(BoundSql boundSql) {
 		return boundSql.getCacheValue(this.sqlInterceptors, () -> dataSourceNode.getJdbcTemplate().query(boundSql.getSql(), this.columnMapRowMapper, boundSql.getParameters()));
 	}
 
@@ -252,7 +269,11 @@ public class SQLModule extends HashMap<String, SQLModule> implements MagicModule
 	 */
 	@Comment("执行update操作,返回受影响行数")
 	public int update(@Comment("`SQL`语句") String sql) {
-		BoundSql boundSql = new BoundSql(sql);
+		return update(new BoundSql(sql));
+	}
+
+	@UnableCall
+	public int update(BoundSql boundSql) {
 		sqlInterceptors.forEach(sqlInterceptor -> sqlInterceptor.preHandle(boundSql));
 		int value = dataSourceNode.getJdbcTemplate().update(boundSql.getSql(), boundSql.getParameters());
 		if (this.cacheName != null) {
@@ -289,8 +310,7 @@ public class SQLModule extends HashMap<String, SQLModule> implements MagicModule
 	 */
 	@Comment("执行分页查询,分页条件自动获取")
 	public Object page(@Comment("`SQL`语句") String sql) {
-		Page page = pageProvider.getPage(MagicScriptContext.get());
-		return page(sql, page.getLimit(), page.getOffset());
+		return page(new BoundSql(sql, this));
 	}
 
 	/**
@@ -298,7 +318,17 @@ public class SQLModule extends HashMap<String, SQLModule> implements MagicModule
 	 */
 	@Comment("执行分页查询,分页条件手动传入")
 	public Object page(@Comment("`SQL`语句") String sql, @Comment("限制条数") long limit, @Comment("跳过条数") long offset) {
-		BoundSql boundSql = new BoundSql(sql, this.sqlCache, this.cacheName, this.ttl);
+		BoundSql boundSql = new BoundSql(sql, this);
+		return page(boundSql, limit, offset);
+	}
+
+	@UnableCall
+	public Object page(BoundSql boundSql) {
+		Page page = pageProvider.getPage(MagicScriptContext.get());
+		return page(boundSql, page.getLimit(), page.getOffset());
+	}
+
+	private Object page(BoundSql boundSql, long limit, long offset) {
 		Dialect dialect = dataSourceNode.getDialect(dialectAdapter);
 		BoundSql countBoundSql = boundSql.copy(dialect.getCountSql(boundSql.getSql()));
 		int count = countBoundSql.getCacheValue(this.sqlInterceptors, () -> dataSourceNode.getJdbcTemplate().queryForObject(countBoundSql.getSql(), Integer.class, countBoundSql.getParameters()));
@@ -316,7 +346,7 @@ public class SQLModule extends HashMap<String, SQLModule> implements MagicModule
 	 */
 	@Comment("查询int值,适合单行单列int的结果")
 	public Integer selectInt(@Comment("`SQL`语句") String sql) {
-		BoundSql boundSql = new BoundSql(sql, this.sqlCache, this.cacheName, this.ttl);
+		BoundSql boundSql = new BoundSql(sql, this);
 		return boundSql.getCacheValue(this.sqlInterceptors, () -> dataSourceNode.getJdbcTemplate().queryForObject(boundSql.getSql(), boundSql.getParameters(), Integer.class));
 	}
 
@@ -325,7 +355,11 @@ public class SQLModule extends HashMap<String, SQLModule> implements MagicModule
 	 */
 	@Comment("查询单条结果,查不到返回null")
 	public Map<String, Object> selectOne(@Comment("`SQL`语句") String sql) {
-		BoundSql boundSql = new BoundSql(sql, this.sqlCache, this.cacheName, this.ttl);
+		return selectOne(new BoundSql(sql, this));
+	}
+
+	@UnableCall
+	public Map<String, Object> selectOne(BoundSql boundSql) {
 		return boundSql.getCacheValue(this.sqlInterceptors, () -> {
 			List<Map<String, Object>> list = dataSourceNode.getJdbcTemplate().query(boundSql.getSql(), this.columnMapRowMapper, boundSql.getParameters());
 			return list.size() > 0 ? list.get(0) : null;
@@ -337,13 +371,13 @@ public class SQLModule extends HashMap<String, SQLModule> implements MagicModule
 	 */
 	@Comment("查询单行单列的值")
 	public Object selectValue(@Comment("`SQL`语句") String sql) {
-		BoundSql boundSql = new BoundSql(sql, this.sqlCache, this.cacheName, this.ttl);
+		BoundSql boundSql = new BoundSql(sql, this);
 		return boundSql.getCacheValue(this.sqlInterceptors, () -> dataSourceNode.getJdbcTemplate().queryForObject(boundSql.getSql(), boundSql.getParameters(), Object.class));
 	}
 
-	@Comment("指定table,进行一系列操作")
+	@Comment("指定table,进行单表操作")
 	public NamedTable table(String tableName) {
-		return new NamedTable(tableName, this.dataSourceNode);
+		return new NamedTable(tableName, this);
 	}
 
 	@UnableCall

+ 185 - 0
src/main/java/org/ssssssss/magicapi/modules/table/NamedTable.java

@@ -0,0 +1,185 @@
+package org.ssssssss.magicapi.modules.table;
+
+import org.apache.commons.lang3.StringUtils;
+import org.ssssssss.magicapi.exception.MagicAPIException;
+import org.ssssssss.magicapi.modules.BoundSql;
+import org.ssssssss.magicapi.modules.SQLModule;
+import org.ssssssss.script.annotation.Comment;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class NamedTable {
+
+	String tableName;
+
+	SQLModule sqlModule;
+
+	String primary;
+
+	Map<String, Object> columns = new HashMap<>();
+
+	List<String> fields = new ArrayList<>();
+
+	Where where = new Where(this);
+
+	public NamedTable(String tableName, SQLModule sqlModule) {
+		this.tableName = tableName;
+		this.sqlModule = sqlModule;
+	}
+
+	@Comment("设置主键名,update时使用")
+	public NamedTable primary(String primary) {
+		this.primary = primary;
+		return this;
+	}
+
+	@Comment("拼接where")
+	public Where where() {
+		return where;
+	}
+
+	@Comment("设置单列的值")
+	public NamedTable column(@Comment("列名") String key, @Comment("值") Object value) {
+		this.columns.put(key, value);
+		return this;
+	}
+
+	@Comment("设置查询的列,如`columns('a','b','c')`")
+	public NamedTable columns(@Comment("各项列") String... columns) {
+		if (columns != null) {
+			for (String column : columns) {
+				column(column);
+			}
+		}
+		return this;
+	}
+
+	@Comment("设置查询的列,如`columns(['a','b','c'])`")
+	public NamedTable columns(Collection<String> columns) {
+		if (columns != null) {
+			columns.stream().filter(StringUtils::isNotBlank).forEach(this.fields::add);
+		}
+		return this;
+	}
+
+	@Comment("设置查询的列,如`column('a')`")
+	public NamedTable column(String column) {
+		if (StringUtils.isNotBlank(column)) {
+			this.fields.add(column);
+		}
+		return this;
+	}
+
+	private List<Map.Entry<String, Object>> filterNotBlanks() {
+		return this.columns.entrySet().stream()
+				.filter(it -> StringUtils.isNotBlank(Objects.toString(it.getValue(), "")))
+				.collect(Collectors.toList());
+	}
+
+	@Comment("执行插入")
+	public int insert() {
+		return insert(null);
+	}
+
+	@Comment("执行插入")
+	public int insert(@Comment("各项列和值") Map<String, Object> data) {
+		if (data != null) {
+			this.columns.putAll(data);
+		}
+		List<Map.Entry<String, Object>> entries = filterNotBlanks();
+		if (entries.isEmpty()) {
+			throw new MagicAPIException("参数不能为空");
+		}
+		StringBuilder builder = new StringBuilder();
+		builder.append("insert into ");
+		builder.append(tableName);
+		builder.append("(");
+		builder.append(StringUtils.join(entries.stream().map(Map.Entry::getKey).toArray(), ","));
+		builder.append(") values (");
+		builder.append(StringUtils.join(Collections.nCopies(entries.size(), "?"), ","));
+		return sqlModule.update(new BoundSql(builder.toString(), entries.stream().map(Map.Entry::getValue).collect(Collectors.toList()), sqlModule));
+	}
+
+	@Comment("保存到表中,当主键有值时则修改,否则插入")
+	public int save() {
+		return this.save(null);
+	}
+
+	@Comment("保存到表中,当主键有值时则修改,否则插入")
+	public int save(@Comment("各项列和值") Map<String, Object> data) {
+		if (StringUtils.isBlank(this.primary)) {
+			throw new MagicAPIException("请设置主键");
+		}
+		if (this.columns.containsKey(this.primary) || (data != null && data.containsKey(this.primary))) {
+			return update(data);
+		}
+		return insert(data);
+	}
+
+
+	@Comment("执行`select`查询")
+	public List<Map<String, Object>> select() {
+		return sqlModule.select(buildSelect());
+	}
+
+	@Comment("执行`selectOne`查询")
+	public Map<String, Object> selectOne() {
+		return sqlModule.selectOne(buildSelect());
+	}
+
+	private BoundSql buildSelect() {
+		StringBuilder builder = new StringBuilder();
+		builder.append("select ");
+		if (this.fields.isEmpty()) {
+			builder.append("*");
+		} else {
+			builder.append(StringUtils.join(this.fields, ","));
+		}
+		builder.append(" from ").append(tableName);
+		List<Object> params = new ArrayList<>();
+		if (!where.isEmpty()) {
+			builder.append(where.getSql());
+			params.addAll(where.getParams());
+		}
+		return new BoundSql(builder.toString(), params, sqlModule);
+	}
+
+	@Comment("执行分页查询")
+	public Object page() {
+		return sqlModule.page(buildSelect());
+	}
+
+	@Comment("执行update语句")
+	public int update() {
+		return update(null);
+	}
+
+	@Comment("执行update语句")
+	public int update(@Comment("各项列和值") Map<String, Object> data) {
+		if (null != data) {
+			this.columns.putAll(data);
+		}
+		if (StringUtils.isNotBlank(this.primary)) {
+			this.columns.remove(this.primary);
+		}
+		List<Map.Entry<String, Object>> entries = filterNotBlanks();
+		if (entries.isEmpty()) {
+			throw new MagicAPIException("要修改的列不能为空");
+		}
+		StringBuilder builder = new StringBuilder();
+		builder.append("update ");
+		builder.append(tableName);
+		builder.append(" set ");
+		List<Object> params = new ArrayList<>();
+		for (Map.Entry<String, Object> entry : entries) {
+			builder.append(entry.getKey()).append(" = ?");
+			params.add(entry.getValue());
+		}
+		if (!where.isEmpty()) {
+			builder.append(where.getSql());
+			params.addAll(where.getParams());
+		}
+		return sqlModule.update(new BoundSql(builder.toString(), params, sqlModule));
+	}
+}

+ 341 - 0
src/main/java/org/ssssssss/magicapi/modules/table/Where.java

@@ -0,0 +1,341 @@
+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<String> tokens = new ArrayList<>();
+
+	private final List<Object> 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<Object> 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<Object> 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<Object> 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<Object[], Where> 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<Object[], Where> 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 int save() {
+		return namedTable.save();
+	}
+
+	@Comment("保存到表中,当主键有值时则修改,否则插入")
+	public int save(@Comment("各项列和值") Map<String, Object> data) {
+		return namedTable.save(data);
+	}
+
+	@Comment("执行插入语句")
+	public int insert() {
+		return namedTable.insert();
+	}
+
+	@Comment("执行插入语句")
+	public int insert(@Comment("各项列和值") Map<String, Object> data) {
+		return namedTable.insert(data);
+	}
+
+	@Comment("执行update语句")
+	public int update() {
+		return namedTable.update();
+	}
+
+	@Comment("执行update语句")
+	public int update(@Comment("各项列和值") Map<String, Object> data) {
+		return namedTable.update(data);
+	}
+
+	@Comment("执行分页查询")
+	public Object page() {
+		return namedTable.page();
+	}
+
+	@Comment("执行select查询")
+	public List<Map<String, Object>> select() {
+		return namedTable.select();
+	}
+
+	@Comment("执行selectOne查询")
+	public Map<String, Object> selectOne() {
+		return namedTable.selectOne();
+	}
+
+}