diff --git a/README.md b/README.md index 8ccabd6c92e3e4388367e9cb9896ec9fca48f9c0..a57e926d0bd1c374e179b0ab4d7a5de8713c3121 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,11 @@ com.gitee.qdbp qdbp-able - 5.2.25 + 5.3.0 com.gitee.qdbp qdbp-tools - 5.2.25 + 5.3.0 ``` \ No newline at end of file diff --git a/able/pom.xml b/able/pom.xml index 6438ce33afddf3e3352a4f7a3701857ba9fae099..60961fb17029b9eaa23df52207812103d2c0375e 100644 --- a/able/pom.xml +++ b/able/pom.xml @@ -9,7 +9,7 @@ qdbp-able - 5.2.25 + 5.3.0 jar ${project.artifactId} https://gitee.com/qdbp/qdbp-able/ diff --git a/able/src/main/java/com/gitee/qdbp/able/debug/Debugger.java b/able/src/main/java/com/gitee/qdbp/able/debug/Debugger.java index 324bb44a342e17a905d52549f4690c873c8cf6fc..f8915c688f2f3214335e42e19a50a75d888f8033 100644 --- a/able/src/main/java/com/gitee/qdbp/able/debug/Debugger.java +++ b/able/src/main/java/com/gitee/qdbp/able/debug/Debugger.java @@ -15,4 +15,9 @@ public interface Debugger { * @param args 占位符参数 */ void debug(String message, Object... args); + + public static interface Aware { + + void setDebugger(Debugger debugger); + } } diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/BizCondition.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/BizCondition.java new file mode 100644 index 0000000000000000000000000000000000000000..c8f098266ed8175cf3681b06005b60612362e3a2 --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/BizCondition.java @@ -0,0 +1,50 @@ +package com.gitee.qdbp.able.jdbc.condition; + +import com.gitee.qdbp.able.enums.LogicType; +import com.gitee.qdbp.able.enums.MatchType; +import com.gitee.qdbp.able.jdbc.base.DbCondition; +import com.gitee.qdbp.able.jdbc.base.LogicCondition; +import com.gitee.qdbp.able.jdbc.base.MatchCondition; +import com.gitee.qdbp.able.jdbc.base.WhereCondition; + +/** + * 自定义条件 + * + * @author zhaohuihua + * @version 20210613 + */ +public class BizCondition implements DbCondition, LogicCondition, MatchCondition { + + private final WhereCondition condition; + /** 逻辑联连类型: AND / OR **/ + private final LogicType logicType; + /** 匹配模式 **/ + private final MatchType matchType; + + public BizCondition(LogicType logicType, MatchType matchType, WhereCondition condition) { + this.condition = condition; + this.logicType = logicType; + this.matchType = matchType; + } + + public WhereCondition getWhereCondition() { + return condition; + } + + /** 逻辑联连类型: AND / OR **/ + @Override + public LogicType getLogicType() { + return logicType; + } + + /** 匹配模式 **/ + @Override + public MatchType getMatchType() { + return matchType; + } + + @Override + public boolean isEmpty() { + return condition == null ? true : condition.isEmpty(); + } +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbItems.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbItems.java index dade8910de7f97359ac9765965d0cfec3ca37212..c3c2ea96569a5788931594b2a5fb911d6a82ba9e 100644 --- a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbItems.java +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbItems.java @@ -18,17 +18,20 @@ abstract class DbItems implements DbConditions, Serializable { /** SerialVersionUID **/ private static final long serialVersionUID = 1L; - private List items = new ArrayList<>(); + private List items; /** 默认构造函数 **/ protected DbItems() { + this.items = new ArrayList<>(); } /** 带条件的构造函数 **/ - protected DbItems(List conditions) { - VerifyTools.requireNonNull(conditions, "conditions"); - this.items.clear(); - this.items.addAll(conditions); + protected DbItems(List conditions) { + this.items = conditions; + } + + protected List items() { + return this.items; } /** @@ -175,7 +178,7 @@ abstract class DbItems implements DbConditions, Serializable { * 根据字段名称替换条件 * * @param field 字段 - * @param int 被替换的次数 + * @param int 被替换的次数 */ protected int replace(DbField field) { VerifyTools.requireNotBlank(field, "field"); diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdate.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdate.java index 40e41c4db679e8adc5de5d1c4b24da4caa5011d3..eb662ea5a8cfa74c3dbfa7288d24c59281233eac 100644 --- a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdate.java +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdate.java @@ -11,14 +11,21 @@ import com.gitee.qdbp.tools.utils.VerifyTools; * 支持Set,Add,ToNull操作
*
     DbUpdate ud = new DbUpdate();
+    // 用户名修改为指定值
     // SQL> SET USER_NAME = :$1
-    ud.set("userName", "zhaohuihua"); // 用户名修改为指定值
+    ud.set("userName").to("zhaohuihua");
+    
+    // 会员积分增加100
     // SQL> SET MEMBER_SCORE = MEMBER_SCORE + :$1
-    ud.add("memberScore", +100); // 会员积分增加100
+    ud.set("memberScore").add(+100);
+    
+    // 会员积分减少100
     // SQL> SET MEMBER_SCORE = MEMBER_SCORE - :$1
-    ud.add("memberScore", -100); // 会员积分减少100
+    ud.set("memberScore").add(-100);
+    
+    // 用户状态修改为空
     // SQL> SET USER_STATE = NULL
-    ud.toNull("userState"); // 用户状态修改为空
+    ud.set("userState").toNull();
  * 
* * @author zhaohuihua @@ -29,22 +36,41 @@ public class DbUpdate extends DbItems implements Copyable { /** SerialVersionUID **/ private static final long serialVersionUID = 1L; - /** SET :fieldName = :fieldValue **/ - public DbUpdate set(String fieldName, Object fieldValue) { - this.put(fieldName, fieldValue); - return this; + public DbUpdateForFieldCore set(String fieldName) { + DbUpdateForStartCore start = new DbUpdateForStartCore<>(this, this); + return new DbUpdateForFieldCore<>(start, fieldName); } - /** SET :fieldName = :fieldName + :fieldValue **/ - public DbUpdate add(String fieldName, Object fieldValue) { - this.put("Add", fieldName, fieldValue); - return this; + /** + * 只有当判断条件为true时才添加查询条件 + * + * @param ifValue 判断条件 + * @return 返回后续流式操作对象 + */ + public DbUpdateForStartBase ifTrue(boolean ifValue) { + DbUpdateForStartCore start = new DbUpdateForStartCore<>(this, this); + return new DbUpdateForStartBase<>(start, ifValue ? SkipType.NONE : SkipType.SKIP); } - /** SET :fieldName = NULL **/ - public DbUpdate toNull(String fieldName) { - this.put("ToNull", fieldName, null); - return this; + /** + * 只有当目标值不为空时才添加查询条件 + * + * @param value 目标值 + * @return 返回后续流式操作对象 + */ + public DbUpdateForStartBase ifHasValue(Object value) { + DbUpdateForStartCore start = new DbUpdateForStartCore<>(this, this); + return new DbUpdateForStartBase<>(start, InnerUtils.isBlank(value) ? SkipType.SKIP : SkipType.NONE); + } + + /** + * 只有当字段值不为空时才添加查询条件 + * + * @return 返回后续流式操作对象 + */ + public DbUpdateForStartByField ifHasValue() { + DbUpdateForStartCore start = new DbUpdateForStartCore<>(this, this); + return new DbUpdateForStartByField<>(start, SkipType.BLANK_VALUE); } @Override diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateBase.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateBase.java new file mode 100644 index 0000000000000000000000000000000000000000..9ce946c85e13bfc6557254778dc29fcd2029576c --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateBase.java @@ -0,0 +1,22 @@ +package com.gitee.qdbp.able.jdbc.condition; + +/** + * 数据库更新条件容器 + * + * @author zhaohuihua + * @version 20210606 + */ +abstract class DbUpdateBase { + + protected T root; + protected DbItems items; + + protected DbUpdateBase(T root, DbItems items) { + this.root = root; + this.items = items; + } + + protected void put(String operate, String fieldName, Object fieldValue) { + this.items.put(operate, fieldName, fieldValue); + } +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateForFieldBase.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateForFieldBase.java new file mode 100644 index 0000000000000000000000000000000000000000..53a145d5c0852e34d2e40fb7b8acb1b3a3e20993 --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateForFieldBase.java @@ -0,0 +1,49 @@ +package com.gitee.qdbp.able.jdbc.condition; + +/** + * 数据库更新条件容器 + * + * @author zhaohuihua + * @version 20210606 + */ +public class DbUpdateForFieldBase extends DbUpdateBase { + + protected DbUpdateForStartCore start; + private SkipType skipType; + private String fieldName; + + protected DbUpdateForFieldBase(DbUpdateForStartCore start, SkipType skipType, String fieldName) { + super(start.root, start.items); + this.start = start; + this.skipType = skipType; + this.fieldName = fieldName; + } + + protected DbUpdateForStartCore on(String operate, Object fieldValue) { + if (skipType == SkipType.NONE || skipType == SkipType.BLANK_VALUE && !InnerUtils.isBlank(fieldValue)) { + this.put(operate, fieldName, fieldValue); + } + return start; + } + + /** SET fieldName = :fieldValue **/ + public DbUpdateForStartCore to(Object fieldValue) { + return this.on(null, fieldValue); + } + + /** SET fieldName = fieldName + :fieldValue **/ + public DbUpdateForStartCore add(Object fieldValue) { + return this.on("Add", fieldValue); + } + + /** + * 自定义条件 + * + * @param operate 操作符 + * @param fieldValue 字段值 + * @return 返回后续流式操作对象 + */ + public DbUpdateForStartCore when(String operate, Object fieldValue) { + return this.on(operate, fieldValue); + } +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateForFieldCore.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateForFieldCore.java new file mode 100644 index 0000000000000000000000000000000000000000..f310369f285c4edc49f6c669c4480d8c711a47a0 --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateForFieldCore.java @@ -0,0 +1,23 @@ +package com.gitee.qdbp.able.jdbc.condition; + +/** + * 数据库更新条件容器 + * + * @author zhaohuihua + * @version 20210606 + */ +public class DbUpdateForFieldCore extends DbUpdateForFieldBase { + + public DbUpdateForFieldCore(DbUpdateForStartCore start, String fieldName) { + super(start, SkipType.NONE, fieldName); + } + + protected DbUpdateForFieldCore(DbUpdateForStartCore start, SkipType skipType, String fieldName) { + super(start, skipType, fieldName); + } + + /** SET :fieldName = NULL **/ + public DbUpdateForStartCore toNull() { + return this.on("ToNull", null); + } +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateForStartBase.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateForStartBase.java new file mode 100644 index 0000000000000000000000000000000000000000..a7ab339d959ad9d22764d88ae3553be71c549eff --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateForStartBase.java @@ -0,0 +1,24 @@ +package com.gitee.qdbp.able.jdbc.condition; + +/** + * 数据库Update条件容器 + * + * @author zhaohuihua + * @version 181221 + */ +public class DbUpdateForStartBase extends DbUpdateBase { + + private DbUpdateForStartCore start; + protected SkipType skipType; + + protected DbUpdateForStartBase(DbUpdateForStartCore start, SkipType skipType) { + super(start.root, start.items); + this.start = start; + this.skipType = skipType; + } + + public DbUpdateForFieldCore set(String fieldName) { + return new DbUpdateForFieldCore<>(start, skipType, fieldName); + } + +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateForStartByField.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateForStartByField.java new file mode 100644 index 0000000000000000000000000000000000000000..7ce2367a670ce4780cdff6aa4424710c9fdcb9d7 --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateForStartByField.java @@ -0,0 +1,24 @@ +package com.gitee.qdbp.able.jdbc.condition; + +/** + * 数据库Update条件容器 + * + * @author zhaohuihua + * @version 181221 + */ +public class DbUpdateForStartByField extends DbUpdateBase { + + private DbUpdateForStartCore start; + protected SkipType skipType; + + protected DbUpdateForStartByField(DbUpdateForStartCore start, SkipType skipType) { + super(start.root, start.items); + this.start = start; + this.skipType = skipType; + } + + public DbUpdateForFieldBase set(String fieldName) { + return new DbUpdateForFieldBase<>(start, skipType, fieldName); + } + +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateForStartCore.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateForStartCore.java new file mode 100644 index 0000000000000000000000000000000000000000..07c52b0f0222991d824e1c5f8dbf38715311d017 --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbUpdateForStartCore.java @@ -0,0 +1,51 @@ +package com.gitee.qdbp.able.jdbc.condition; + +/** + * 数据库Update条件容器 + * + * @author zhaohuihua + * @version 181221 + */ +public class DbUpdateForStartCore extends DbUpdateBase { + + public DbUpdateForStartCore(T root, DbItems items) { + super(root, items); + } + + public T end() { + return root; + } + + public DbUpdateForFieldCore set(String fieldName) { + return new DbUpdateForFieldCore<>(this, fieldName); + } + + /** + * 只有当判断条件为true时才添加查询条件 + * + * @param ifValue 判断条件 + * @return 返回后续流式操作对象 + */ + public DbUpdateForStartBase ifTrue(boolean ifValue) { + return new DbUpdateForStartBase(this, ifValue ? SkipType.NONE : SkipType.SKIP); + } + + /** + * 只有当目标值不为空时才添加查询条件 + * + * @param value 目标值 + * @return 返回后续流式操作对象 + */ + public DbUpdateForStartBase ifHasValue(Object value) { + return new DbUpdateForStartBase<>(this, InnerUtils.isBlank(value) ? SkipType.SKIP : SkipType.NONE); + } + + /** + * 只有当字段值不为空时才添加查询条件 + * + * @return 返回后续流式操作对象 + */ + public DbUpdateForStartByField ifHasValue() { + return new DbUpdateForStartByField<>(this, SkipType.BLANK_VALUE); + } +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhere.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhere.java index 59de92b9987a371d606df8f1f1213642b9242da2..d407bfca87588e3444e5597a715afc1a2422c5be 100644 --- a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhere.java +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhere.java @@ -1,16 +1,10 @@ package com.gitee.qdbp.able.jdbc.condition; -import java.util.Collection; import java.util.Iterator; import java.util.List; import com.gitee.qdbp.able.beans.Copyable; import com.gitee.qdbp.able.enums.LogicType; -import com.gitee.qdbp.able.enums.MatchType; import com.gitee.qdbp.able.jdbc.base.DbCondition; -import com.gitee.qdbp.able.jdbc.base.LogicCondition; -import com.gitee.qdbp.able.jdbc.base.MatchCondition; -import com.gitee.qdbp.able.jdbc.base.WhereCondition; -import com.gitee.qdbp.able.jdbc.model.LikeValue; import com.gitee.qdbp.tools.utils.VerifyTools; /** @@ -18,50 +12,50 @@ import com.gitee.qdbp.tools.utils.VerifyTools; *
     DbWhere where = new DbWhere();
     // [SQL] AND ID = :$1
-    where.andEquals("id", entity.getId());
+    where.on("id").equals(entity.getId());
     // [SQL] AND ID != :$1
-    where.andNotEquals("id", entity.getId());
+    where.on("id").notEquals(entity.getId());
     // [SQL] AND CREATE_TIME > :$1
-    where.andGreaterThen("createTime", new Date());
+    where.on("createTime").greaterThen(new Date());
     // [SQL] AND CREATE_TIME >= :$1
-    where.andGreaterEqualsThen("createTime", new Date());
+    where.on("createTime").greaterEqualsThen(new Date());
     // [SQL] AND CREATE_TIME < :$1
-    where.andLessThen("createTime", new Date());
+    where.on("createTime").lessThen(new Date());
     // [SQL] AND CREATE_TIME <= :$1
-    where.andLessEqualsThen("createTime", new Date());
+    where.on("createTime").lessEqualsThen(new Date());
     // [SQL] AND USER_STATE IS NULL
-    where.andIsNull("userState");
+    where.on("userState").isNull();
     // [SQL] AND USER_STATE IS NOT NULL
-    where.andIsNotNull("userState");
+    where.on("userState").isNotNull();
     // [ORACLE/DB2] AND USER_NAME LIKE('%'||:$1||'%')
     // [MYSQL] AND USER_NAME LIKE CONCAT('%',:$1,'%')
-    where.andLike("userName", entity.getUserName());
+    where.on("userName").like(entity.getUserName());
     // [ORACLE/DB2] AND USER_NAME NOT LIKE('%'||:$1||'%')
     // [MYSQL] AND USER_NAME NOT LIKE CONCAT('%',:$1,'%')
-    where.andNotLike("userName", entity.getUserName());
+    where.on("userName").notLkie(entity.getUserName());
     // [ORACLE/DB2] AND PHONE LIKE(:$1||'%')
     // [MYSQL] AND PHONE LIKE CONCAT(:$1,'%')
-    where.andStarts("phone", "139");
+    where.on("phone").startsWith("139");
     // [ORACLE/DB2] AND PHONE LIKE('%'||:$1)
     // [MYSQL] AND PHONE LIKE CONCAT('%',:$1)
-    where.andEnds("phone", "8888");
+    where.on("phone").endsWith("8888");
     // [SQL] AND USER_STATE IN (:$1, :$2, ...)
-    where.andIn("userState", UserState.NORMAL, UserState.LOCKED, ...);
+    where.on("userState").in(UserState.NORMAL, UserState.LOCKED, ...);
     // [SQL] AND USER_STATE NOT IN (:$1, :$2, ...)
-    where.andNotIn("userState", UserState.NORMAL, UserState.LOCKED, ...);
+    where.on("userState").notIn(UserState.NORMAL, UserState.LOCKED, ...);
     // [SQL] AND CREATE_TIME BETWEEN :$1 AND :$2
-    where.andBetween("createTime", entity.getStartTime(), entity.getEndTime());
+    where.on("createTime").between(entity.getStartTime(), entity.getEndTime());
     // [SQL] AND ( USER_NAME LIKE '%'||:$1||'%' OR REAL_NAME LIKE '%'||:$2||'%' )
-    where.andSubCondition(new SubCondition() { // 子条件
+    where.on().subCondition(new SubCondition() { // 子条件
         public void build(DbWhere w) {
-            w.orLike("userName", entity.getKeyword())
-                .orLike("realName", entity.getKeyword());
+            w.on("userName").like(entity.getKeyword())
+             .or("realName").like(entity.getKeyword());
         }
     });
     // JDK8
-    where.andSubCondition((w) -> { // 子条件
-        w.orLike("userName", entity.getKeyword())
-            .orLike("realName", entity.getKeyword());
+    where.on().subCondition((w) -> { // 子条件
+        w.on("userName").like(entity.getKeyword())
+         .or("realName").like(entity.getKeyword());
     });
  * 
* @@ -76,1664 +70,84 @@ public class DbWhere extends DbItems implements Copyable { /** 没有查询条件的空Where **/ public static final DbWhere NONE = new ReadonlyWhere(); - /** - * Where条件
- * 字段名可以带表别名, 如where.on("u.id", "=", entity.getId());
- * - * @param fieldName 字段名称 - * @param operate 目前支持如下操作:
- * =, !=, <, <=, >, >=,
- * Equals(equals), NotEquals(not equals),
- * LessThen(less then), LessEqualsThen(less equals then),
- * GreaterThen(greater then), GreaterEqualsThen(greater equals then),
- * IsNull(is null), IsNotNull(is not null),
- * Like(like), NotLike(not like),
- * Starts(starts), NotStarts(not starts), Ends(ends), NotEnds(not ends),
- * In(in), NotIn(not in), Between(between), NotBetween(not between) - * @param fieldValues 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere on(String fieldName, String operate, Object... fieldValues) { - return this.and(fieldName, operate, fieldValues); - } - - /** 增加自定义条件 **/ - public DbWhere on(WhereCondition condition) { - super.put(condition); - return this; - } - - /** - * AND查询条件 - * - * @param fieldName 字段名称 - * @param operate 操作符 - * @param fieldValues 字段值 - * @return 返回容器自身, 用于链式操作 - */ - protected DbWhere and(String fieldName, String operate, Object... fieldValues) { - DbField condition = parseField(LogicType.AND, fieldName, operate, fieldValues); - this.put(condition); - return this; - } - - /** - * OR查询条件 - * - * @param fieldName 字段名称 - * @param operate 操作符 - * @param fieldValues 字段值 - * @return 返回容器自身, 用于链式操作 - */ - protected DbWhere or(String fieldName, String operate, Object... fieldValues) { - DbField condition = parseField(LogicType.OR, fieldName, operate, fieldValues); - this.put(condition); - return this; - } - - /** - * AND查询条件 - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名称 - * @param operate 操作符 - * @param fieldValues 字段值 - * @return 返回容器自身, 用于链式操作 - */ - protected DbWhere andIf(boolean asserts, String fieldName, String operate, Object... fieldValues) { - if (asserts) { - DbField condition = parseField(LogicType.AND, fieldName, operate, fieldValues); - this.put(condition); - } - return this; - } - - /** - * OR查询条件 - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名称 - * @param operate 操作符 - * @param fieldValues 字段值 - * @return 返回容器自身, 用于链式操作 - */ - protected DbWhere orIf(boolean asserts, String fieldName, String operate, Object... fieldValues) { - if (asserts) { - DbField condition = parseField(LogicType.OR, fieldName, operate, fieldValues); - this.put(condition); - } - return this; - } - - /** - * 增加条件 - * - * @param condition 条件 - */ - @Override - protected void put(DbField condition) { - VerifyTools.requireNonNull(condition, "condition"); - if (condition instanceof Field) { - super.put(condition); - } else { - super.put(new Field(LogicType.AND, condition)); - } - } - - /** - * 增加条件 - * - * @param condition 自定义条件 - */ - @Override - protected void put(DbCondition condition) { - VerifyTools.requireNonNull(condition, "condition"); - if (condition instanceof Field) { - super.put(condition); - } else if (condition instanceof DbField) { - super.put(new Field(LogicType.AND, (DbField) condition)); - } else { - super.put(condition); - } - } - - protected Field parseField(LogicType logicType, String fieldName, String operate, Object... fieldValues) { - VerifyTools.nvl(fieldName, "fieldName"); - Field condition = new Field(logicType); - condition.setFieldName(fieldName); - condition.setOperateType(operate); - if (fieldValues != null && fieldValues.length > 0) { - if (fieldValues.length == 1) { - condition.setFieldValue(fieldValues[0]); - } else { - condition.setFieldValue(fieldValues); - } - } - return condition; - } - - /** - * 创建子查询条件 - * - * @param logicType 逻辑类型 AND/OR 这里指的是容器内部子条件项之间默认的连接类型 - * @return 子查询条件容器 - * @deprecated 这里的逻辑类型并不是此容器的连接类型
- * 而是容器内部子条件项之间使用on()方法时使用的连接类型, 不符合一般理解
- * 改为{@link #andSubCondition(SubCondition)}
- * {@link #andNotSubCondition(SubCondition)}
- * {@link #orSubCondition(SubCondition)}
- * {@link #orNotSubCondition(SubCondition)}
- */ - @Deprecated - public SubWhere sub(String logicType) { - return this.sub(logicType, true); - } - - /** - * 创建子查询条件容器 - * - * @param logicType 逻辑类型 AND/OR 这里指的是容器内部子条件项之间默认的连接类型 - * @param positive 匹配模式 肯定模式还是否定模式 - * @return 子查询条件容器 - * @deprecated 这里的逻辑类型并不是此容器的连接类型
- * 而是容器内部子条件项之间使用on()方法时使用的连接类型, 不符合一般理解
- * 改为{@link #andSubCondition(SubCondition)}
- * {@link #andNotSubCondition(SubCondition)}
- * {@link #orSubCondition(SubCondition)}
- * {@link #orNotSubCondition(SubCondition)}
- */ - @Deprecated - public SubWhere sub(String logicType, boolean positive) { - VerifyTools.nvl(logicType, "logicType"); - LogicType innerLogicType; - if ("AND".equalsIgnoreCase(logicType)) { - innerLogicType = LogicType.AND; - } else if ("OR".equalsIgnoreCase(logicType)) { - innerLogicType = LogicType.OR; - } else { - String msg = "Unsupported logic type: " + logicType + ". acceptable values are: 'AND', 'OR'."; - throw new IllegalArgumentException(msg); - } - MatchType matchType = positive ? MatchType.Positive : MatchType.Negative; - SubWhere sub = new InnerSubWhere(this, LogicType.AND, matchType, innerLogicType); - this.put(sub); - return sub; - } - - /** - * 克隆为新对象(如果子类有新增字段或没有默认构造函数就应该覆盖该方法) - * - * @return 新对象 - * @since 5.0.0 - */ - @Override - public DbWhere copy() { - DbWhere copies = newCopies(); - this.copyTo(copies); - return copies; - } - - protected void copyTo(DbWhere copies) { - Iterator iterator = this.iterator(); - while (iterator.hasNext()) { - DbCondition item = iterator.next(); - if (item instanceof Field) { - copies.put(((Field) item).copy()); - } else if (item instanceof DbField) { - copies.put(((DbField) item).copy()); - } else if (item instanceof SubWhere) { - copies.put(((SubWhere) item).copy().setParent(copies)); - } else if (item instanceof DbWhere) { - copies.put(((DbWhere) item).copy()); - } else if (item instanceof Copyable) { - DbCondition newer = (DbCondition) ((Copyable) item).copy(); - copies.put(newer); - } else { // DbCondition/DbConditions - copies.put(item); // 无法克隆为副本 - } - } - } - - /** - * 创建副本对象(如果子类没有默认构造函数就应该覆盖该方法) - * - * @return 副本对象 - * @since 5.0.0 - */ - protected DbWhere newCopies() { - if (this.getClass() == DbWhere.class) { // 当前类 - return new DbWhere(); - } else { // 子类 - try { - return this.getClass().newInstance(); - } catch (Exception e) { - throw new IllegalStateException("CloneNotSupported, FailedToInvokeDefaultConstructor."); - } - } - } - - /** - * 根据字段名称替换条件 - * - * @param fieldName 字段名称 - * @return 替换了几个条件 - */ - public int replace(String fieldName, String operate, Object... fieldValues) { - DbField condition = parseField(null, fieldName, operate, fieldValues); - int count = this.replace(condition); - if (count == 0) { - this.put(condition); - count++; - } - return count; - } - - /** - * 等于条件
- * [SQL] AND fieldName = fieldValue - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andEquals(String fieldName, Object fieldValue) { - return this.and(fieldName, "=", fieldValue); - } - - /** - * 不等于条件
- * [SQL] AND fieldName != fieldValue - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andNotEquals(String fieldName, Object fieldValue) { - return this.and(fieldName, "!=", fieldValue); - } - - /** - * 小于条件
- * [SQL] AND fieldName < fieldValue - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andLessThen(String fieldName, Object fieldValue) { - return this.and(fieldName, "<", fieldValue); - } - - /** - * 小于等于条件
- * [SQL] AND fieldName <= fieldValue - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andLessEqualsThen(String fieldName, Object fieldValue) { - return this.and(fieldName, "<=", fieldValue); - } - - /** - * 大于条件
- * [SQL] AND fieldName > fieldValue - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andGreaterThen(String fieldName, Object fieldValue) { - return this.and(fieldName, ">", fieldValue); - } - - /** - * 大于等于条件
- * [SQL] AND fieldName >= fieldValue - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andGreaterEqualsThen(String fieldName, Object fieldValue) { - return this.and(fieldName, ">=", fieldValue); - } - - /** - * IS NULL条件
- * [SQL] AND fieldName IS NULL - * - * @param fieldName 字段名 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andIsNull(String fieldName) { - return this.and(fieldName, "is null"); - } - - /** - * IS NOT NULL条件
- * [SQL] AND fieldName IS NOT NULL - * - * @param fieldName 字段名 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andIsNotNull(String fieldName) { - return this.and(fieldName, "is not null"); - } - - /** - * LIKE条件
- * [ORACLE/DB2] AND fieldName LIKE('%'||fieldValue||'%')
- * [MYSQL] AND fieldName LIKE CONCAT('%',fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找带有%的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #andLike(String, LikeValue)}方法
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #andLike(String, LikeValue) - */ - public DbWhere andLike(String fieldName, String fieldValue) { - return this.and(fieldName, "like", fieldValue); - } - - /** - * LIKE条件
- * AND fieldName LIKE fieldValue ESCAPE escapeChar
- * 如果传入了escapeChar, 将会自动生成带ESCAPE的SQL
- * 如: andLike("code", new LikeValue('#', "%10#%"));表示查找以10%结尾的数据
- * 如: andLike("code", new LikeValue("%HOT%COOL%"));表示查找含有HOT和COOL的数据
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 (带escapeChar和通配符的LikeValue) - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andLike(String fieldName, LikeValue fieldValue) { - return this.and(fieldName, "like", fieldValue); - } - - /** - * NOT LIKE条件
- * [ORACLE/DB2] AND fieldName NOT LIKE('%'||fieldValue||'%')
- * [MYSQL] AND fieldName NOT LIKE CONCAT('%',fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找不包含%的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #andNotLike(String, LikeValue)}方法
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #andNotLike(String, LikeValue) - */ - public DbWhere andNotLike(String fieldName, String fieldValue) { - return this.and(fieldName, "not like", fieldValue); - } - - /** - * NOT LIKE条件
- * AND fieldName NOT LIKE fieldValue ESCAPE escapeChar
- * 如果传入了escapeChar, 将会自动生成带ESCAPE的SQL
- * 如: andNotLike("code", new LikeValue('#', "%10#%"));表示查找不以10%结尾的数据
- * 如: andNotLike("code", new LikeValue("%HOT%COOL%"));表示查找不含有HOT和COOL的数据
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 (带escapeChar和通配符的LikeValue) - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andNotLike(String fieldName, LikeValue fieldValue) { - return this.and(fieldName, "not like", fieldValue); - } - - /** - * LIKE前缀查询条件
- * [ORACLE/DB2] AND fieldName LIKE(fieldValue||'%')
- * [MYSQL] AND fieldName LIKE CONCAT(fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找以%开头的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #andLike(String, LikeValue)}方法
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #andLike(String, LikeValue) - */ - public DbWhere andStarts(String fieldName, String fieldValue) { - return this.and(fieldName, "starts", fieldValue); - } - - /** - * NOT LIKE前缀查询条件
- * [ORACLE/DB2] AND fieldName NOT LIKE(fieldValue||'%')
- * [MYSQL] AND fieldName NOT LIKE CONCAT(fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找不以%开头的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #andNotLike(String, LikeValue)}方法
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #andNotLike(String, LikeValue) - */ - public DbWhere andNotStarts(String fieldName, String fieldValue) { - return this.and(fieldName, "not starts", fieldValue); - } - - /** - * LIKE后缀查询条件
- * [ORACLE/DB2] AND fieldName LIKE('%'||fieldValue)
- * [MYSQL] AND fieldName LIKE CONCAT('%',fieldValue)
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找以%结尾的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #andLike(String, LikeValue)}方法
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #andLike(String, LikeValue) - */ - public DbWhere andEnds(String fieldName, String fieldValue) { - return this.and(fieldName, "ends", fieldValue); - } - - /** - * NOT LIKE后缀查询条件
- * [ORACLE/DB2] AND fieldName NOT LIKE('%'||fieldValue)
- * [MYSQL] AND fieldName NOT LIKE CONCAT('%',fieldValue)
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找不以%结尾的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #andNotLike(String, LikeValue)}方法
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #andNotLike(String, LikeValue) - */ - public DbWhere andNotEnds(String fieldName, String fieldValue) { - return this.and(fieldName, "not ends", fieldValue); - } - - /** - * IN查询条件
- * [SQL] AND fieldName IN (fieldValue1, fieldValue2, ...) - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andIn(String fieldName, Collection fieldValue) { - return this.and(fieldName, "in", fieldValue); - } - - /** - * IN查询条件
- * [SQL] AND fieldName IN (fieldValue1, fieldValue2, ...) - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andIn(String fieldName, Object... fieldValue) { - return this.and(fieldName, "in", fieldValue); - } - - /** - * NOT IN查询条件
- * [SQL] AND fieldName NOT IN (fieldValue1, fieldValue2, ...) - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andNotIn(String fieldName, Collection fieldValue) { - return this.and(fieldName, "not in", fieldValue); - } - - /** - * NOT IN查询条件
- * [SQL] AND fieldName NOT IN (fieldValue1, fieldValue2, ...) - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andNotIn(String fieldName, Object... fieldValue) { - return this.and(fieldName, "not in", fieldValue); - } - - /** - * BETWEEN查询条件
- * [SQL] AND fieldName BETWEEN startValue AND endValue - * - * @param fieldName 字段名 - * @param startValue 开始字段值 - * @param endValue 结束字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andBetween(String fieldName, Object startValue, Object endValue) { - return this.and(fieldName, "between", startValue, endValue); - } - - /** - * NOT BETWEEN查询条件
- * [SQL] AND fieldName NOT BETWEEN startValue AND endValue - * - * @param fieldName 字段名 - * @param startValue 开始字段值 - * @param endValue 结束字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andNotBetween(String fieldName, Object startValue, Object endValue) { - return this.and(fieldName, "not between", startValue, endValue); - } - - /** - * 子查询条件
-    // [SQL] AND ( USER_NAME LIKE '%'||keyword||'%' OR REAL_NAME LIKE '%'||keyword||'%' )
-    where.andSubCondition(new SubCondition() { // 子条件
-        public void build(DbWhere w) {
-            w.orLike("userName", entity.getKeyword())
-                .orLike("realName", entity.getKeyword());
-        }
-    });
-    // JDK8
-    where.andSubCondition((w) -> { // 子条件
-        w.orLike("userName", entity.getKeyword())
-            .orLike("realName", entity.getKeyword());
-    });
- * - * @param condition 条件构造器 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andSubCondition(SubCondition condition) { - SubWhere where = new SubWhere(this, LogicType.AND, MatchType.Positive); - this.put(where); - condition.build(where); - return this; - } - - /** - * 否定子查询条件
-    // [SQL] AND NOT ( USER_NAME LIKE '%'||keyword||'%' OR REAL_NAME LIKE '%'||keyword||'%' )
-    where.andNotSubCondition(new SubCondition() { // 子条件
-        public void build(DbWhere w) {
-            w.orLike("userName", entity.getKeyword())
-                .orLike("realName", entity.getKeyword());
-        }
-    });
-    // JDK8
-    where.andNotSubCondition((w) -> { // 子条件
-        w.orLike("userName", entity.getKeyword())
-            .orLike("realName", entity.getKeyword());
-    });
- * - * @param condition 条件构造器 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andNotSubCondition(SubCondition condition) { - SubWhere where = new SubWhere(this, LogicType.AND, MatchType.Negative); - this.put(where); - condition.build(where); - return this; - } - - /** - * 自定义查询条件 - * - * @param condition 条件对象 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andBizCondition(WhereCondition condition) { - BizCondition bizCondition = new BizCondition(condition, LogicType.AND, MatchType.Positive); - super.put(bizCondition); - return this; - } - - /** - * 自定义查询条件 - * - * @param condition 条件对象 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andNotBizCondition(WhereCondition condition) { - BizCondition bizCondition = new BizCondition(condition, LogicType.AND, MatchType.Negative); - super.put(bizCondition); - return this; - } - - /** - * 等于条件
- * [SQL] OR fieldName = fieldValue - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orEquals(String fieldName, Object fieldValue) { - return this.or(fieldName, "=", fieldValue); - } - - /** - * 不等于条件
- * [SQL] OR fieldName != fieldValue - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orNotEquals(String fieldName, Object fieldValue) { - return this.or(fieldName, "!=", fieldValue); - } - - /** - * 小于条件
- * [SQL] OR fieldName < fieldValue - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orLessThen(String fieldName, Object fieldValue) { - return this.or(fieldName, "<", fieldValue); - } - - /** - * 小于等于条件
- * [SQL] OR fieldName <= fieldValue - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orLessEqualsThen(String fieldName, Object fieldValue) { - return this.or(fieldName, "<=", fieldValue); - } - - /** - * 大于条件
- * [SQL] OR fieldName > fieldValue - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orGreaterThen(String fieldName, Object fieldValue) { - return this.or(fieldName, ">", fieldValue); - } - - /** - * 大于等于条件
- * [SQL] OR fieldName >= fieldValue - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orGreaterEqualsThen(String fieldName, Object fieldValue) { - return this.or(fieldName, ">=", fieldValue); - } - - /** - * IS NULL条件
- * [SQL] OR fieldName IS NULL - * - * @param fieldName 字段名 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orIsNull(String fieldName) { - return this.or(fieldName, "is null"); - } - - /** - * IS NOT NULL条件
- * [SQL] OR fieldName IS NOT NULL - * - * @param fieldName 字段名 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orIsNotNull(String fieldName) { - return this.or(fieldName, "is not null"); - } - - /** - * LIKE条件
- * [ORACLE/DB2] OR fieldName LIKE('%'||fieldValue||'%')
- * [MYSQL] OR fieldName LIKE CONCAT('%',fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找带有%的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #orLike(String, LikeValue)}方法
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #orLike(String, LikeValue) - */ - public DbWhere orLike(String fieldName, String fieldValue) { - return this.or(fieldName, "like", fieldValue); - } - - /** - * LIKE条件
- * OR fieldName LIKE fieldValue ESCAPE escapeChar
- * 如果传入了escapeChar, 将会自动生成带ESCAPE的SQL
- * 如: orLike("code", new LikeValue('#', "%10#%"));表示查找以10%结尾的数据
- * 如: orLike("code", new LikeValue("%HOT%COOL%"));表示查找含有HOT和COOL的数据
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 (带escapeChar和通配符的LikeValue) - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orLike(String fieldName, LikeValue fieldValue) { - return this.or(fieldName, "like", fieldValue); - } - - /** - * NOT LIKE条件
- * [ORACLE/DB2] OR fieldName NOT LIKE('%'||fieldValue||'%')
- * [MYSQL] OR fieldName NOT LIKE CONCAT('%',fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找不包含%的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #orNotLike(String, LikeValue)}方法
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #orNotLike(String, LikeValue) - */ - public DbWhere orNotLike(String fieldName, String fieldValue) { - return this.or(fieldName, "not like", fieldValue); - } - - /** - * NOT LIKE条件
- * OR fieldName NOT LIKE fieldValue ESCAPE escapeChar
- * 如果传入了escapeChar, 将会自动生成带ESCAPE的SQL
- * 如: orNotLike("code", new LikeValue('#', "%10#%"));表示查找不以10%结尾的数据
- * 如: orNotLike("code", new LikeValue("%HOT%COOL%"));表示查找不含有HOT和COOL的数据
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 (带escapeChar和通配符的LikeValue) - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orNotLike(String fieldName, LikeValue fieldValue) { - return this.or(fieldName, "not like", fieldValue); - } - - /** - * LIKE前缀查询条件
- * [ORACLE/DB2] OR fieldName LIKE(fieldValue||'%')
- * [MYSQL] OR fieldName LIKE CONCAT(fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找以%开头的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #orLike(String, LikeValue)}方法
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #orLike(String, LikeValue) - */ - public DbWhere orStarts(String fieldName, String fieldValue) { - return this.or(fieldName, "starts", fieldValue); - } - - /** - * NOT LIKE前缀查询条件
- * [ORACLE/DB2] OR fieldName NOT LIKE(fieldValue||'%')
- * [MYSQL] OR fieldName NOT LIKE CONCAT(fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找不以%开头的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #orNotLike(String, LikeValue)}方法
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #orNotLike(String, LikeValue) - */ - public DbWhere orNotStarts(String fieldName, String fieldValue) { - return this.or(fieldName, "not starts", fieldValue); - } - - /** - * LIKE后缀查询条件
- * [ORACLE/DB2] OR fieldName LIKE('%'||fieldValue)
- * [MYSQL] OR fieldName LIKE CONCAT('%',fieldValue)
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找以%结尾的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #orLike(String, LikeValue)}方法
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #orLike(String, LikeValue) - */ - public DbWhere orEnds(String fieldName, String fieldValue) { - return this.or(fieldName, "ends", fieldValue); - } - - /** - * NOT LIKE后缀查询条件
- * [ORACLE/DB2] OR fieldName NOT LIKE('%'||fieldValue)
- * [MYSQL] OR fieldName NOT LIKE CONCAT('%',fieldValue)
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找不以%结尾的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #orNotLike(String, LikeValue)}方法
- * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #orNotLike(String, LikeValue) - */ - public DbWhere orNotEnds(String fieldName, String fieldValue) { - return this.or(fieldName, "not ends", fieldValue); - } - - /** - * IN查询条件
- * [SQL] OR fieldName IN (fieldValue1, fieldValue2, ...) - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orIn(String fieldName, Collection fieldValue) { - return this.or(fieldName, "in", fieldValue); - } - - /** - * IN查询条件
- * [SQL] OR fieldName IN (fieldValue1, fieldValue2, ...) - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orIn(String fieldName, Object... fieldValue) { - return this.or(fieldName, "in", fieldValue); - } - - /** - * NOT IN查询条件
- * [SQL] OR fieldName NOT IN (fieldValue1, fieldValue2, ...) - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orNotIn(String fieldName, Collection fieldValue) { - return this.or(fieldName, "not in", fieldValue); - } - - /** - * NOT IN查询条件
- * [SQL] OR fieldName NOT IN (fieldValue1, fieldValue2, ...) - * - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orNotIn(String fieldName, Object... fieldValue) { - return this.or(fieldName, "not in", fieldValue); - } - - /** - * BETWEEN查询条件
- * [SQL] OR fieldName BETWEEN startValue AND endValue - * - * @param fieldName 字段名 - * @param startValue 开始字段值 - * @param endValue 结束字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orBetween(String fieldName, Object startValue, Object endValue) { - return this.or(fieldName, "between", startValue, endValue); - } - - /** - * NOT BETWEEN查询条件
- * [SQL] OR fieldName NOT BETWEEN startValue AND endValue - * - * @param fieldName 字段名 - * @param startValue 开始字段值 - * @param endValue 结束字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orNotBetween(String fieldName, Object startValue, Object endValue) { - return this.or(fieldName, "not between", startValue, endValue); - } - - /** - * 子查询条件
-    // [SQL] OR ( USER_NAME LIKE '%'||keyword||'%' OR REAL_NAME LIKE '%'||keyword||'%' )
-    where.orSubCondition(new SubCondition() { // 子条件
-        public void build(DbWhere w) {
-            w.orLike("userName", entity.getKeyword())
-                .orLike("realName", entity.getKeyword());
-        }
-    });
-    // JDK8
-    where.orSubCondition((w) -> { // 子条件
-        w.orLike("userName", entity.getKeyword())
-            .orLike("realName", entity.getKeyword());
-    });
- * - * @param condition 条件构造器 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orSubCondition(SubCondition condition) { - SubWhere where = new SubWhere(this, LogicType.OR, MatchType.Positive); - this.put(where); - condition.build(where); - return this; - } - - /** - * 否定子查询条件
-    // [SQL] OR NOT ( USER_NAME LIKE '%'||keyword||'%' OR REAL_NAME LIKE '%'||keyword||'%' )
-    where.orNotSubCondition(new SubCondition() { // 子条件
-        public void build(DbWhere w) {
-            w.orLike("userName", entity.getKeyword())
-                .orLike("realName", entity.getKeyword());
-        }
-    });
-    // JDK8
-    where.orNotSubCondition((w) -> { // 子条件
-        w.orLike("userName", entity.getKeyword())
-            .orLike("realName", entity.getKeyword());
-    });
- * - * @param condition 条件构造器 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orNotSubCondition(SubCondition condition) { - SubWhere where = new SubWhere(this, LogicType.OR, MatchType.Negative); - this.put(where); - condition.build(where); - return this; - } - - /** - * 自定义查询条件 - * - * @param condition 条件对象 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orBizCondition(WhereCondition condition) { - BizCondition bizCondition = new BizCondition(condition, LogicType.OR, MatchType.Positive); - super.put(bizCondition); - return this; - } - - /** - * 自定义查询条件 - * - * @param condition 条件对象 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orNotBizCondition(WhereCondition condition) { - BizCondition bizCondition = new BizCondition(condition, LogicType.OR, MatchType.Negative); - super.put(bizCondition); - return this; - } - - /** - * 等于条件
- * [SQL] AND fieldName = fieldValue - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andEqualsIf(boolean asserts, String fieldName, Object fieldValue) { - return this.andIf(asserts, fieldName, "=", fieldValue); - } - - /** - * 不等于条件
- * [SQL] AND fieldName != fieldValue - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andNotEqualsIf(boolean asserts, String fieldName, Object fieldValue) { - return this.andIf(asserts, fieldName, "!=", fieldValue); - } - - /** - * 小于条件
- * [SQL] AND fieldName < fieldValue - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andLessThenIf(boolean asserts, String fieldName, Object fieldValue) { - return this.andIf(asserts, fieldName, "<", fieldValue); - } - - /** - * 小于等于条件
- * [SQL] AND fieldName <= fieldValue - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andLessEqualsThenIf(boolean asserts, String fieldName, Object fieldValue) { - return this.andIf(asserts, fieldName, "<=", fieldValue); - } - - /** - * 大于条件
- * [SQL] AND fieldName > fieldValue - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andGreaterThenIf(boolean asserts, String fieldName, Object fieldValue) { - return this.andIf(asserts, fieldName, ">", fieldValue); - } - - /** - * 大于等于条件
- * [SQL] AND fieldName >= fieldValue - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andGreaterEqualsThenIf(boolean asserts, String fieldName, Object fieldValue) { - return this.andIf(asserts, fieldName, ">=", fieldValue); - } - - /** - * IS NULL条件
- * [SQL] AND fieldName IS NULL - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andIsNullIf(boolean asserts, String fieldName) { - return this.andIf(asserts, fieldName, "is null"); - } - - /** - * IS NOT NULL条件
- * [SQL] AND fieldName IS NOT NULL - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andIsNotNullIf(boolean asserts, String fieldName) { - return this.andIf(asserts, fieldName, "is not null"); - } - - /** - * LIKE条件
- * [ORACLE/DB2] AND fieldName LIKE('%'||fieldValue||'%')
- * [MYSQL] AND fieldName LIKE CONCAT('%',fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找带有%的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #andLikeIf(String, LikeValue)}方法
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #andLikeIf(String, LikeValue) - */ - public DbWhere andLikeIf(boolean asserts, String fieldName, String fieldValue) { - return this.andIf(asserts, fieldName, "like", fieldValue); - } - - /** - * LIKE条件
- * AND fieldName LIKE fieldValue ESCAPE escapeChar
- * 如果传入了escapeChar, 将会自动生成带ESCAPE的SQL
- * 如: andLike("code", new LikeValue('#', "%10#%"));表示查找以10%结尾的数据
- * 如: andLike("code", new LikeValue("%HOT%COOL%"));表示查找含有HOT和COOL的数据
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 (带escapeChar和通配符的LikeValue) - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andLikeIf(boolean asserts, String fieldName, LikeValue fieldValue) { - return this.andIf(asserts, fieldName, "like", fieldValue); - } - - /** - * NOT LIKE条件
- * [ORACLE/DB2] AND fieldName NOT LIKE('%'||fieldValue||'%')
- * [MYSQL] AND fieldName NOT LIKE CONCAT('%',fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找不包含%的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #andNotLikeIf(String, LikeValue)}方法
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #andNotLikeIf(String, LikeValue) - */ - public DbWhere andNotLikeIf(boolean asserts, String fieldName, String fieldValue) { - return this.andIf(asserts, fieldName, "not like", fieldValue); - } - - /** - * NOT LIKE条件
- * AND fieldName NOT LIKE fieldValue ESCAPE escapeChar
- * 如果传入了escapeChar, 将会自动生成带ESCAPE的SQL
- * 如: andNotLike("code", new LikeValue('#', "%10#%"));表示查找不以10%结尾的数据
- * 如: andNotLike("code", new LikeValue("%HOT%COOL%"));表示查找不含有HOT和COOL的数据
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 (带escapeChar和通配符的LikeValue) - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andNotLikeIf(boolean asserts, String fieldName, LikeValue fieldValue) { - return this.andIf(asserts, fieldName, "not like", fieldValue); - } - - /** - * LIKE前缀查询条件
- * [ORACLE/DB2] AND fieldName LIKE(fieldValue||'%')
- * [MYSQL] AND fieldName LIKE CONCAT(fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找以%开头的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #andLikeIf(String, LikeValue)}方法
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #andLikeIf(String, LikeValue) - */ - public DbWhere andStartsIf(boolean asserts, String fieldName, String fieldValue) { - return this.andIf(asserts, fieldName, "starts", fieldValue); - } - - /** - * NOT LIKE前缀查询条件
- * [ORACLE/DB2] AND fieldName NOT LIKE(fieldValue||'%')
- * [MYSQL] AND fieldName NOT LIKE CONCAT(fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找不以%开头的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #andNotLikeIf(String, LikeValue)}方法
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #andNotLikeIf(String, LikeValue) - */ - public DbWhere andNotStartsIf(boolean asserts, String fieldName, String fieldValue) { - return this.andIf(asserts, fieldName, "not starts", fieldValue); - } - - /** - * LIKE后缀查询条件
- * [ORACLE/DB2] AND fieldName LIKE('%'||fieldValue)
- * [MYSQL] AND fieldName LIKE CONCAT('%',fieldValue)
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找以%结尾的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #andLikeIf(String, LikeValue)}方法
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #andLikeIf(String, LikeValue) - */ - public DbWhere andEndsIf(boolean asserts, String fieldName, String fieldValue) { - return this.andIf(asserts, fieldName, "ends", fieldValue); - } - - /** - * NOT LIKE后缀查询条件
- * [ORACLE/DB2] AND fieldName NOT LIKE('%'||fieldValue)
- * [MYSQL] AND fieldName NOT LIKE CONCAT('%',fieldValue)
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找不以%结尾的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #andNotLikeIf(String, LikeValue)}方法
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #andNotLikeIf(String, LikeValue) - */ - public DbWhere andNotEndsIf(boolean asserts, String fieldName, String fieldValue) { - return this.andIf(asserts, fieldName, "not ends", fieldValue); - } - - /** - * IN查询条件
- * [SQL] AND fieldName IN (fieldValue1, fieldValue2, ...) - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andInIf(boolean asserts, String fieldName, Collection fieldValue) { - return this.andIf(asserts, fieldName, "in", fieldValue); - } - - /** - * IN查询条件
- * [SQL] AND fieldName IN (fieldValue1, fieldValue2, ...) - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andInIf(boolean asserts, String fieldName, Object... fieldValue) { - return this.andIf(asserts, fieldName, "in", fieldValue); - } - - /** - * NOT IN查询条件
- * [SQL] AND fieldName NOT IN (fieldValue1, fieldValue2, ...) - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andNotInIf(boolean asserts, String fieldName, Collection fieldValue) { - return this.andIf(asserts, fieldName, "not in", fieldValue); - } - - /** - * NOT IN查询条件
- * [SQL] AND fieldName NOT IN (fieldValue1, fieldValue2, ...) - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andNotInIf(boolean asserts, String fieldName, Object... fieldValue) { - return this.andIf(asserts, fieldName, "not in", fieldValue); - } - - /** - * BETWEEN查询条件
- * [SQL] AND fieldName BETWEEN startValue AND endValue - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param startValue 开始字段值 - * @param endValue 结束字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andBetweenIf(boolean asserts, String fieldName, Object startValue, Object endValue) { - return this.andIf(asserts, fieldName, "between", startValue, endValue); - } - - /** - * NOT BETWEEN查询条件
- * [SQL] AND fieldName NOT BETWEEN startValue AND endValue - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param startValue 开始字段值 - * @param endValue 结束字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere andNotBetweenIf(boolean asserts, String fieldName, Object startValue, Object endValue) { - return this.andIf(asserts, fieldName, "not between", startValue, endValue); - } - - /** - * 等于条件
- * [SQL] OR fieldName = fieldValue - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orEqualsIf(boolean asserts, String fieldName, Object fieldValue) { - return this.orIf(asserts, fieldName, "=", fieldValue); - } - - /** - * 不等于条件
- * [SQL] OR fieldName != fieldValue - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orNotEqualsIf(boolean asserts, String fieldName, Object fieldValue) { - return this.orIf(asserts, fieldName, "!=", fieldValue); - } - - /** - * 小于条件
- * [SQL] OR fieldName < fieldValue - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orLessThenIf(boolean asserts, String fieldName, Object fieldValue) { - return this.orIf(asserts, fieldName, "<", fieldValue); - } - - /** - * 小于等于条件
- * [SQL] OR fieldName <= fieldValue - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orLessEqualsThenIf(boolean asserts, String fieldName, Object fieldValue) { - return this.orIf(asserts, fieldName, "<=", fieldValue); - } - - /** - * 大于条件
- * [SQL] OR fieldName > fieldValue - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orGreaterThenIf(boolean asserts, String fieldName, Object fieldValue) { - return this.orIf(asserts, fieldName, ">", fieldValue); - } - - /** - * 大于等于条件
- * [SQL] OR fieldName >= fieldValue - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orGreaterEqualsThenIf(boolean asserts, String fieldName, Object fieldValue) { - return this.orIf(asserts, fieldName, ">=", fieldValue); - } - - /** - * IS NULL条件
- * [SQL] OR fieldName IS NULL - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orIsNullIf(boolean asserts, String fieldName) { - return this.orIf(asserts, fieldName, "is null"); - } - - /** - * IS NOT NULL条件
- * [SQL] OR fieldName IS NOT NULL - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orIsNotNullIf(boolean asserts, String fieldName) { - return this.orIf(asserts, fieldName, "is not null"); - } - - /** - * LIKE条件
- * [ORACLE/DB2] OR fieldName LIKE('%'||fieldValue||'%')
- * [MYSQL] OR fieldName LIKE CONCAT('%',fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找带有%的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #orLikeIf(String, LikeValue)}方法
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #orLikeIf(String, LikeValue) - */ - public DbWhere orLikeIf(boolean asserts, String fieldName, String fieldValue) { - return this.orIf(asserts, fieldName, "like", fieldValue); - } - - /** - * LIKE条件
- * OR fieldName LIKE fieldValue ESCAPE escapeChar
- * 如果传入了escapeChar, 将会自动生成带ESCAPE的SQL
- * 如: orLike("code", new LikeValue('#', "%10#%"));表示查找以10%结尾的数据
- * 如: orLike("code", new LikeValue("%HOT%COOL%"));表示查找含有HOT和COOL的数据
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 (带escapeChar和通配符的LikeValue) - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orLikeIf(boolean asserts, String fieldName, LikeValue fieldValue) { - return this.orIf(asserts, fieldName, "like", fieldValue); - } - - /** - * NOT LIKE条件
- * [ORACLE/DB2] OR fieldName NOT LIKE('%'||fieldValue||'%')
- * [MYSQL] OR fieldName NOT LIKE CONCAT('%',fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找不包含%的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #orNotLikeIf(String, LikeValue)}方法
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #orNotLikeIf(String, LikeValue) - */ - public DbWhere orNotLikeIf(boolean asserts, String fieldName, String fieldValue) { - return this.orIf(asserts, fieldName, "not like", fieldValue); - } - - /** - * NOT LIKE条件
- * OR fieldName NOT LIKE fieldValue ESCAPE escapeChar
- * 如果传入了escapeChar, 将会自动生成带ESCAPE的SQL
- * 如: orNotLike("code", new LikeValue('#', "%10#%"));表示查找不以10%结尾的数据
- * 如: orNotLike("code", new LikeValue("%HOT%COOL%"));表示查找不含有HOT和COOL的数据
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 (带escapeChar和通配符的LikeValue) - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orNotLikeIf(boolean asserts, String fieldName, LikeValue fieldValue) { - return this.orIf(asserts, fieldName, "not like", fieldValue); - } - - /** - * LIKE前缀查询条件
- * [ORACLE/DB2] OR fieldName LIKE(fieldValue||'%')
- * [MYSQL] OR fieldName LIKE CONCAT(fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找以%开头的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #orLikeIf(String, LikeValue)}方法
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #orLikeIf(String, LikeValue) - */ - public DbWhere orStartsIf(boolean asserts, String fieldName, String fieldValue) { - return this.orIf(asserts, fieldName, "starts", fieldValue); - } - - /** - * NOT LIKE前缀查询条件
- * [ORACLE/DB2] OR fieldName NOT LIKE(fieldValue||'%')
- * [MYSQL] OR fieldName NOT LIKE CONCAT(fieldValue,'%')
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找不以%开头的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #orNotLikeIf(String, LikeValue)}方法
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #orNotLikeIf(String, LikeValue) - */ - public DbWhere orNotStartsIf(boolean asserts, String fieldName, String fieldValue) { - return this.orIf(asserts, fieldName, "not starts", fieldValue); - } - - /** - * LIKE后缀查询条件
- * [ORACLE/DB2] OR fieldName LIKE('%'||fieldValue)
- * [MYSQL] OR fieldName LIKE CONCAT('%',fieldValue)
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找以%结尾的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #orLikeIf(String, LikeValue)}方法
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #orLikeIf(String, LikeValue) - */ - public DbWhere orEndsIf(boolean asserts, String fieldName, String fieldValue) { - return this.orIf(asserts, fieldName, "ends", fieldValue); - } - - /** - * NOT LIKE后缀查询条件
- * [ORACLE/DB2] OR fieldName NOT LIKE('%'||fieldValue)
- * [MYSQL] OR fieldName NOT LIKE CONCAT('%',fieldValue)
- * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找不以%结尾的数据, 将会自动生成带ESCAPE的SQL
- * 如果希望自己处理ESCAPE逻辑, 可使用{@link #orNotLikeIf(String, LikeValue)}方法
- * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - * @see #orNotLikeIf(String, LikeValue) - */ - public DbWhere orNotEndsIf(boolean asserts, String fieldName, String fieldValue) { - return this.orIf(asserts, fieldName, "not ends", fieldValue); + public DbWhere() { + super(); } - /** - * IN查询条件
- * [SQL] OR fieldName IN (fieldValue1, fieldValue2, ...) - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orInIf(boolean asserts, String fieldName, Collection fieldValue) { - return this.orIf(asserts, fieldName, "in", fieldValue); + protected DbWhere(List conditions) { + super(conditions); } /** - * IN查询条件
- * [SQL] OR fieldName IN (fieldValue1, fieldValue2, ...) + * 查询条件 * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 + * @param fieldName 字段名称 + * @return 返回后续流式操作对象 */ - public DbWhere orInIf(boolean asserts, String fieldName, Object... fieldValue) { - return this.orIf(asserts, fieldName, "in", fieldValue); + public DbWhereForFieldCore on(String fieldName) { + DbWhereForStartCore start = new DbWhereForStartCore<>(this, this); + return new DbWhereForFieldCore<>(start, SkipType.NONE, LogicType.AND, fieldName); } /** - * NOT IN查询条件
- * [SQL] OR fieldName NOT IN (fieldValue1, fieldValue2, ...) + * 查询条件 * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 + * @return 返回后续流式操作对象 */ - public DbWhere orNotInIf(boolean asserts, String fieldName, Collection fieldValue) { - return this.orIf(asserts, fieldName, "not in", fieldValue); + public DbWhereForOnFieldless on() { + DbWhereForStartCore start = new DbWhereForStartCore<>(this, this); + return new DbWhereForOnFieldless<>(start, SkipType.NONE); } /** - * NOT IN查询条件
- * [SQL] OR fieldName NOT IN (fieldValue1, fieldValue2, ...) + * 克隆为新对象(如果子类有新增字段或没有默认构造函数就应该覆盖该方法) * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param fieldValue 字段值 - * @return 返回容器自身, 用于链式操作 + * @return 新对象 + * @since 5.0.0 */ - public DbWhere orNotInIf(boolean asserts, String fieldName, Object... fieldValue) { - return this.orIf(asserts, fieldName, "not in", fieldValue); + @Override + public DbWhere copy() { + DbWhere copies = newCopies(); + this.copyTo(copies); + return copies; } - /** - * BETWEEN查询条件
- * [SQL] OR fieldName BETWEEN startValue AND endValue - * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param startValue 开始字段值 - * @param endValue 结束字段值 - * @return 返回容器自身, 用于链式操作 - */ - public DbWhere orBetweenIf(boolean asserts, String fieldName, Object startValue, Object endValue) { - return this.orIf(asserts, fieldName, "between", startValue, endValue); + protected void copyTo(DbWhere copies) { + Iterator iterator = this.iterator(); + while (iterator.hasNext()) { + DbCondition item = iterator.next(); + if (item instanceof LogicField) { + copies.put(((LogicField) item).copy()); + } else if (item instanceof DbField) { + copies.put(((DbField) item).copy()); + } else if (item instanceof SubWhere) { + copies.put(((SubWhere) item).copy()); + } else if (item instanceof DbWhere) { + copies.put(((DbWhere) item).copy()); + } else if (item instanceof Copyable) { + DbCondition newer = (DbCondition) ((Copyable) item).copy(); + copies.put(newer); + } else { // DbCondition/DbConditions + copies.put(item); // 无法克隆为副本 + } + } } /** - * NOT BETWEEN查询条件
- * [SQL] OR fieldName NOT BETWEEN startValue AND endValue + * 创建副本对象(如果子类没有默认构造函数就应该覆盖该方法) * - * @param asserts 判断条件, 只有asserts=true才添加查询条件 - * @param fieldName 字段名 - * @param startValue 开始字段值 - * @param endValue 结束字段值 - * @return 返回容器自身, 用于链式操作 + * @return 副本对象 + * @since 5.0.0 */ - public DbWhere orNotBetweenIf(boolean asserts, String fieldName, Object startValue, Object endValue) { - return this.orIf(asserts, fieldName, "not between", startValue, endValue); - } - - public static interface SubCondition { - - void build(DbWhere where); - } - - public static class BizCondition implements DbCondition, LogicCondition, MatchCondition { - - private final WhereCondition condition; - /** 逻辑联连类型: AND / OR **/ - private final LogicType logicType; - /** 匹配模式 **/ - private final MatchType matchType; - - public BizCondition(WhereCondition condition, LogicType logicType, MatchType matchType) { - this.condition = condition; - this.logicType = logicType; - this.matchType = matchType; - } - - public WhereCondition getWhereCondition() { - return condition; - } - - /** 逻辑联连类型: AND / OR **/ - @Override - public LogicType getLogicType() { - return logicType; - } - - /** 匹配模式 **/ - @Override - public MatchType getMatchType() { - return matchType; - } - - @Override - public boolean isEmpty() { - return condition == null ? true : condition.isEmpty(); + protected DbWhere newCopies() { + if (this.getClass() == DbWhere.class) { // 当前类 + return new DbWhere(); + } else { // 子类 + try { + return this.getClass().newInstance(); + } catch (Exception e) { + throw new IllegalStateException("CloneNotSupported, FailedToInvokeDefaultConstructor."); + } } } @@ -1763,123 +177,9 @@ public class DbWhere extends DbItems implements Copyable { return instance; } - public class Field extends DbField implements LogicCondition { - - /** serialVersionUID **/ - private static final long serialVersionUID = 1L; - - private final DbWhere container; - private final LogicType logicType; - - /** 构造函数 **/ - public Field(LogicType logicType) { - this.logicType = logicType; - this.container = DbWhere.this; - } - - /** 构造函数 **/ - private Field(LogicType logicType, DbField field) { - super(field.getOperateType(), field.getFieldName(), field.getFieldValue()); - this.container = DbWhere.this; - this.logicType = logicType; - } - - /** 构造函数 **/ - public Field(LogicType logicType, String fieldName, Object fieldValue) { - super(fieldName, fieldValue); - this.container = DbWhere.this; - this.logicType = logicType; - } - - /** 构造函数 **/ - public Field(LogicType logicType, String operateType, String fieldName, Object fieldValue) { - super(operateType, fieldName, fieldValue); - this.container = DbWhere.this; - this.logicType = logicType; - } - - public DbWhere getContainer() { - return container; - } - - @Override - public LogicType getLogicType() { - return logicType; - } - - @Override - public Field copy() { - LogicType logicType = this.getLogicType(); - String operateType = this.getOperateType(); - String fieldName = this.getFieldName(); - Object fieldValue = this.getFieldValue(); - return new Field(logicType, operateType, fieldName, fieldValue); - } - } - - private static class InnerSubWhere extends SubWhere { - - /** SerialVersionUID **/ - private static final long serialVersionUID = 1L; - - private LogicType innerLogicType; - - protected InnerSubWhere() { - super(); - } - - public InnerSubWhere(DbWhere parent, LogicType logicType, MatchType matchType, LogicType innerLogicType) { - super(parent, logicType, matchType); - this.innerLogicType = innerLogicType; - } - - @Override - public SubWhere on(String fieldName, String operate, Object... fieldValues) { - if (innerLogicType == LogicType.OR) { - this.or(fieldName, operate, fieldValues); - } else { - this.and(fieldName, operate, fieldValues); - } - return this; - } - - /** 增加自定义条件 **/ - @Override - public SubWhere on(WhereCondition condition) { - if (innerLogicType == LogicType.OR) { - super.orBizCondition(condition); - } else { - super.andBizCondition(condition); - } - return this; - } - - /** {@inheritDoc} **/ - @Override - public InnerSubWhere copy() { - InnerSubWhere copies = newCopies(); - this.copyTo(copies); - return copies; - } - - protected void copyTo(InnerSubWhere copies) { - super.copyTo(copies); - copies.innerLogicType = this.innerLogicType; - } + public static interface SubCondition { - /** {@inheritDoc} **/ - @Override - protected InnerSubWhere newCopies() { - if (this.getClass() == InnerSubWhere.class) { // 当前类 - return new InnerSubWhere(); - } else { // 子类 - try { - return this.getClass().newInstance(); - } catch (Exception e) { - throw new IllegalStateException("CloneNotSupported, FailedToInvokeDefaultConstructor."); - } - } - } + void build(DbWhere where); } /** @@ -1942,11 +242,5 @@ public class DbWhere extends DbItems implements Copyable { public void clear() { throw new UnsupportedOperationException("read only"); } - - @Override - public SubWhere sub(String operate) { - throw new UnsupportedOperationException("read only"); - } - } } diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereBase.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereBase.java new file mode 100644 index 0000000000000000000000000000000000000000..83045b61456a79e20cadd9f23ec44b8c2e9dc9a3 --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereBase.java @@ -0,0 +1,78 @@ +package com.gitee.qdbp.able.jdbc.condition; + +import com.gitee.qdbp.able.enums.LogicType; +import com.gitee.qdbp.able.enums.MatchType; +import com.gitee.qdbp.able.jdbc.base.WhereCondition; +import com.gitee.qdbp.able.jdbc.condition.DbWhere.SubCondition; +import com.gitee.qdbp.tools.utils.VerifyTools; + +/** + * DbField收集器 + * + * @author zhaohuihua + * @version 20210606 + */ +abstract class DbWhereBase { + + protected T root; + protected DbItems items; + + protected DbWhereBase(T root, DbItems items) { + this.root = root; + this.items = items; + } + + /** + * 增加条件 + * + * @param condition 条件 + */ + protected void put(DbField condition) { + VerifyTools.requireNonNull(condition, "condition"); + if (condition instanceof LogicField) { + this.items.put(condition); + } else { + this.items.put(new LogicField(LogicType.AND, condition)); + } + } + + /** + * 增加条件 + * + * @param fieldName 字段名称 + * @param operate 操作符 + * @param fieldValues 字段值 + * @return 返回后续流式操作对象 + */ + protected void put(LogicType logicType, String fieldName, String operate, Object... fieldValues) { + LogicField condition = LogicField.of(logicType, fieldName, operate, fieldValues); + this.items.put(condition); + } + + /** + * 增加子查询条件 + * + * @param logicType 逻辑类型 AND还是OR + * @param matchType 匹配类型 正向匹配还是反向匹配 + * @param condition 条件构造器 + * @return 返回后续流式操作对象 + */ + protected void put(LogicType logicType, MatchType matchType, SubCondition condition) { + SubWhere where = new SubWhere(logicType, matchType); + condition.build(where); + this.items.put(where); + } + + /** + * 增加自定义查询条件 + * + * @param logicType 逻辑类型 AND还是OR + * @param matchType 匹配类型 正向匹配还是反向匹配 + * @param condition 条件对象 + * @return 返回后续流式操作对象 + */ + protected void put(LogicType logicType, MatchType matchType, WhereCondition condition) { + BizCondition bizCondition = new BizCondition(logicType, matchType, condition); + this.items.put(bizCondition); + } +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForFieldBase.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForFieldBase.java new file mode 100644 index 0000000000000000000000000000000000000000..d065fd3d9ac91e45aa418fefa40b4a176093cd5b --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForFieldBase.java @@ -0,0 +1,309 @@ +package com.gitee.qdbp.able.jdbc.condition; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Collection; +import com.gitee.qdbp.able.enums.LogicType; +import com.gitee.qdbp.able.jdbc.model.LikeValue; + +/** + * 数据库Where条件容器 + * + * @author zhaohuihua + * @version 181221 + */ +public class DbWhereForFieldBase extends DbWhereBase { + + private DbWhereForStartCore start; + private SkipType skipType; + private LogicType logicType; + private String fieldName; + + protected DbWhereForFieldBase(DbWhereForStartCore start, SkipType skipType, LogicType logicType, + String fieldName) { + super(start.root, start.items); + this.start = start; + this.skipType = skipType; + this.logicType = logicType; + this.fieldName = fieldName; + } + + /** + * 自定义条件 + * + * @param operate 操作符 + * @param fieldValues 字段值 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore when(String operate, Object... fieldValues) { + return this.on(operate, fieldValues); + } + + /** + * 增加条件 + * + * @param operate 操作符 + * @param fieldValues 字段值 + * @return 返回后续流式操作对象 + */ + protected DbWhereForStartCore on(String operate, Object... fieldValues) { + if (skipType == SkipType.NONE || skipType == SkipType.BLANK_VALUE && !InnerUtils.isBlank(fieldValues)) { + this.put(logicType, fieldName, operate, fieldValues); + } + return start; + } + + /** + * 等于条件
+ * [SQL] AND fieldName = fieldValue + * + * @param fieldValue 字段值 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore equals(Serializable fieldValue) { + return this.on("=", fieldValue); + } + + /** + * 不等于条件
+ * [SQL] AND fieldName != fieldValue + * + * @param fieldValue 字段值 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore notEquals(Object fieldValue) { + return this.on("!=", fieldValue); + } + + /** + * 小于条件
+ * [SQL] AND fieldName < fieldValue + * + * @param fieldValue 字段值 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore lessThen(Object fieldValue) { + return this.on("<", fieldValue); + } + + /** + * 小于等于条件
+ * [SQL] AND fieldName <= fieldValue + * + * @param fieldValue 字段值 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore lessEqualsThen(Object fieldValue) { + return this.on("<=", fieldValue); + } + + /** + * 大于条件
+ * [SQL] AND fieldName > fieldValue + * + * @param fieldValue 字段值 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore greaterThen(Object fieldValue) { + return this.on(">", fieldValue); + } + + /** + * 大于等于条件
+ * [SQL] AND fieldName >= fieldValue + * + * @param fieldValue 字段值 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore greaterEqualsThen(Object fieldValue) { + return this.on(">=", fieldValue); + } + + /** + * LIKE条件
+ * [ORACLE/DB2] AND fieldName LIKE('%'||fieldValue||'%')
+ * [MYSQL] AND fieldName LIKE CONCAT('%',fieldValue,'%')
+ * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找带有%的数据, 将会自动生成带ESCAPE的SQL
+ * 如果希望自己处理ESCAPE逻辑, 可使用{@link #like(LikeValue)}方法
+ * + * @param fieldValue 字段值 + * @return 返回后续流式操作对象 + * @see #like(LikeValue) + */ + public DbWhereForStartCore like(String fieldValue) { + return this.on("like", fieldValue); + } + + /** + * LIKE条件
+ * AND fieldName LIKE fieldValue ESCAPE escapeChar
+ * 如果传入了escapeChar, 将会自动生成带ESCAPE的SQL
+ * 如: andLike("code", new LikeValue('#', "%10#%"));表示查找以10%结尾的数据
+ * 如: andLike("code", new LikeValue("%HOT%COOL%"));表示查找含有HOT和COOL的数据
+ * + * @param fieldValue 字段值 (带escapeChar和通配符的LikeValue) + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore like(LikeValue fieldValue) { + return this.on("like", fieldValue); + } + + /** + * NOT LIKE条件
+ * [ORACLE/DB2] AND fieldName NOT LIKE('%'||fieldValue||'%')
+ * [MYSQL] AND fieldName NOT LIKE CONCAT('%',fieldValue,'%')
+ * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找不包含%的数据, 将会自动生成带ESCAPE的SQL
+ * 如果希望自己处理ESCAPE逻辑, 可使用{@link #notLike(LikeValue)}方法
+ * + * @param fieldValue 字段值 + * @return 返回后续流式操作对象 + * @see #notLike(LikeValue) + */ + public DbWhereForStartCore notLike(String fieldValue) { + return this.on("not like", fieldValue); + } + + /** + * NOT LIKE条件
+ * AND fieldName NOT LIKE fieldValue ESCAPE escapeChar
+ * 如果传入了escapeChar, 将会自动生成带ESCAPE的SQL
+ * 如: andNotLike("code", new LikeValue('#', "%10#%"));表示查找不以10%结尾的数据
+ * 如: andNotLike("code", new LikeValue("%HOT%COOL%"));表示查找不含有HOT和COOL的数据
+ * + * @param fieldValue 字段值 (带escapeChar和通配符的LikeValue) + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore notLike(LikeValue fieldValue) { + return this.on("not like", fieldValue); + } + + /** + * LIKE前缀查询条件
+ * [ORACLE/DB2] AND fieldName LIKE(fieldValue||'%')
+ * [MYSQL] AND fieldName LIKE CONCAT(fieldValue,'%')
+ * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找以%开头的数据, 将会自动生成带ESCAPE的SQL
+ * 如果希望自己处理ESCAPE逻辑, 可使用{@link #like(LikeValue)}方法
+ * + * @param fieldValue 字段值 + * @return 返回后续流式操作对象 + * @see #like(LikeValue) + */ + public DbWhereForStartCore startsWith(String fieldValue) { + return this.on("starts", fieldValue); + } + + /** + * NOT LIKE前缀查询条件
+ * [ORACLE/DB2] AND fieldName NOT LIKE(fieldValue||'%')
+ * [MYSQL] AND fieldName NOT LIKE CONCAT(fieldValue,'%')
+ * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找不以%开头的数据, 将会自动生成带ESCAPE的SQL
+ * 如果希望自己处理ESCAPE逻辑, 可使用{@link #notLike(LikeValue)}方法
+ * + * @param fieldValue 字段值 + * @return 返回后续流式操作对象 + * @see #notLike(LikeValue) + */ + public DbWhereForStartCore notStartsWith(String fieldValue) { + return this.on("not starts", fieldValue); + } + + /** + * LIKE后缀查询条件
+ * [ORACLE/DB2] AND fieldName LIKE('%'||fieldValue)
+ * [MYSQL] AND fieldName LIKE CONCAT('%',fieldValue)
+ * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找以%结尾的数据, 将会自动生成带ESCAPE的SQL
+ * 如果希望自己处理ESCAPE逻辑, 可使用{@link #like(LikeValue)}方法
+ * + * @param fieldValue 字段值 + * @return 返回后续流式操作对象 + * @see #like(LikeValue) + */ + public DbWhereForStartCore endsWith(String fieldValue) { + return this.on("ends", fieldValue); + } + + /** + * NOT LIKE后缀查询条件
+ * [ORACLE/DB2] AND fieldName NOT LIKE('%'||fieldValue)
+ * [MYSQL] AND fieldName NOT LIKE CONCAT('%',fieldValue)
+ * 如果fieldValue中包含%等特殊字符, 只会当作普通字符处理, 就表示查找不以%结尾的数据, 将会自动生成带ESCAPE的SQL
+ * 如果希望自己处理ESCAPE逻辑, 可使用{@link #notLike(LikeValue)}方法
+ * + * @param fieldValue 字段值 + * @return 返回后续流式操作对象 + * @see #notLike(LikeValue) + */ + public DbWhereForStartCore notEndsWith(String fieldValue) { + return this.on("not ends", fieldValue); + } + + /** + * IN查询条件
+ * [SQL] AND fieldName IN (fieldValue1, fieldValue2, ...) + * + * @param fieldValues 字段值 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore in(Collection fieldValues) { + return this.on("in", fieldValues); + } + + /** + * IN查询条件
+ * [SQL] AND fieldName IN (fieldValue1, fieldValue2, ...) + * + * @param fieldValues 字段值 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore in(Serializable... fieldValues) { + return this.on("in", Arrays.asList(fieldValues)); + } + + /** + * NOT IN查询条件
+ * [SQL] AND fieldName NOT IN (fieldValue1, fieldValue2, ...) + * + * @param fieldValues 字段值 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore notIn(Collection fieldValues) { + return this.on("not in", fieldValues); + } + + /** + * NOT IN查询条件
+ * [SQL] AND fieldName NOT IN (fieldValue1, fieldValue2, ...) + * + * @param fieldValues 字段值 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore notIn(Serializable... fieldValues) { + return this.on("not in", Arrays.asList(fieldValues)); + } + + /** + * BETWEEN查询条件
+ * [SQL] AND fieldName BETWEEN startValue AND endValue
+ * 在常见数据库中, BETWEEN是包含两端的, 即 fieldName>=startValue AND fieldName<=endValue
+ * + * @param startValue 开始字段值 + * @param endValue 结束字段值 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore between(Serializable startValue, Serializable endValue) { + return this.on("between", startValue, endValue); + } + + /** + * NOT BETWEEN查询条件
+ * [SQL] AND fieldName NOT BETWEEN startValue AND endValue + * + * @param startValue 开始字段值 + * @param endValue 结束字段值 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore notBetween(Serializable startValue, Serializable endValue) { + return this.on("not between", startValue, endValue); + } + +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForFieldCore.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForFieldCore.java new file mode 100644 index 0000000000000000000000000000000000000000..269c898853b8b4d18814c780a56484da64e5f683 --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForFieldCore.java @@ -0,0 +1,37 @@ +package com.gitee.qdbp.able.jdbc.condition; + +import com.gitee.qdbp.able.enums.LogicType; + +/** + * 数据库Where条件容器 + * + * @author zhaohuihua + * @version 181221 + */ +public class DbWhereForFieldCore extends DbWhereForFieldBase { + + public DbWhereForFieldCore(DbWhereForStartCore parent, SkipType skipType, LogicType logicType, String fieldName) { + super(parent, skipType, logicType, fieldName); + } + + /** + * IS NULL条件
+ * [SQL] AND fieldName IS NULL + * + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore isNull() { + return this.on("is null"); + } + + /** + * IS NOT NULL条件
+ * [SQL] AND fieldName IS NOT NULL + * + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore isNotNull() { + return this.on("is not null"); + } + +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForFieldless.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForFieldless.java new file mode 100644 index 0000000000000000000000000000000000000000..31b62c77dc0a23f21ac2dc3bfcde1f6ee7754cfb --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForFieldless.java @@ -0,0 +1,120 @@ +package com.gitee.qdbp.able.jdbc.condition; + +import com.gitee.qdbp.able.enums.LogicType; +import com.gitee.qdbp.able.enums.MatchType; +import com.gitee.qdbp.able.jdbc.base.WhereCondition; +import com.gitee.qdbp.able.jdbc.condition.DbWhere.SubCondition; + +/** + * 数据库Where条件容器 + * + * @author zhaohuihua + * @version 181221 + */ +public class DbWhereForFieldless extends DbWhereBase { + + protected DbWhereForStartCore start; + protected SkipType skipType; + protected LogicType logicType; + + protected DbWhereForFieldless(DbWhereForStartCore start, SkipType skipType, LogicType logicType) { + super(start.root, start.items); + this.start = start; + this.skipType = skipType; + this.logicType = logicType; + } + + /** + * 子查询条件 + * + * @param logicType 逻辑类型 AND还是OR + * @param matchType 匹配类型 正向匹配还是反向匹配 + * @param condition 条件构造器 + * @return 返回后续流式操作对象 + */ + protected DbWhereForStartCore on(MatchType matchType, SubCondition condition) { + if (skipType == SkipType.NONE || skipType == SkipType.BLANK_VALUE && condition != null) { + this.put(logicType, matchType, condition); + } + return start; + } + + /** + * 自定义查询条件 + * + * @param condition 条件对象 + * @param logicType 逻辑类型 AND还是OR + * @param matchType 匹配类型 正向匹配还是反向匹配 + * @return 返回后续流式操作对象 + */ + protected DbWhereForStartCore on(MatchType matchType, WhereCondition condition) { + if (skipType == SkipType.NONE || skipType == SkipType.BLANK_VALUE && condition != null) { + this.put(logicType, matchType, condition); + } + return start; + } + + /** + * 子查询条件
+    // [SQL] AND ( USER_NAME LIKE '%'||keyword||'%' OR REAL_NAME LIKE '%'||keyword||'%' )
+    where.and().subCondition(new SubCondition() { // 子条件
+        public void build(DbWhere w) {
+            w.on("userName").like(entity.getKeyword())
+                .or("realName").like(entity.getKeyword());
+        }
+    });
+    // JDK8
+    where.and().subCondition((w) -> { // 子条件
+        w.on("userName").like(entity.getKeyword())
+            .or("realName").like(entity.getKeyword());
+    });
+ * + * @param condition 条件构造器 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore subCondition(SubCondition condition) { + return this.on(MatchType.Positive, condition); + } + + /** + * 否定子查询条件
+    // [SQL] AND NOT ( USER_NAME LIKE '%'||keyword||'%' OR REAL_NAME LIKE '%'||keyword||'%' )
+    where.and().notSubCondition(new SubCondition() { // 子条件
+        public void build(DbWhere w) {
+            w.on("userName").like(entity.getKeyword())
+                .or("realName").like(entity.getKeyword());
+        }
+    });
+    // JDK8
+    where.and().notSubCondition((w) -> { // 子条件
+        w.onLike("userName", entity.getKeyword())
+            .orLike("realName", entity.getKeyword());
+    });
+ * + * @param condition 条件构造器 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore notSubCondition(SubCondition condition) { + return this.on(MatchType.Negative, condition); + } + + /** + * 自定义查询条件 + * + * @param condition 条件对象 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore bizCondition(WhereCondition condition) { + return this.on(MatchType.Positive, condition); + } + + /** + * 自定义查询条件 + * + * @param condition 条件对象 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartCore notBizCondition(WhereCondition condition) { + return this.on(MatchType.Negative, condition); + } +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForOnFieldless.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForOnFieldless.java new file mode 100644 index 0000000000000000000000000000000000000000..d0a5224ac79bc7baed79c913474c07e2b5616fb5 --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForOnFieldless.java @@ -0,0 +1,65 @@ +package com.gitee.qdbp.able.jdbc.condition; + +import com.gitee.qdbp.able.enums.LogicType; + +/** + * 数据库Where条件容器 + * + * @author zhaohuihua + * @version 181221 + */ +public class DbWhereForOnFieldless extends DbWhereForFieldless { + + public DbWhereForOnFieldless(DbWhereForStartCore start, SkipType skipType) { + super(start, skipType, LogicType.AND); + } + + /** + * AND查询条件 + * + * @param fieldName 字段名称 + * @return 返回后续流式操作对象 + */ + public DbWhereForFieldCore and(String fieldName) { + return new DbWhereForFieldCore(start, skipType, LogicType.AND, fieldName); + } + + /** + * OR查询条件 + * + * @param fieldName 字段名称 + * @return 返回后续流式操作对象 + */ + public DbWhereForFieldCore or(String fieldName) { + return new DbWhereForFieldCore(start, skipType, LogicType.OR, fieldName); + } + + /** + * 只有当判断条件为true时才添加查询条件 + * + * @param ifValue 判断条件 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartContinue ifTrue(boolean ifValue) { + return new DbWhereForStartContinue(start, ifValue ? SkipType.NONE : SkipType.SKIP); + } + + /** + * 只有当目标值不为空时才添加查询条件 + * + * @param value 目标值 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartContinue ifHasValue(Object value) { + return new DbWhereForStartContinue<>(start, InnerUtils.isBlank(value) ? SkipType.SKIP : SkipType.NONE); + } + + /** + * 只有当字段值不为空时才添加查询条件 + * + * @return 返回后续流式操作对象 + */ + public DbWhereForStartByField ifHasValue() { + return new DbWhereForStartByField<>(start, SkipType.BLANK_VALUE); + } +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForStartAbstract.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForStartAbstract.java new file mode 100644 index 0000000000000000000000000000000000000000..5e44f420c591a162beba96051f9de43b2b222231 --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForStartAbstract.java @@ -0,0 +1,59 @@ +package com.gitee.qdbp.able.jdbc.condition; + +import com.gitee.qdbp.able.enums.LogicType; + +/** + * 数据库Where条件容器 + * + * @author zhaohuihua + * @version 181221 + */ +abstract class DbWhereForStartAbstract extends DbWhereBase { + + protected SkipType skipType; + + protected DbWhereForStartAbstract(T root, DbItems where, SkipType skipType) { + super(root, where); + this.skipType = skipType; + } + + protected abstract DbWhereForStartCore getStartWhere(); + + /** + * AND查询条件 + * + * @param fieldName 字段名称 + * @return 返回后续流式操作对象 + */ + public DbWhereForFieldCore and(String fieldName) { + return new DbWhereForFieldCore<>(getStartWhere(), skipType, LogicType.AND, fieldName); + } + + /** + * OR查询条件 + * + * @param fieldName 字段名称 + * @return 返回后续流式操作对象 + */ + public DbWhereForFieldCore or(String fieldName) { + return new DbWhereForFieldCore<>(getStartWhere(), skipType, LogicType.OR, fieldName); + } + + /** + * AND查询条件 + * + * @return 返回后续流式操作对象 + */ + public DbWhereForFieldless and() { + return new DbWhereForFieldless<>(getStartWhere(), skipType, LogicType.AND); + } + + /** + * OR查询条件 + * + * @return 返回后续流式操作对象 + */ + public DbWhereForFieldless or() { + return new DbWhereForFieldless<>(getStartWhere(), skipType, LogicType.OR); + } +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForStartByField.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForStartByField.java new file mode 100644 index 0000000000000000000000000000000000000000..3f163ae39120b2a842104dad58a09ac7a9389091 --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForStartByField.java @@ -0,0 +1,41 @@ +package com.gitee.qdbp.able.jdbc.condition; + +import com.gitee.qdbp.able.enums.LogicType; + +/** + * 数据库Where条件容器 + * + * @author zhaohuihua + * @version 181221 + */ +public class DbWhereForStartByField extends DbWhereBase { + + protected DbWhereForStartCore start; + private SkipType skipType; + + protected DbWhereForStartByField(DbWhereForStartCore start, SkipType skipType) { + super(start.root, start.items); + this.start = start; + this.skipType = skipType; + } + + /** + * AND查询条件 + * + * @param fieldName 字段名称 + * @return 返回后续流式操作对象 + */ + public DbWhereForFieldBase and(String fieldName) { + return new DbWhereForFieldBase<>(start, skipType, LogicType.AND, fieldName); + } + + /** + * OR查询条件 + * + * @param fieldName 字段名称 + * @return 返回后续流式操作对象 + */ + public DbWhereForFieldBase or(String fieldName) { + return new DbWhereForFieldBase<>(start, skipType, LogicType.OR, fieldName); + } +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForStartContinue.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForStartContinue.java new file mode 100644 index 0000000000000000000000000000000000000000..527ae05df5971b3110e5ecc6e36fed4c1de787f7 --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForStartContinue.java @@ -0,0 +1,22 @@ +package com.gitee.qdbp.able.jdbc.condition; + +/** + * 数据库Where条件容器 + * + * @author zhaohuihua + * @version 181221 + */ +public class DbWhereForStartContinue extends DbWhereForStartAbstract { + + protected DbWhereForStartCore start; + + protected DbWhereForStartContinue(DbWhereForStartCore start, SkipType skipType) { + super(start.root, start.items, skipType); + this.start = start; + } + + @Override + protected DbWhereForStartCore getStartWhere() { + return start; + } +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForStartCore.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForStartCore.java new file mode 100644 index 0000000000000000000000000000000000000000..577f2840d914f5bbd577a6ca94033f368940163d --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/DbWhereForStartCore.java @@ -0,0 +1,52 @@ +package com.gitee.qdbp.able.jdbc.condition; + +/** + * 数据库Where条件容器 + * + * @author zhaohuihua + * @version 181221 + */ +public class DbWhereForStartCore extends DbWhereForStartAbstract { + + public DbWhereForStartCore(T root, DbItems items) { + super(root, items, SkipType.NONE); + } + + @Override + protected DbWhereForStartCore getStartWhere() { + return this; + } + + public T end() { + return root; + } + + /** + * 只有当判断条件为true时才添加查询条件 + * + * @param ifValue 判断条件 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartContinue ifTrue(boolean ifValue) { + return new DbWhereForStartContinue(this, ifValue ? SkipType.NONE : SkipType.SKIP); + } + + /** + * 只有当目标值不为空时才添加查询条件 + * + * @param value 目标值 + * @return 返回后续流式操作对象 + */ + public DbWhereForStartContinue ifHasValue(Object value) { + return new DbWhereForStartContinue<>(this, InnerUtils.isBlank(value) ? SkipType.SKIP : SkipType.NONE); + } + + /** + * 只有当字段值不为空时才添加查询条件 + * + * @return 返回后续流式操作对象 + */ + public DbWhereForStartByField ifHasValue() { + return new DbWhereForStartByField<>(this, SkipType.BLANK_VALUE); + } +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/InnerUtils.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/InnerUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..e48a2f6fce20845e5b26a06f599ec256934b2ab4 --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/InnerUtils.java @@ -0,0 +1,21 @@ +package com.gitee.qdbp.able.jdbc.condition; + +import com.gitee.qdbp.tools.utils.VerifyTools; + +class InnerUtils { + + public static boolean isBlank(Object... fieldValues) { + if (fieldValues == null) { + return true; + } else if (fieldValues.length == 0) { + return true; + } else { + for (Object object : fieldValues) { + if (VerifyTools.isNotBlank(object)) { + return false; + } + } + return true; + } + } +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/LogicField.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/LogicField.java new file mode 100644 index 0000000000000000000000000000000000000000..6bf05f4400b0b38c50f5d25bf50fcb91e95ea322 --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/LogicField.java @@ -0,0 +1,65 @@ +package com.gitee.qdbp.able.jdbc.condition; + +import com.gitee.qdbp.able.enums.LogicType; +import com.gitee.qdbp.able.jdbc.base.LogicCondition; +import com.gitee.qdbp.tools.utils.VerifyTools; + +class LogicField extends DbField implements LogicCondition { + + /** serialVersionUID **/ + private static final long serialVersionUID = 1L; + + private final LogicType logicType; + + /** 构造函数 **/ + public LogicField(LogicType logicType) { + this.logicType = logicType; + } + + /** 构造函数 **/ + protected LogicField(LogicType logicType, DbField field) { + super(field.getOperateType(), field.getFieldName(), field.getFieldValue()); + this.logicType = logicType; + } + + /** 构造函数 **/ + public LogicField(LogicType logicType, String fieldName, Object fieldValue) { + super(fieldName, fieldValue); + this.logicType = logicType; + } + + /** 构造函数 **/ + public LogicField(LogicType logicType, String operateType, String fieldName, Object fieldValue) { + super(operateType, fieldName, fieldValue); + this.logicType = logicType; + } + + @Override + public LogicType getLogicType() { + return logicType; + } + + @Override + public LogicField copy() { + LogicType logicType = this.getLogicType(); + String operateType = this.getOperateType(); + String fieldName = this.getFieldName(); + Object fieldValue = this.getFieldValue(); + return new LogicField(logicType, operateType, fieldName, fieldValue); + } + + public static LogicField of(LogicType logicType, String fieldName, String operate, Object... fieldValues) { + VerifyTools.nvl(fieldName, "fieldName"); + LogicField condition = new LogicField(logicType); + condition.setFieldName(fieldName); + condition.setOperateType(operate); + if (fieldValues != null && fieldValues.length > 0) { + if (fieldValues.length == 1) { + condition.setFieldValue(fieldValues[0]); + } else { + condition.setFieldValue(fieldValues); + } + } + return condition; + } +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/SkipType.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/SkipType.java new file mode 100644 index 0000000000000000000000000000000000000000..c666ab44b7a84e1b4bdb117b945e0d9f852fda5c --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/SkipType.java @@ -0,0 +1,11 @@ +package com.gitee.qdbp.able.jdbc.condition; + + +public enum SkipType { + /** 不跳过 **/ + NONE, + /** 始终跳过 **/ + SKIP, + /** 字段值为空时跳过 **/ + BLANK_VALUE +} diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/SubWhere.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/SubWhere.java index 1d915c99baed84feb9e6b62f87ce28b5f3245c96..fa476407c8389aa97b5133e14c7bc2fa98972e5d 100644 --- a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/SubWhere.java +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/SubWhere.java @@ -4,7 +4,6 @@ import com.gitee.qdbp.able.enums.LogicType; import com.gitee.qdbp.able.enums.MatchType; import com.gitee.qdbp.able.jdbc.base.LogicCondition; import com.gitee.qdbp.able.jdbc.base.MatchCondition; -import com.gitee.qdbp.able.jdbc.base.WhereCondition; /** * 子查询条件 @@ -17,8 +16,6 @@ public class SubWhere extends DbWhere implements LogicCondition, MatchCondition /** SerialVersionUID **/ private static final long serialVersionUID = 1L; - /** 所属上级 **/ - private DbWhere parent; /** 逻辑联连类型: AND / OR **/ private LogicType logicType; /** 匹配模式 **/ @@ -27,35 +24,11 @@ public class SubWhere extends DbWhere implements LogicCondition, MatchCondition protected SubWhere() { } - public SubWhere(DbWhere parent, LogicType logicType, MatchType matchType) { - this.parent = parent; + protected SubWhere(LogicType logicType, MatchType matchType) { this.logicType = logicType; this.matchType = matchType; } - @Override - public SubWhere on(String fieldName, String operate, Object... fieldValues) { - super.on(fieldName, operate, fieldValues); - return this; - } - - /** 增加自定义条件 **/ - @Override - public SubWhere on(WhereCondition condition) { - super.put(condition); - return this; - } - - /** 返回上级 **/ - public DbWhere end() { - return this.parent; - } - - protected DbWhere setParent(DbWhere parent) { - this.parent = parent; - return this; - } - /** 逻辑联连类型: AND / OR **/ @Override public LogicType getLogicType() { @@ -88,7 +61,6 @@ public class SubWhere extends DbWhere implements LogicCondition, MatchCondition protected void copyTo(SubWhere copies) { super.copyTo(copies); - copies.parent = this.parent; copies.logicType = this.logicType; copies.matchType = this.matchType; } diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/TableJoin.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/TableJoin.java index 4d4da140e40ced9e2b400cd3ee99d2b7826f6614..e99daf3edb39f55669eca6eea695c6238081e47b 100644 --- a/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/TableJoin.java +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/condition/TableJoin.java @@ -3,6 +3,7 @@ package com.gitee.qdbp.able.jdbc.condition; import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import com.gitee.qdbp.able.enums.LogicType; import com.gitee.qdbp.tools.utils.NamingTools; import com.gitee.qdbp.tools.utils.VerifyTools; @@ -24,20 +25,21 @@ import com.gitee.qdbp.tools.utils.VerifyTools; *
     List<String> userCodes = Arrays.asList("evan", "kelly", "coral");
     // @formatter:off
-    TableJoin tables = new TableJoin(SysUser.class, "u", "user")
+    TableJoin tables = new TableJoin(SysUser.class, "u").saveTo("user")
         .innerJoin(SysUserRole.class, "ur")
-        .on("u.id", "=", "ur.userId")
-        .and("ur.dataState", "=", 1)
-        .innerJoin(SysRole.class, "r", "role")
-        .on("ur.roleId", "=", "r.id")
-        .and("r.dataState", "=", 1)
+            .on("u.id").equals("ur.userId")
+            .and("ur.dataState").equals(1)
+            .end()
+        .innerJoin(SysRole.class, "r").saveTo("role")
+            .on("ur.roleId").equals("r.id")
+            .and("r.dataState").equals(1)
         .end();
     // @formatter:on
     // UserRole = { SysUser user; SysRole role; }
     // 这里不关注SysUserRole
     // 因此innerJoin(SysUserRole.class, "ur")未指定第3个参数resultField
     // 不会出现在SELECT后面的字段列表中, 也就不会保存查询结果
-    JoinQueryer<UserRole> query = qdbcBoot.buildJoinQuery(tables, UserRole.class);
+    JoinQueryer<UserRole> query = qdbcBoot.joinQueryer(tables, UserRole.class);
     DbWhere where = new DbWhere();
     where.on("u.userCode", "in", userCodes);
     PageList<UserRole> userRoles = query.list(where, OrderPaging.NONE);
@@ -57,7 +59,7 @@ import com.gitee.qdbp.tools.utils.VerifyTools;
     // @formatter:on
     DbWhere where = new DbWhere();
     where.on("u.userId", "=", userId);
-    JoinQueryer<SysRole> query = qdbcBoot.buildJoinQuery(tables, SysRole.class);
+    JoinQueryer<SysRole> query = qdbcBoot.joinQueryer(tables, SysRole.class);
     PageList<SysRole> roles = query.list(where, OrderPaging.NONE);
     log.debug("RolesQueryByUser: {}", JsonTools.toLogString(roles));
  * 
@@ -88,19 +90,18 @@ public class TableJoin implements Serializable { } /** - * 构造函数 + * 设置数据保存字段名 * - * @param tableType 主表类型 - * @param tableAlias 主表别名 - * @param resultField 数据保存至结果类的哪个字段(子对象), this表示结果字段放在主对象中 + * @param resultField 数据保存至结果类的哪个字段(子对象), "this"表示结果字段放在主对象中 + * @return 返回当前对象 */ - public TableJoin(Class tableType, String tableAlias, String resultField) { - this.major = new TableItem(tableType, tableAlias, resultField); - this.joins = new ArrayList<>(); + public TableJoin saveTo(String resultField) { + this.major.resultField = resultField; + return this; } /** - * 增加 inner join 表连接, 仅用于表关联, 不取返回结果(如果需要返回结果请添加resultField字段) + * 增加 inner join 表连接 * * @param tableType 表类型 * @param tableAlias 表别名 @@ -143,61 +144,13 @@ public class TableJoin implements Serializable { return joinStart(tableType, tableAlias, JoinType.FullJoin); } - /** - * 增加 inner join 表连接 - * - * @param tableType 表类型 - * @param tableAlias 表别名 - * @param resultField 数据保存至结果类的哪个字段(子对象), this表示结果字段放在主对象中 - * @return JoinStart 用于添加on条件 - */ - public JoinStart innerJoin(Class tableType, String tableAlias, String resultField) { - return joinStart(tableType, tableAlias, resultField, JoinType.InnerJoin); - } - - /** - * 增加 left join 表连接 - * - * @param tableType 表类型 - * @param tableAlias 表别名 - * @param resultField 数据保存至结果类的哪个字段(子对象), this表示结果字段放在主对象中 - * @return JoinStart 用于添加on条件 - */ - public JoinStart leftJoin(Class tableType, String tableAlias, String resultField) { - return joinStart(tableType, tableAlias, resultField, JoinType.LeftJoin); - } - - /** - * 增加 right join 表连接 - * - * @param tableType 表类型 - * @param tableAlias 表别名 - * @param resultField 数据保存至结果类的哪个字段(子对象), this表示结果字段放在主对象中 - * @return JoinStart 用于添加on条件 - */ - public JoinStart rightJoin(Class tableType, String tableAlias, String resultField) { - return joinStart(tableType, tableAlias, resultField, JoinType.RightJoin); - } - - /** - * 增加 full join 表连接 - * - * @param tableType 表类型 - * @param tableAlias 表别名 - * @param resultField 数据保存至结果类的哪个字段(子对象), this表示结果字段放在主对象中 - * @return JoinStart 用于添加on条件 - */ - public JoinStart fullJoin(Class tableType, String tableAlias, String resultField) { - return joinStart(tableType, tableAlias, resultField, JoinType.FullJoin); - } - /** 主表 **/ public TableItem getMajor() { return major; } /** 主表 **/ - public void setMajor(TableItem major) { + protected void setMajor(TableItem major) { this.major = major; } @@ -207,7 +160,7 @@ public class TableJoin implements Serializable { } /** 关联表 **/ - public void setJoins(List joins) { + protected void setJoins(List joins) { this.joins = joins; } @@ -259,7 +212,7 @@ public class TableJoin implements Serializable { } /** 表类型 **/ - public void setTableType(Class tableType) { + protected void setTableType(Class tableType) { this.tableType = tableType; } @@ -269,7 +222,7 @@ public class TableJoin implements Serializable { } /** 别名 **/ - public void setTableAlias(String tableAlias) { + protected void setTableAlias(String tableAlias) { this.tabletableAlias = tableAlias; } @@ -279,10 +232,9 @@ public class TableJoin implements Serializable { } /** 数据保存至结果类的哪个字段(子对象), this表示结果字段放在主对象中 **/ - public void setResultField(String resultField) { + protected void setResultField(String resultField) { this.resultField = resultField; } - } public static class JoinItem extends TableItem { @@ -306,6 +258,16 @@ public class TableJoin implements Serializable { this.joinType = joinType; this.where = where; } + /** + * 设置数据保存字段名 + * + * @param resultField 数据保存至结果类的哪个字段(子对象), "this"表示结果字段放在主对象中 + * @return 返回当前对象 + */ + public JoinItem saveTo(String resultField) { + this.setResultField(resultField); + return this; + } /** 连接类型 **/ public JoinType getJoinType() { @@ -313,7 +275,7 @@ public class TableJoin implements Serializable { } /** 连接类型 **/ - public void setJoinType(JoinType type) { + protected void setJoinType(JoinType type) { this.joinType = type; } @@ -323,7 +285,7 @@ public class TableJoin implements Serializable { } /** 连接条件 **/ - public void setWhere(DbWhere where) { + protected void setWhere(DbWhere where) { this.where = where; } @@ -339,10 +301,29 @@ public class TableJoin implements Serializable { this.join = join; } + /** + * 设置数据保存字段名 + * + * @param resultField 数据保存至结果类的哪个字段(子对象), "this"表示结果字段放在主对象中 + * @return 返回当前对象 + */ + public JoinStart saveTo(String resultField) { + this.join.current.setResultField(resultField); + return this; + } + /** 增加连接条件 **/ - public JoinOn on(String fieldName, String operate, Object... fieldValues) { - this.join.current.where.on(fieldName, operate, fieldValues); - return new JoinOn(join); + public DbWhereForFieldCore on(String fieldName) { + JoinOn next = new JoinOn(join); + DbWhereForStartCore start = new DbWhereForStartCore<>(next, this.join.current.where); + return new DbWhereForFieldCore<>(start, SkipType.NONE, LogicType.AND, fieldName); + } + + /** 增加连接条件 **/ + public DbWhereForOnFieldless on() { + JoinOn next = new JoinOn(join); + DbWhereForStartCore start = new DbWhereForStartCore<>(next, this.join.current.where); + return new DbWhereForOnFieldless<>(start, SkipType.NONE); } public TableJoin end() { @@ -364,12 +345,6 @@ public class TableJoin implements Serializable { return this.join; } - /** 增加连接条件 **/ - public JoinOn and(String fieldName, String operate, Object... fieldValues) { - this.join.current.where.on(fieldName, operate, fieldValues); - return this; - } - /** 增加InnerJoin表连接 **/ public JoinStart innerJoin(Class tableType, String tableAlias) { return this.join.joinStart(tableType, tableAlias, JoinType.InnerJoin); @@ -390,25 +365,6 @@ public class TableJoin implements Serializable { return this.join.joinStart(tableType, tableAlias, JoinType.FullJoin); } - /** 增加InnerJoin表连接 **/ - public JoinStart innerJoin(Class tableType, String tableAlias, String resultField) { - return this.join.joinStart(tableType, tableAlias, resultField, JoinType.InnerJoin); - } - - /** 增加LeftJoin表连接 **/ - public JoinStart leftJoin(Class tableType, String tableAlias, String resultField) { - return this.join.joinStart(tableType, tableAlias, resultField, JoinType.LeftJoin); - } - - /** 增加RightJoin表连接 **/ - public JoinStart rightJoin(Class tableType, String tableAlias, String resultField) { - return this.join.joinStart(tableType, tableAlias, resultField, JoinType.RightJoin); - } - - /** 增加FullJoin表连接 **/ - public JoinStart fullJoin(Class tableType, String tableAlias, String resultField) { - return this.join.joinStart(tableType, tableAlias, resultField, JoinType.FullJoin); - } } public static String buildCacheKey(TableJoin tables, boolean simpleName) { @@ -443,17 +399,17 @@ public class TableJoin implements Serializable { return buildCacheKey(this, true); } - /** 构造多表关联关系, 由于缺少on语句, 只能用于qdbcBoot.buildSqlBuilder(tables), 不能用于qdbcBoot.buildJoinQuery(tables) **/ + /** 构造多表关联关系, 由于缺少on语句, 只能用于qdbcBoot.sqlBuilder(tables), 不能用于qdbcBoot.joinQueryer(tables) **/ public static TableJoin of(Class clazz1, String alias1) { return new TableJoin(clazz1, alias1); } - /** 构造多表关联关系, 由于缺少on语句, 只能用于qdbcBoot.buildSqlBuilder(tables), 不能用于qdbcBoot.buildJoinQuery(tables) **/ + /** 构造多表关联关系, 由于缺少on语句, 只能用于qdbcBoot.sqlBuilder(tables), 不能用于qdbcBoot.joinQueryer(tables) **/ public static TableJoin of(Class clazz1, String alias1, Class clazz2, String alias2) { return new TableJoin(clazz1, alias1).innerJoin(clazz2, alias2).end(); } - /** 构造多表关联关系, 由于缺少on语句, 只能用于qdbcBoot.buildSqlBuilder(tables), 不能用于qdbcBoot.buildJoinQuery(tables) **/ + /** 构造多表关联关系, 由于缺少on语句, 只能用于qdbcBoot.sqlBuilder(tables), 不能用于qdbcBoot.joinQueryer(tables) **/ public static TableJoin of(Class clazz1, String alias1, Class clazz2, String alias2, Class clazz3, String alias3) { TableJoin tables = new TableJoin(clazz1, alias1); @@ -462,7 +418,7 @@ public class TableJoin implements Serializable { return tables; } - /** 构造多表关联关系, 由于缺少on语句, 只能用于qdbcBoot.buildSqlBuilder(tables), 不能用于qdbcBoot.buildJoinQuery(tables) **/ + /** 构造多表关联关系, 由于缺少on语句, 只能用于qdbcBoot.sqlBuilder(tables), 不能用于qdbcBoot.joinQueryer(tables) **/ public static TableJoin of(Class clazz1, String alias1, Class clazz2, String alias2, Class clazz3, String alias3, Class clazz4, String alias4) { TableJoin tables = new TableJoin(clazz1, alias1); @@ -472,7 +428,7 @@ public class TableJoin implements Serializable { return tables; } - /** 构造多表关联关系, 由于缺少on语句, 只能用于qdbcBoot.buildSqlBuilder(tables), 不能用于qdbcBoot.buildJoinQuery(tables) **/ + /** 构造多表关联关系, 由于缺少on语句, 只能用于qdbcBoot.sqlBuilder(tables), 不能用于qdbcBoot.joinQueryer(tables) **/ public static TableJoin of(Class clazz1, String alias1, Class clazz2, String alias2, Class clazz3, String alias3, Class clazz4, String alias4, Class clazz5, String alias5) { TableJoin tables = new TableJoin(clazz1, alias1); @@ -483,7 +439,7 @@ public class TableJoin implements Serializable { return tables; } - /** 构造多表关联关系, 由于缺少on语句, 只能用于qdbcBoot.buildSqlBuilder(tables), 不能用于qdbcBoot.buildJoinQuery(tables) **/ + /** 构造多表关联关系, 由于缺少on语句, 只能用于qdbcBoot.sqlBuilder(tables), 不能用于qdbcBoot.joinQueryer(tables) **/ public static TableJoin of(Class clazz1, String alias1, Class clazz2, String alias2, Class clazz3, String alias3, Class clazz4, String alias4, Class clazz5, String alias5, Class clazz6, String alias6) { diff --git a/able/src/main/java/com/gitee/qdbp/able/jdbc/ordering/Orderings.java b/able/src/main/java/com/gitee/qdbp/able/jdbc/ordering/Orderings.java index eb89d0268b011f5b601f5ae6ff0a34dc72534158..2101bd9ace57cc397b8845045cd373042e2ade33 100644 --- a/able/src/main/java/com/gitee/qdbp/able/jdbc/ordering/Orderings.java +++ b/able/src/main/java/com/gitee/qdbp/able/jdbc/ordering/Orderings.java @@ -82,20 +82,20 @@ public class Orderings extends ArrayList implements Serializable { container.add(ordering); String word = sa.readWord(); if (!sa.isLastReadSuccess()) { - throw new IllegalArgumentException("OrderBy format error: " + sa.readToEnd(index)); + throw new IllegalArgumentException("OrderBy format error: " + sa.peekToEnd(index)); } sa.skipWhitespace(); char nextChar = sa.peekChar(); if (nextChar == '.') { // t.userName String temp = sa.skipChar().readWord(); if (!sa.isLastReadSuccess()) { - throw new IllegalArgumentException("OrderBy format error: " + sa.readToEnd(index)); + throw new IllegalArgumentException("OrderBy format error: " + sa.peekToEnd(index)); } ordering.setOrderBy(word + '.' + temp); } else if (nextChar == '(') { // pinyin(userName) List params = sa.readMethodParams(); if (!sa.isLastReadSuccess()) { - throw new IllegalArgumentException("OrderBy format error: " + sa.readToEnd(index)); + throw new IllegalArgumentException("OrderBy format error: " + sa.peekToEnd(index)); } ordering.setFunctionName(word); // 查找第1个没有单引号包围且不是数字/Boolean/null的字段 @@ -119,34 +119,34 @@ public class Orderings extends ArrayList implements Serializable { } sa.skipWhitespace(); if (!sa.isReadable()) { - ordering.setOriginal(sa.readFrom(index).trim()); + ordering.setOriginal(sa.peekFrom(index).trim()); } else { if (sa.peekChar() == ',') { - ordering.setOriginal(sa.readFrom(index).trim()); + ordering.setOriginal(sa.peekFrom(index).trim()); sa.skipChar(); continue; } String orderType = sa.readWord(); if (!sa.isLastReadSuccess()) { // 既不是逗号也不是单词 - throw new IllegalArgumentException("OrderBy format error: " + sa.readToEnd(index)); + throw new IllegalArgumentException("OrderBy format error: " + sa.peekToEnd(index)); } if ("ASC".equalsIgnoreCase(orderType)) { ordering.setOrderType(OrderType.ASC); } else if ("DESC".equalsIgnoreCase(orderType)) { ordering.setOrderType(OrderType.DESC); } else { // 既不是ASC也不是DESC - throw new IllegalArgumentException("OrderBy format error: " + sa.readFrom(index)); + throw new IllegalArgumentException("OrderBy format error: " + sa.peekFrom(index)); } sa.skipWhitespace(); if (!sa.isReadable()) { - ordering.setOriginal(sa.readFrom(index).trim()); + ordering.setOriginal(sa.peekFrom(index).trim()); } else { if (sa.peekChar() == ',') { - ordering.setOriginal(sa.readFrom(index).trim()); + ordering.setOriginal(sa.peekFrom(index).trim()); sa.skipChar(); } else { - throw new IllegalArgumentException("OrderBy format error: " + sa.readToEnd(index)); + throw new IllegalArgumentException("OrderBy format error: " + sa.peekToEnd(index)); } } } diff --git a/able/src/main/java/com/gitee/qdbp/eachfile/process/BaseFileProcessor.java b/able/src/main/java/com/gitee/qdbp/eachfile/process/BaseFileProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..997937623c569354463ae3f0f4db64f9f9fc6dc2 --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/eachfile/process/BaseFileProcessor.java @@ -0,0 +1,205 @@ +package com.gitee.qdbp.eachfile.process; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; +import com.gitee.qdbp.able.debug.Debugger; +import com.gitee.qdbp.tools.files.PathTools; +import com.gitee.qdbp.tools.utils.StringTools; + +/** + * 文件处理接口
+ * 包含与排除不能同时设置(如果同时设置以包含为准) + * + * @author zhaohuihua + * @version 20200218 + */ +public abstract class BaseFileProcessor implements FileProcessor, Debugger.Aware { + + /** 是否跳过文件夹 **/ + private boolean skipFolder; + /** 是否跳过文件 **/ + private boolean skipFile; + /** 包含的文件夹 **/ + private Map includeFolders; + /** 排除的文件夹 **/ + private Map excludeFolders; + /** 包含的文件名 **/ + private Map includeFileNames; + /** 排除的文件名 **/ + private Map excludeFileNames; + /** 包含的文件类型 **/ + private Map includeFileTypes; + /** 排除的文件类型 **/ + private Map excludeFileTypes; + /** 包含的文件名正则表达式 **/ + private Pattern includeFilePattern; + /** 排除的文件名正则表达式 **/ + private Pattern excludeFilePattern; + /** 日志接口 **/ + private Debugger debugger; + + public BaseFileProcessor(boolean skipFolder, boolean skipFile) { + this.skipFolder = skipFolder; + this.skipFile = skipFile; + } + + protected void setIncludeFolders(String... includeFolders) { + this.includeFolders = toKeyMaps(includeFolders); + } + + protected void setExcludeFolders(String... excludeFolders) { + this.excludeFolders = toKeyMaps(excludeFolders); + } + + protected void setIncludeFileNames(String... includeFileNames) { + this.includeFileNames = toKeyMaps(includeFileNames); + } + + protected void setExcludeFileNames(String... excludeFileNames) { + this.excludeFileNames = toKeyMaps(excludeFileNames); + } + + protected void setIncludeFileTypes(String... includeFileTypes) { + this.includeFileTypes = toKeyMaps(includeFileTypes); + } + + protected void setExcludeFileTypes(String... excludeFileTypes) { + this.excludeFileTypes = toKeyMaps(excludeFileTypes); + } + + protected void setIncludeFilePattern(String includeFilePattern) { + this.includeFilePattern = Pattern.compile(includeFilePattern, Pattern.CASE_INSENSITIVE); + } + + protected void setIncludeFilePattern(Pattern includeFilePattern) { + this.includeFilePattern = includeFilePattern; + } + + protected void setExcludeFilePattern(String excludeFilePattern) { + this.excludeFilePattern = Pattern.compile(excludeFilePattern, Pattern.CASE_INSENSITIVE); + } + + protected void setExcludeFilePattern(Pattern excludeFilePattern) { + this.excludeFilePattern = excludeFilePattern; + } + + public static Map toKeyMaps(String... keys) { + Map map = new HashMap<>(); + for (String item : keys) { + String[] array = StringTools.split(item, ','); + for (String key : array) { + map.put(key == null ? null : key.toLowerCase(), null); + } + } + return map; + } + + /** + * 检查文件 + * + * @param root 根目录 + * @param file 待处理的文件 + * @return 是否处理 + */ + protected boolean doFileCheck(String root, File file) { + return true; + } + + /** + * 处理文件 + * + * @param root 根目录 + * @param file 待处理的文件 + */ + protected void doFileProcess(String root, File file) { + } + + /** + * 检查文件夹 + * + * @param root 根目录 + * @param folder 待处理的文件夹 + * @return 是否继续, true表示继续处理文件夹中的文件或子文件夹, false表示跳过文件夹 + */ + protected boolean doFolderCheck(String root, File folder) { + return true; + } + + /** + * 处理文件夹 + * + * @param root 根目录 + * @param folder 待处理的文件夹 + * @return 是否继续, true表示继续处理文件夹中的文件或子文件夹, false表示跳过文件夹 + */ + protected boolean doFolderProcess(String root, File folder) { + return true; + } + + @Override + public final void fileProcess(String root, File file) { + String fileName = file.getName().toLowerCase(); + if (includeFileNames != null && !includeFileNames.containsKey(fileName)) { + return; + } else if (excludeFileNames != null && excludeFileNames.containsKey(fileName)) { + return; + } + String extension = PathTools.getExtension(fileName, false); + if (extension != null) { + extension = extension.toLowerCase(); + } + if (includeFileTypes != null && !includeFileTypes.containsKey(extension)) { + return; + } else if (excludeFileTypes != null && excludeFileTypes.containsKey(extension)) { + return; + } + if (includeFilePattern != null && !includeFilePattern.matcher(fileName).find()) { + return; + } else if (excludeFilePattern != null && excludeFilePattern.matcher(fileName).find()) { + return; + } + if (!doFileCheck(root, file)) { + return; + } + if (skipFile) { + return; + } + doFileProcess(root, file); + } + + @Override + public final boolean folderProcess(String root, File folder) { + String fileName = folder.getName().toLowerCase(); + if (includeFolders != null && !includeFolders.containsKey(fileName)) { + return false; + } else if (excludeFolders != null && excludeFolders.containsKey(fileName)) { + return false; + } + if (!doFolderCheck(root, folder)) { + return false; + } + if (skipFolder) { + return true; + } + return doFolderProcess(root, folder); + } + + /** 日志接口 **/ + public Debugger getDebugger() { + return debugger; + } + + /** 日志接口 **/ + @Override + public void setDebugger(Debugger listener) { + this.debugger = listener; + } + + protected void debug(String message, Object... args) { + if (this.debugger != null) { + this.debugger.debug(message, args); + } + } +} diff --git a/able/src/main/java/com/gitee/qdbp/eachfile/process/FileProcessor.java b/able/src/main/java/com/gitee/qdbp/eachfile/process/FileProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..149d47687b9b8dd78be8cfe54a7d8149ea46214d --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/eachfile/process/FileProcessor.java @@ -0,0 +1,29 @@ +package com.gitee.qdbp.eachfile.process; + +import java.io.File; + +/** + * 文件处理接口 + * + * @author zhaohuihua + * @version 20200218 + */ +public interface FileProcessor { + + /** + * 处理文件 + * + * @param root 根目录 + * @param file 待处理的文件 + */ + void fileProcess(String root, File file); + + /** + * 处理文件夹 + * + * @param root 根目录 + * @param folder 待处理的文件夹 + * @return 是否继续, false表示跳过后面的文件 + */ + boolean folderProcess(String root, File folder); +} diff --git a/able/src/main/java/com/gitee/qdbp/eachfile/process/FilterFileProcessor.java b/able/src/main/java/com/gitee/qdbp/eachfile/process/FilterFileProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..91c1e84b46f5784c98727babac7706b79d3bf1e3 --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/eachfile/process/FilterFileProcessor.java @@ -0,0 +1,66 @@ +package com.gitee.qdbp.eachfile.process; + +import java.util.regex.Pattern; + +/** + * 可以设置限制条件的处理器 + * + * @author zhaohuihua + * @version 20200426 + */ +public abstract class FilterFileProcessor extends BaseFileProcessor { + + public FilterFileProcessor(boolean skipFolder, boolean skipFile) { + super(skipFolder, skipFile); + } + + @Override + public void setIncludeFolders(String... includeFolders) { + super.setIncludeFolders(includeFolders); + } + + @Override + public void setExcludeFolders(String... excludeFolders) { + super.setExcludeFolders(excludeFolders); + } + + @Override + public void setIncludeFileNames(String... includeFileNames) { + super.setIncludeFileNames(includeFileNames); + } + + @Override + public void setExcludeFileNames(String... excludeFileNames) { + super.setExcludeFileNames(excludeFileNames); + } + + @Override + public void setIncludeFileTypes(String... includeFileTypes) { + super.setIncludeFileTypes(includeFileTypes); + } + + @Override + public void setExcludeFileTypes(String... excludeFileTypes) { + super.setExcludeFileTypes(excludeFileTypes); + } + + @Override + public void setIncludeFilePattern(String includeFilePattern) { + super.setIncludeFilePattern(includeFilePattern); + } + + @Override + public void setIncludeFilePattern(Pattern includeFilePattern) { + super.setIncludeFilePattern(includeFilePattern); + } + + @Override + public void setExcludeFilePattern(String excludeFilePattern) { + super.setExcludeFilePattern(excludeFilePattern); + } + + @Override + public void setExcludeFilePattern(Pattern excludeFilePattern) { + super.setExcludeFilePattern(excludeFilePattern); + } +} diff --git a/able/src/main/java/com/gitee/qdbp/eachfile/runner/FileEachRunner.java b/able/src/main/java/com/gitee/qdbp/eachfile/runner/FileEachRunner.java new file mode 100644 index 0000000000000000000000000000000000000000..875d282085c1cbca2c994959a4c18bd364f0030e --- /dev/null +++ b/able/src/main/java/com/gitee/qdbp/eachfile/runner/FileEachRunner.java @@ -0,0 +1,156 @@ +package com.gitee.qdbp.eachfile.runner; + +import java.io.File; +import java.io.FileFilter; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.net.URLDecoder; +import com.gitee.qdbp.able.debug.ConsoleDebugger; +import com.gitee.qdbp.able.debug.Debugger; +import com.gitee.qdbp.eachfile.process.FileProcessor; +import com.gitee.qdbp.tools.files.PathTools; +import com.gitee.qdbp.tools.utils.StringTools; +import com.gitee.qdbp.tools.wait.SingleLock; + +/** + * 文件遍历工具 + * + * @author zhaohuihua + * @version 190719 + */ +public class FileEachRunner extends Thread { + + private final String root; + private final FileProcessor processor; + private final FileFilter fileFilter; + private final Debugger debugger; + private SingleLock lock; + + public FileEachRunner(String root, FileProcessor processor) { + this(root, null, processor, null); + } + + public FileEachRunner(String root, FileProcessor processor, Debugger listener) { + this(root, null, processor, listener); + } + + public FileEachRunner(String root, FileFilter fileFilter, FileProcessor processor, Debugger debugger) { + this.root = PathTools.concat(true, root, "/"); + this.fileFilter = fileFilter; + this.processor = processor; + this.debugger = debugger != null ? debugger : new ConsoleDebugger(); + if (this.processor instanceof Debugger.Aware) { + ((Debugger.Aware) this.processor).setDebugger(this.debugger); + } + } + + @Override + public void run() { + File folder = new File(root); + if (!checkRoot(folder)) { + return; + } + + each(folder); + + if (lock != null) { + lock.signal(); + } + } + + public void await() { + if (this.lock == null) { + this.lock = new SingleLock(); + this.lock.await(); + } + } + + protected void each(File folder) { + File[] files; + if (fileFilter == null) { + files = folder.listFiles(); + } else { + files = folder.listFiles(fileFilter); + } + if (files == null || files.length == 0) { + return; + } + for (File file : files) { + if (file.isFile()) { + processor.fileProcess(root, file); + } else if (file.isDirectory()) { + boolean isContinue = processor.folderProcess(root, file); + if (isContinue) { + each(file); + } + } + } + } + + protected boolean checkRoot(File root) { + if (root.isFile()) { + debugger.debug("根路径必须是文件夹"); + return false; + } else { + return true; + } + } + + public String getRoot() { + return root; + } + + public FileProcessor getProcessor() { + return processor; + } + + public FileFilter getFileFilter() { + return fileFilter; + } + + public Debugger getDebugger() { + return debugger; + } + + + /** + * 获取指定类所在的classpath + * + * @param clazz 指定类 + * @return classpath + */ + public static String getClasspath(Class clazz) { + // 获取与JAR包自身所在的文件夹 + // project-path/target/classes/ + URL url = clazz.getResource("/"); + if (url != null) { + return PathTools.toUriPath(url); + } else { // jar包中获取为空 + // project-path/target/classes/com/gitee/qdbp/.../ + // jar:file:/F:/project-path/xxx.jar!/com/gitee/qdbp/.../ + url = clazz.getResource(""); + String p = PathTools.toUriPath(url); + p = StringTools.removePrefix(p, "jar://"); + p = StringTools.removePrefix(p, "jar:"); + p = StringTools.removePrefix(p, "file:"); + int index = p.indexOf('!'); + if (index > 0) { + p = PathTools.removeFileName(p.substring(0, index)); + } + if ((p.length() > 2) && (p.charAt(2) == ':')) { + // "/c:/foo/" --> "c:/foo/" + p = p.substring(1); + } + if (!new File(p).exists() && p.contains("%")) { + try { + p = URLDecoder.decode(p, "UTF-8"); + if (!new File(p).exists()) { + p = URLDecoder.decode(p, "GBK"); + } + } catch (UnsupportedEncodingException e) { + } + } + return p; + } + } +} diff --git a/able/src/main/java/com/gitee/qdbp/tools/parse/StringAccess.java b/able/src/main/java/com/gitee/qdbp/tools/parse/StringAccess.java index 737754c78c71b7cf7973899edbba7531efa1d17b..ace4370add93639a08ffdeb122a6c067adefffc9 100644 --- a/able/src/main/java/com/gitee/qdbp/tools/parse/StringAccess.java +++ b/able/src/main/java/com/gitee/qdbp/tools/parse/StringAccess.java @@ -4,7 +4,10 @@ import java.util.ArrayList; import java.util.List; /** - * 字符串访问工具类 + * 字符串访问工具类
+ * 总规则:
+ * -- peekXxx不会移动index; readXxx会移动index
+ * -- 如果已到最后, 将设置lastReadSuccess=true并返回null
* * @author zhaohuihua * @version 20210430 @@ -35,7 +38,7 @@ public class StringAccess { * @param string 源字符串 * @param index 开始位置 * @param multiline 是否支持多行模式: false=最多读取至行尾; true=最多读取至文本结束
- * 如 (1\n2) 在多行模式下正确; 在单行模式下会报错(因为读取到行尾都没找到结束的括号) + * 如 读取括号中的内容, (1\n2) 在多行模式下正确; 在单行模式下会报错(因为读取到行尾都没找到结束的括号) */ public StringAccess(String string, int index, boolean multiline) { this.string = string; @@ -124,13 +127,83 @@ public class StringAccess { } public StringAccess skipChars(int size) { - if (index < length) { - index += size; - } + this.index = Math.min(index + size, length); this.lastReadSuccess = true; return this; } + /** + * 读取几个字符
+ * 如果不够读取的数量, 将设置lastReadSuccess=false并返回null + * + * @param size 期望读取的数量 + * @return 字符串 + */ + public String readChars(int size) { + if (index >= length) { + this.lastReadSuccess = true; + return null; + } else if (index + size > length) { + this.lastReadSuccess = false; + return null; + } else { + int endIndex = index + size; + String substring = string.substring(index, endIndex); + this.index = endIndex; + this.lastReadSuccess = true; + return substring; + } + } + + /** + * 查看几个字符
+ * 如果不够查看的数量, 将返回null + * + * @param size 期望查看的数量 + * @return 字符串 + */ + public String peekChars(int size) { + if (index >= length) { + this.lastReadSuccess = true; + return null; + } else if (index + size > length) { + this.lastReadSuccess = false; + return null; + } else { + int endIndex = index + size; + this.lastReadSuccess = true; + return string.substring(index, endIndex); + } + } + + /** + * 读取连续的指定字符
+ * 如果一个字符都没有读取到, 将设置lastReadSuccess=false并返回null + * + * @param chars 指定字符 + * @return 字符串 + */ + public String readChars(char... chars) { + if (index >= length) { + this.lastReadSuccess = true; + return null; + } + int originalIndex = this.index; + for (; index < length; index++) { + char c = string.charAt(index); + if (!isInChars(c, chars)) { + break; + } + } + if (this.index == originalIndex) { + this.lastReadSuccess = false; + return null; + } else { + this.lastReadSuccess = true; + return string.substring(originalIndex, index); + } + } + /** 跳过空白字符 (空格/TAB/换行) **/ public StringAccess skipWhitespace() { return this.doSkipWhitespace(true); @@ -141,6 +214,30 @@ public class StringAccess { return this.doSkipWhitespace(false); } + /** 读取空白字符 (空格/TAB/换行) **/ + public String readWhitespace() { + if (index >= length) { + this.lastReadSuccess = true; + return null; + } else { + int originalIndex = this.index; + this.doSkipWhitespace(true); + return string.substring(originalIndex, index); + } + } + + /** 读取空格和TAB字符 **/ + public String readSpaceChars() { + if (index >= length) { + this.lastReadSuccess = true; + return null; + } else { + int originalIndex = this.index; + this.doSkipWhitespace(false); + return string.substring(originalIndex, index); + } + } + protected StringAccess doSkipWhitespace(boolean multiline) { for (; index < length; index++) { char c = string.charAt(index); @@ -241,20 +338,155 @@ public class StringAccess { return originIndex == index ? null : string.substring(originIndex, index); } + /** + * 从当前位置开始读取, 直到遇到指定字符
+ * 返回字符串不会包含指定字符
+ * 如果到最后也没遇到指定字符, 将还原位置/设置lastReadSuccess=false/返回null
+ * + * @param chars 指定字符 + * @return 子字符串 + */ + public String readUntil(char... chars) { + if (index >= length) { + this.lastReadSuccess = true; + return null; + } + int newIndex = index; + boolean found = false; + while (newIndex < length) { + char c = string.charAt(newIndex); + if (isInChars(c, chars)) { + found = true; + break; + } else if (!multiline && (c == '\r' || c == '\n')) { + found = false; + break; // 单行模式下遇到换行符, 也是结束 + } else { + newIndex++; + continue; + } + } + if (!found) { + this.lastReadSuccess = false; + return null; + } else { + this.lastReadSuccess = true; + String result = string.substring(index, newIndex); + this.index = newIndex; + return result; + } + } + + /** + * 从当前位置开始读取, 直到遇到指定字符串
+ * 返回字符串不会包含指定字符串
+ * 如果到最后也没遇到指定字符串, 将还原位置/设置lastReadSuccess=false/返回null
+ * + * @param strings 指定字符串 + * @return 子字符串 + */ + public String readUntil(String... strings) { + if (index >= length) { + this.lastReadSuccess = true; + return null; + } + int newIndex = index; + boolean found = false; + while (newIndex < length) { + if (isStartsWith(string, index, strings)) { + found = true; + break; + } + char c = string.charAt(newIndex); + if (!multiline && (c == '\r' || c == '\n')) { + found = false; + break; // 单行模式下遇到换行符, 也是结束 + } else { + newIndex++; + continue; + } + } + if (!found) { + this.lastReadSuccess = false; + return null; + } else { + this.lastReadSuccess = true; + String result = string.substring(index, newIndex); + this.index = newIndex; + return result; + } + } + + /** + * 从当前位置开始读取, 直到行尾
+ * 返回字符串不会包含指定字符
+ * 如果到最后也没遇到换行符, 将读取到最后
+ * + * @return 子字符串 + */ + public String readToLineEnd() { + if (index >= length) { + this.lastReadSuccess = true; + return null; + } + String line = this.readUntil('\n'); + if (line != null) { + return line; + } else { + return this.readToEnd(); + } + } + + private static boolean isInChars(char c, char... chars) { + for (int i = 0; i < chars.length; i++) { + if (c == chars[i]) { + return true; + } + } + if (c == '\r') { + // 如果是\r, 只要chars中包含\n也返回true + for (int i = 0; i < chars.length; i++) { + if (c == '\n') { + return true; + } + } + } + return false; + } + + private static boolean isStartsWith(String string, int index, String... prefixes) { + for (String prefix : prefixes) { + if (index + prefix.length() > string.length()) { + continue; + } + if (string.substring(index, index + prefix.length()).equals(prefix)) { + return true; + } + } + return false; + } + /** 从当前位置读取到最后 (如果当前位置已在最后将返回null) **/ public String readToEnd() { - return doReadToEnd(this.index); + String substring = doPeekToEnd(this.index); + this.index = this.length; + return substring; } - /** 从指定位置读取到最后 (如果指定位置已在最后将返回null) **/ - public String readToEnd(int index) { + /** 查看从当前位置到最后的字符串 (如果当前位置已在最后将返回null) **/ + public String peekToEnd() { + return doPeekToEnd(this.index); + } + + /** 查看从指定位置到最后的字符串 (如果指定位置已在最后将返回null) **/ + public String peekToEnd(int index) { if (index < 0 || index > length) { throw new IndexOutOfBoundsException("Index[" + index + "] out of bounds (0, " + length + ")"); } - return doReadToEnd(index); + return doPeekToEnd(index); } - private String doReadToEnd(int index) { + private String doPeekToEnd(int index) { if (index >= length) { this.lastReadSuccess = true; return null; @@ -265,13 +497,13 @@ public class StringAccess { } /** - * 从指定位置读取到当前位置 + * 查看从指定位置到当前位置的字符串 * * @param startIndex 开始位置 * @return 子字符串 * @throws IndexOutOfBoundsException 位置超出源字符串范围 */ - public String readFrom(int startIndex) { + public String peekFrom(int startIndex) { if (startIndex < 0 || startIndex > index) { throw new IndexOutOfBoundsException("StartIndex[" + startIndex + "] out of bounds (0, " + index + ")"); } @@ -280,14 +512,14 @@ public class StringAccess { } /** - * 读取子字符串 + * 查看子字符串 * * @param startIndex 开始位置 * @param endIndex 结束位置 * @return 子字符串 * @throws IndexOutOfBoundsException 位置超出源字符串范围 */ - public String readSubstring(int startIndex, int endIndex) { + public String peekSubstring(int startIndex, int endIndex) { if (startIndex < 0 || startIndex > length) { throw new IndexOutOfBoundsException("StartIndex[" + startIndex + "] out of bounds (0, " + length + ")"); } @@ -302,6 +534,16 @@ public class StringAccess { } } + /** + * 读取括号中的内容
+ * 返回内容不会包含外层括号
+ * 如果没有找到匹配的括号, 将还原位置/设置lastReadSuccess=false/返回null
+ * 支持括号嵌套, 如 new StringAccess("(1/(a+b))").readInBracket('(', ')')将返回1/(a+b) + * + * @param leftBracket 左括号 + * @param rightBracket 右括号 + * @return 括号中的内容 + */ public String readInBracket(char leftBracket, char rightBracket) { if (index >= length) { this.lastReadSuccess = true; @@ -329,27 +571,6 @@ public class StringAccess { return result.substring(1, result.length() - 1).trim(); // pinyin } - /** - * 读取一个单项内容 - * - * @param stopChar 停止符 - * @param multiline 是否支持多行 - * @return 单项内容 - * @deprecated 改为{@link #readUniterm(char...)} - */ - @Deprecated - public String readUniterm(char stopChar, boolean multiline) { - if (this.multiline == multiline) { - return readUniterm(stopChar); - } else { - boolean originalMultiline = this.multiline; - this.multiline = multiline; - String result = readUniterm(stopChar); - this.multiline = originalMultiline; - return result; - } - } - /** * 读取一个单项内容
* 支持以下这些单项:
@@ -391,27 +612,6 @@ public class StringAccess { } } - /** - * 读取后续所有的单项内容 - * - * @param separator 分隔符 - * @param multiline 是否支持多行 - * @return 多个单项内容列表 - * @deprecated 改为{@link #readUniterms(boolean, char...)} - */ - @Deprecated - public List readUniterms(char separator, boolean multiline) { - if (this.multiline == multiline) { - return readUniterms(separator); - } else { - boolean originalMultiline = this.multiline; - this.multiline = multiline; - List result = readUniterms(separator); - this.multiline = originalMultiline; - return result; - } - } - /** * 读取后续所有的单项内容 ( 如果不允许多行将读取至行尾; 如果允许多行将读取至文本结束 )
* 调这个方法应该是期望到行尾或文尾, 都是单项内容
diff --git a/tools/pom.xml b/tools/pom.xml index 7407fb1501ccc617ff613f518f67bff9100db13a..b42fc0c6d364807717f6b5cfd893a7b450c14ab6 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -10,7 +10,7 @@ qdbp-tools jar - 5.2.25 + 5.3.0 https://gitee.com/qdbp/qdbp-able/ qdbp tools library diff --git a/tools/src/test/java/com/gitee/qdbp/tools/parse/StringAccessTest.java b/tools/src/test/java/com/gitee/qdbp/tools/parse/StringAccessTest.java index 21ed867dc4eb47e4f9304234a827345ee04603fd..ab87aebc44c7d939208b9bf7b58406bb12c3ce38 100644 --- a/tools/src/test/java/com/gitee/qdbp/tools/parse/StringAccessTest.java +++ b/tools/src/test/java/com/gitee/qdbp/tools/parse/StringAccessTest.java @@ -209,4 +209,28 @@ public class StringAccessTest { } Assert.assertEquals(uiterms, null, source); } + + @Test + public void testReadChars15() { + StringAccess sa = new StringAccess("ABCDEFG"); + Assert.assertEquals(sa.readChars(2), "AB"); + Assert.assertEquals(sa.readChars(3), "CDE"); + Assert.assertEquals(sa.readChars(2), "FG"); + Assert.assertEquals(sa.readChars(3), null); + } + + @Test + public void testReadChars16() { + StringAccess sa = new StringAccess("ABCABCDEFG"); + Assert.assertEquals(sa.readChars('A', 'B', 'C'), "ABCABC"); + Assert.assertEquals(sa.readChars('A', 'B', 'C'), null); + } + + @Test + public void testReadInBracket() { + StringAccess sa = new StringAccess("calculate(1/(a+b))"); + Assert.assertEquals(sa.readWord(), "calculate"); + Assert.assertEquals(sa.readInBracket('(', ')'), "1/(a+b)"); + } + }