在 QueryColumnBehavior 中新增静态字段 conditionCaster ,用于全局设置在满足一定条件后,将原条件转换为指定条件,例如将 column = null 转换为 column is null 。可兼容原有的 in 到 = 的智能转换。当智能转换被打开时,会先执行智能转换再执行 conditionCaster 的方法。

对应的测试方法在 DynamicConditionTest 中。
This commit is contained in:
CloudPlayer 2024-01-25 00:42:01 +08:00
parent 46fb406e1e
commit 3b21443d80
2 changed files with 141 additions and 0 deletions

View File

@ -15,7 +15,12 @@
*/ */
package com.mybatisflex.core.query; 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.Objects;
import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
/** /**
@ -23,6 +28,7 @@ import java.util.function.Predicate;
* *
* @author michael * @author michael
* @author 王帅 * @author 王帅
* @author CloudPlayer
*/ */
public class QueryColumnBehavior { public class QueryColumnBehavior {
@ -36,11 +42,54 @@ public class QueryColumnBehavior {
public static final Predicate<Object> IGNORE_EMPTY = o -> o == null || "".equals(o); public static final Predicate<Object> IGNORE_EMPTY = o -> o == null || "".equals(o);
public static final Predicate<Object> IGNORE_BLANK = o -> o == null || "".equals(o.toString().trim()); public static final Predicate<Object> IGNORE_BLANK = o -> o == null || "".equals(o.toString().trim());
/**
* 在满足输入的数组或可迭代对象中的容量为 1 即只有一个元素自动将条件中的 in 转换为 =
*/
public static final Function<? super QueryCondition, ? extends QueryCondition> 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<? super QueryCondition, ? extends QueryCondition> CONVERT_EQUALS_TO_IS_NULL = it -> it.value == null ? it.column.isNull() : it;
/** /**
* 自定义全局的自动忽略参数的方法 * 自定义全局的自动忽略参数的方法
*/ */
private static Predicate<Object> ignoreFunction = IGNORE_NULL; private static Predicate<Object> ignoreFunction = IGNORE_NULL;
/**
* 自定义全局的自动转换条件的方法
*/
private static Function<? super QueryCondition, ? extends QueryCondition> conditionCaster = Function.identity();
/** /**
* {@code IN(...)} 条件只有 1 个参数时是否自动把的内容转换为相等 * {@code IN(...)} 条件只有 1 个参数时是否自动把的内容转换为相等
*/ */
@ -66,4 +115,15 @@ public class QueryColumnBehavior {
return ignoreFunction.test(value); return ignoreFunction.test(value);
} }
public static Function<? super QueryCondition, ? extends QueryCondition> getConditionCaster() {
return smartConvertInToEquals ? CONVERT_IN_TO_EQUALS.andThen(conditionCaster) : conditionCaster;
}
public static void setConditionCaster(Function<? super QueryCondition, ? extends QueryCondition> conditionCaster) {
QueryColumnBehavior.conditionCaster = conditionCaster;
}
public static QueryCondition castCondition(QueryCondition condition) {
return getConditionCaster().apply(condition);
}
} }

View File

@ -17,14 +17,19 @@
package com.mybatisflex.coretest; package com.mybatisflex.coretest;
import com.mybatisflex.core.constant.SqlConnector; import com.mybatisflex.core.constant.SqlConnector;
import com.mybatisflex.core.constant.SqlOperator;
import com.mybatisflex.core.query.*; import com.mybatisflex.core.query.*;
import com.mybatisflex.core.util.StringUtil; import com.mybatisflex.core.util.StringUtil;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; 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.bracket;
import static com.mybatisflex.core.query.QueryMethods.raw; import static com.mybatisflex.core.query.QueryMethods.raw;
import static com.mybatisflex.coretest.table.AccountTableDef.ACCOUNT; import static com.mybatisflex.coretest.table.AccountTableDef.ACCOUNT;
@ -227,4 +232,80 @@ public class DynamicConditionTest {
System.out.println(qw.toSQL()); 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);
}
} }