From 3b21443d804440b6739286fba4541e7f5b78d1ae Mon Sep 17 00:00:00 2001 From: CloudPlayer <2909078582@qq.com> Date: Thu, 25 Jan 2024 00:42:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=20QueryColumnBehavior=20=E4=B8=AD?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=9D=99=E6=80=81=E5=AD=97=E6=AE=B5=20condit?= =?UTF-8?q?ionCaster=20=EF=BC=8C=E7=94=A8=E4=BA=8E=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=9C=A8=E6=BB=A1=E8=B6=B3=E4=B8=80=E5=AE=9A?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=E5=90=8E=EF=BC=8C=E5=B0=86=E5=8E=9F=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E8=BD=AC=E6=8D=A2=E4=B8=BA=E6=8C=87=E5=AE=9A=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=EF=BC=8C=E4=BE=8B=E5=A6=82=E5=B0=86=20column=20=3D=20?= =?UTF-8?q?null=20=E8=BD=AC=E6=8D=A2=E4=B8=BA=20column=20is=20null=20?= =?UTF-8?q?=E3=80=82=E5=8F=AF=E5=85=BC=E5=AE=B9=E5=8E=9F=E6=9C=89=E7=9A=84?= =?UTF-8?q?=20in=20=E5=88=B0=20=3D=20=E7=9A=84=E6=99=BA=E8=83=BD=E8=BD=AC?= =?UTF-8?q?=E6=8D=A2=E3=80=82=E5=BD=93=E6=99=BA=E8=83=BD=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E8=A2=AB=E6=89=93=E5=BC=80=E6=97=B6=EF=BC=8C=E4=BC=9A=E5=85=88?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E6=99=BA=E8=83=BD=E8=BD=AC=E6=8D=A2=E5=86=8D?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=20conditionCaster=20=E7=9A=84=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 对应的测试方法在 DynamicConditionTest 中。 --- .../core/query/QueryColumnBehavior.java | 60 ++++++++++++++ .../coretest/DynamicConditionTest.java | 81 +++++++++++++++++++ 2 files changed, 141 insertions(+) diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryColumnBehavior.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryColumnBehavior.java index a8889a4e..f1d91876 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryColumnBehavior.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryColumnBehavior.java @@ -15,7 +15,12 @@ */ package com.mybatisflex.core.query; +import com.mybatisflex.core.constant.SqlConsts; +import com.mybatisflex.core.constant.SqlOperator; + +import java.util.Iterator; import java.util.Objects; +import java.util.function.Function; import java.util.function.Predicate; /** @@ -23,6 +28,7 @@ import java.util.function.Predicate; * * @author michael * @author 王帅 + * @author CloudPlayer */ public class QueryColumnBehavior { @@ -36,11 +42,54 @@ public class QueryColumnBehavior { public static final Predicate IGNORE_EMPTY = o -> o == null || "".equals(o); public static final Predicate IGNORE_BLANK = o -> o == null || "".equals(o.toString().trim()); + /** + * 在满足输入的数组或可迭代对象中的容量为 1 (即只有一个元素)时,自动将条件中的 in 转换为 = + */ + public static final Function CONVERT_IN_TO_EQUALS = it -> { + Object value = it.value; + if (value == null) { + return it; + } + if (it.logic.equalsIgnoreCase(SqlConsts.IN)) { + Object firstValue; + if (value instanceof Iterable) { + Iterator iter = ((Iterable) value).iterator(); + if (!iter.hasNext()) { // 没有元素,直接返回原条件 + return it; + } + firstValue = iter.next(); // 取第一个元素 + if (iter.hasNext()) { // 如果有后续元素,则直接返回原条件 + return it; + } + } else if (value instanceof Object[]) { + Object[] array = (Object[]) value; + if (array.length != 1) { // 如果不是单元素的数组就直接返回 + return it; + } + firstValue = array[0]; // 取第一个元素 + } else { + return it; + } + return QueryCondition.create(it.column, SqlOperator.EQUALS, firstValue); // 将 in 转换为 = + } else { + return it; + } + }; + + /** + * 如果使用了 = 来比较 null ,则将其转为 is null 。 + */ + public static final Function CONVERT_EQUALS_TO_IS_NULL = it -> it.value == null ? it.column.isNull() : it; /** * 自定义全局的自动忽略参数的方法。 */ private static Predicate ignoreFunction = IGNORE_NULL; + /** + * 自定义全局的自动转换条件的方法。 + */ + private static Function conditionCaster = Function.identity(); + /** * 当 {@code IN(...)} 条件只有 1 个参数时,是否自动把的内容转换为相等。 */ @@ -66,4 +115,15 @@ public class QueryColumnBehavior { return ignoreFunction.test(value); } + public static Function getConditionCaster() { + return smartConvertInToEquals ? CONVERT_IN_TO_EQUALS.andThen(conditionCaster) : conditionCaster; + } + + public static void setConditionCaster(Function conditionCaster) { + QueryColumnBehavior.conditionCaster = conditionCaster; + } + + public static QueryCondition castCondition(QueryCondition condition) { + return getConditionCaster().apply(condition); + } } diff --git a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/DynamicConditionTest.java b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/DynamicConditionTest.java index 26fadb0d..e63c4eac 100644 --- a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/DynamicConditionTest.java +++ b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/DynamicConditionTest.java @@ -17,14 +17,19 @@ package com.mybatisflex.coretest; import com.mybatisflex.core.constant.SqlConnector; +import com.mybatisflex.core.constant.SqlOperator; import com.mybatisflex.core.query.*; import com.mybatisflex.core.util.StringUtil; +import org.junit.Assert; import org.junit.Test; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Objects; +import static com.mybatisflex.core.query.QueryColumnBehavior.CONVERT_EQUALS_TO_IS_NULL; +import static com.mybatisflex.core.query.QueryColumnBehavior.getConditionCaster; import static com.mybatisflex.core.query.QueryMethods.bracket; import static com.mybatisflex.core.query.QueryMethods.raw; import static com.mybatisflex.coretest.table.AccountTableDef.ACCOUNT; @@ -227,4 +232,80 @@ public class DynamicConditionTest { System.out.println(qw.toSQL()); } + + private void assertConditionEquals(QueryCondition expect, QueryCondition actual) { + Assert.assertEquals(expect.getColumn(), actual.getColumn()); + Assert.assertEquals(expect.getLogic(), actual.getLogic()); + Assert.assertEquals(expect.getValue(), actual.getValue()); + } + + @Test + public void testCastFunction1() { + QueryCondition condition = QueryCondition.create(new QueryColumn("id"), SqlOperator.IN, new Object[] {null}); + Assert.assertSame(condition, getConditionCaster().apply(condition)); + } + + @Test + public void testCastFunction2() { + QueryColumn column = new QueryColumn("id"); + QueryColumnBehavior.setConditionCaster(CONVERT_EQUALS_TO_IS_NULL); + + QueryCondition condition = QueryCondition.create(column, SqlOperator.EQUALS, null); + QueryCondition expect = column.isNull(); + QueryCondition actual = getConditionCaster().apply(condition); + + assertConditionEquals(expect, actual); + } + + @Test + public void testCastFunction3() { + QueryColumn column = new QueryColumn("id"); + QueryColumnBehavior.setConditionCaster(CONVERT_EQUALS_TO_IS_NULL); + QueryColumnBehavior.setSmartConvertInToEquals(true); + + QueryCondition condition = QueryCondition.create(column, SqlOperator.EQUALS, null); + QueryCondition expect = column.isNull(); + QueryCondition actual = getConditionCaster().apply(condition); + + assertConditionEquals(expect, actual); + } + + @Test + public void testCastFunction4() { + QueryColumn column = new QueryColumn("id"); + QueryColumnBehavior.setConditionCaster(CONVERT_EQUALS_TO_IS_NULL); + QueryColumnBehavior.setSmartConvertInToEquals(true); + + QueryCondition condition = QueryCondition.create(column, SqlOperator.IN, new Object[] { 1 }); + QueryCondition expect = QueryCondition.create(column, SqlOperator.EQUALS, 1); + QueryCondition actual = getConditionCaster().apply(condition); + + assertConditionEquals(expect, actual); + } + + @Test + public void testCastFunction5() { + QueryColumn column = new QueryColumn("id"); + QueryColumnBehavior.setConditionCaster(CONVERT_EQUALS_TO_IS_NULL); + QueryColumnBehavior.setSmartConvertInToEquals(true); + + QueryCondition condition = QueryCondition.create(column, SqlOperator.IN, new Object[] { null }); + QueryCondition expect = column.isNull(); + QueryCondition actual = getConditionCaster().apply(condition); + + assertConditionEquals(expect, actual); + } + + @Test + public void testCastFunction6() { + QueryColumn column = new QueryColumn("id"); + QueryColumnBehavior.setConditionCaster(CONVERT_EQUALS_TO_IS_NULL); + QueryColumnBehavior.setSmartConvertInToEquals(true); + + QueryCondition condition = QueryCondition.create(column, SqlOperator.IN, Collections.singletonList(null)); + QueryCondition expect = column.isNull(); + QueryCondition actual = getConditionCaster().apply(condition); + + assertConditionEquals(expect, actual); + } }