From 665e43305172c81c99df290d36ad123eacfdb0ef Mon Sep 17 00:00:00 2001 From: yulichang <570810310@qq.com> Date: Sat, 23 Dec 2023 16:55:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0ifAbsent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MybatisPlusJoinAutoConfiguration.java | 21 ++- .../MybatisPlusJoinProperties.java | 15 +- ...itional-spring-configuration-metadata.json | 23 +-- .../yulichang/config/ConfigProperties.java | 15 +- .../config/MybatisPlusJoinIfAbsent.java | 12 ++ .../yulichang/config/enums/IfAbsentEnum.java | 40 +++++ .../yulichang/kt/KtAbstractWrapper.java | 22 ++- .../kt/interfaces/CompareIfAbsent.java | 97 ++++++++++++ .../query/MPJLambdaQueryWrapper.java | 147 +++++++++++++++-- .../yulichang/query/MPJQueryWrapper.java | 55 ++++++- .../query/interfaces/CompareIfAbsent.java | 149 ++++++++++++++++++ .../yulichang/toolkit/MPJStringUtils.java | 19 ++- .../yulichang/toolkit/ThrowOptional.java | 53 +++++++ .../yulichang/wrapper/MPJAbstractWrapper.java | 27 +++- .../yulichang/wrapper/MPJLambdaWrapper.java | 10 +- .../wrapper/interfaces/CompareIfAbsent.java | 96 +++++++++++ .../interfaces/CompareStrIfAbsent.java | 55 +++++++ .../yulichang/test/join/QueryWrapperTest.java | 31 ++++ .../yulichang/test/join/m/IfAbsentTest.java | 66 ++++++++ 19 files changed, 895 insertions(+), 58 deletions(-) create mode 100644 mybatis-plus-join-core/src/main/java/com/github/yulichang/config/MybatisPlusJoinIfAbsent.java create mode 100644 mybatis-plus-join-core/src/main/java/com/github/yulichang/config/enums/IfAbsentEnum.java create mode 100644 mybatis-plus-join-core/src/main/java/com/github/yulichang/kt/interfaces/CompareIfAbsent.java create mode 100644 mybatis-plus-join-core/src/main/java/com/github/yulichang/query/interfaces/CompareIfAbsent.java create mode 100644 mybatis-plus-join-core/src/main/java/com/github/yulichang/toolkit/ThrowOptional.java create mode 100644 mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/interfaces/CompareIfAbsent.java create mode 100644 mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/interfaces/CompareStrIfAbsent.java create mode 100644 mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/m/IfAbsentTest.java diff --git a/mybatis-plus-join-boot-starter/src/main/java/com/github/yulichang/autoconfigure/MybatisPlusJoinAutoConfiguration.java b/mybatis-plus-join-boot-starter/src/main/java/com/github/yulichang/autoconfigure/MybatisPlusJoinAutoConfiguration.java index db86189..0c7947f 100644 --- a/mybatis-plus-join-boot-starter/src/main/java/com/github/yulichang/autoconfigure/MybatisPlusJoinAutoConfiguration.java +++ b/mybatis-plus-join-boot-starter/src/main/java/com/github/yulichang/autoconfigure/MybatisPlusJoinAutoConfiguration.java @@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.core.injector.ISqlInjector; import com.github.yulichang.autoconfigure.conditional.MPJSqlInjectorCondition; import com.github.yulichang.config.ConfigProperties; import com.github.yulichang.config.MPJInterceptorConfig; -import com.github.yulichang.config.enums.LogicDelTypeEnum; +import com.github.yulichang.config.MybatisPlusJoinIfAbsent; import com.github.yulichang.extension.mapping.config.MappingConfig; import com.github.yulichang.injector.MPJSqlInjector; import com.github.yulichang.interceptor.MPJInterceptor; @@ -56,20 +56,21 @@ public class MybatisPlusJoinAutoConfiguration { private static final Logger logger = LoggerFactory.getLogger(MybatisPlusJoinAutoConfiguration.class); - @SuppressWarnings("FieldCanBeLocal") private final MybatisPlusJoinProperties properties; public MybatisPlusJoinAutoConfiguration(MybatisPlusJoinProperties properties, - ObjectProvider propertiesConsumers) { + ObjectProvider propertiesConsumers, + ObjectProvider ifAbsentConsumers) { this.properties = Optional.ofNullable(propertiesConsumers.getIfAvailable()).map(c -> c.config(properties)).orElse(properties); ConfigProperties.banner = this.properties.getBanner(); ConfigProperties.subTableLogic = this.properties.getSubTableLogic(); ConfigProperties.msCache = this.properties.isMsCache(); ConfigProperties.tableAlias = this.properties.getTableAlias(); ConfigProperties.joinPrefix = this.properties.getJoinPrefix(); - ConfigProperties.logicDelType = "where".equalsIgnoreCase(this.properties.getLogicDelType()) ? - LogicDelTypeEnum.WHERE : LogicDelTypeEnum.ON; + ConfigProperties.logicDelType = this.properties.getLogicDelType(); ConfigProperties.mappingMaxCount = this.properties.getMappingMaxCount(); + ConfigProperties.ifAbsent = Optional.ofNullable(ifAbsentConsumers.getIfAvailable()).orElse(this.properties.getIfAbsent()); + info("mybatis plus join properties config complete"); } /** @@ -101,7 +102,7 @@ public class MybatisPlusJoinAutoConfiguration { @ConditionalOnBean(ISqlInjector.class) @ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class}) public MPJSqlInjector mpjSqlInjector(ISqlInjector sqlInjector) { - logger.info("MPJSqlInjector init"); + info("mybatis plus join SqlInjector init"); return new MPJSqlInjector(sqlInjector); } @@ -113,7 +114,7 @@ public class MybatisPlusJoinAutoConfiguration { @ConditionalOnMissingBean(ISqlInjector.class) @ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class}) public MPJSqlInjector mpjSqlInjectorOnMiss() { - logger.info("MPJSqlInjector init"); + info("mybatis plus join SqlInjector init"); return new MPJSqlInjector(); } @@ -129,6 +130,12 @@ public class MybatisPlusJoinAutoConfiguration { } } + private void info(String info) { + if (properties.getBanner()) { + logger.info(info); + } + } + @Configuration @ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class}) public static class MPJSpringContext implements SpringContentUtils.SpringContext, BeanFactoryPostProcessor, ApplicationContextAware { diff --git a/mybatis-plus-join-boot-starter/src/main/java/com/github/yulichang/autoconfigure/MybatisPlusJoinProperties.java b/mybatis-plus-join-boot-starter/src/main/java/com/github/yulichang/autoconfigure/MybatisPlusJoinProperties.java index 637f000..e30fe5a 100644 --- a/mybatis-plus-join-boot-starter/src/main/java/com/github/yulichang/autoconfigure/MybatisPlusJoinProperties.java +++ b/mybatis-plus-join-boot-starter/src/main/java/com/github/yulichang/autoconfigure/MybatisPlusJoinProperties.java @@ -1,5 +1,7 @@ package com.github.yulichang.autoconfigure; +import com.github.yulichang.config.enums.IfAbsentEnum; +import com.github.yulichang.config.enums.LogicDelTypeEnum; import lombok.Data; import lombok.experimental.Accessors; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -43,7 +45,7 @@ public class MybatisPlusJoinProperties { /** * 逻辑删除类型 支持 where on */ - private String logicDelType = "on"; + private LogicDelTypeEnum logicDelType = LogicDelTypeEnum.ON; /** * 映射查询最大深度 @@ -54,4 +56,15 @@ public class MybatisPlusJoinProperties { * 子查询别名 */ private String subQueryAlias = "st"; + + /** + * Wrapper ifAbsent 判断策略 + *

+ * NOT_NULL 非null + *

+ * NOT_EMPTY 非空字符串 例: "" -> false, " " -> true ... + *

+ * NOT_BLANK 非空白字符串 例: "" -> false, " " -> false, "\r" -> false, "abc" -> true ... + */ + private IfAbsentEnum ifAbsent = IfAbsentEnum.NOT_EMPTY; } diff --git a/mybatis-plus-join-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/mybatis-plus-join-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json index e0d1738..464b374 100644 --- a/mybatis-plus-join-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/mybatis-plus-join-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -40,8 +40,8 @@ }, { "name": "mybatis-plus-join.logic-del-type", - "defaultValue": "on", - "type": "java.lang.String", + "defaultValue": "com.github.yulichang.config.enums.LogicDelTypeEnum.ON", + "type": "com.github.yulichang.config.enums.LogicDelTypeEnum", "description": "逻辑删除的位置支持where和on两个." }, { @@ -55,21 +55,12 @@ "defaultValue": "st", "type": "java.lang.String", "description": "子查询表别名." - } - ], - "hints": [ + }, { - "name": "mybatis-plus-join.logic-del-type", - "values": [ - { - "value": "where", - "description": "logic delete condition to where." - }, - { - "value": "on", - "description": "logic delete condition to on." - } - ] + "name": "mybatis-plus-join.ifAbsent", + "defaultValue": "com.github.yulichang.config.enums.IfAbsentEnum.NOT_EMPTY", + "type": "com.github.yulichang.config.enums.IfAbsentEnum", + "description": "IfAbsent方法判断策略,如需自定义请用@Bean形式MybatisPlusJoinIfAbsent." } ] } diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/config/ConfigProperties.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/config/ConfigProperties.java index e110c34..a777d84 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/config/ConfigProperties.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/config/ConfigProperties.java @@ -2,6 +2,7 @@ package com.github.yulichang.config; import com.github.yulichang.adapter.AdapterHelper; import com.github.yulichang.adapter.base.ITableInfoAdapter; +import com.github.yulichang.config.enums.IfAbsentEnum; import com.github.yulichang.config.enums.LogicDelTypeEnum; /** @@ -11,7 +12,7 @@ import com.github.yulichang.config.enums.LogicDelTypeEnum; public class ConfigProperties { /** - * 是否开启副表逻辑删除 + * 是否打印banner */ public static boolean banner = true; /** @@ -35,7 +36,7 @@ public class ConfigProperties { */ public static LogicDelTypeEnum logicDelType = LogicDelTypeEnum.ON; /** - * 逻辑删除类型 支持 where on + * 映射查询最大深度 */ public static int mappingMaxCount = 5; /** @@ -46,4 +47,14 @@ public class ConfigProperties { * 子查询别名 */ public static String subQueryAlias = "st"; + /** + * Wrapper ifAbsent 判断策略 + *

+ * NOT_NULL 非null + *

+ * NOT_EMPTY 非空字符串 例: "" -> false, " " -> true ... + *

+ * NOT_BLANK 非空白字符串 例: "" -> false, " " -> false, "\r" -> false, "abc" -> true ... + */ + public static MybatisPlusJoinIfAbsent ifAbsent = IfAbsentEnum.NOT_EMPTY; } diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/config/MybatisPlusJoinIfAbsent.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/config/MybatisPlusJoinIfAbsent.java new file mode 100644 index 0000000..e7e8b7a --- /dev/null +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/config/MybatisPlusJoinIfAbsent.java @@ -0,0 +1,12 @@ +package com.github.yulichang.config; + +import java.util.function.Predicate; + +/** + * 自定义IfAbsent策略 + * + * @author yulichang + * @since 1.4.9 + */ +public interface MybatisPlusJoinIfAbsent extends Predicate { +} diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/config/enums/IfAbsentEnum.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/config/enums/IfAbsentEnum.java new file mode 100644 index 0000000..91e7fa7 --- /dev/null +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/config/enums/IfAbsentEnum.java @@ -0,0 +1,40 @@ +package com.github.yulichang.config.enums; + +import com.github.yulichang.config.MybatisPlusJoinIfAbsent; +import com.github.yulichang.toolkit.MPJStringUtils; + +import java.util.Objects; +import java.util.function.Predicate; + +/** + * 条件判断策略 + * + * @author yulichang + * @since 1.4.9 + */ +public enum IfAbsentEnum implements MybatisPlusJoinIfAbsent { + + /** + * 非null + */ + NOT_NULL(Objects::nonNull), + /** + * 非空字符串 例: "" -> false, " " -> true ... + */ + NOT_EMPTY(val -> NOT_NULL.and(v -> v instanceof CharSequence).and(v -> MPJStringUtils.isNotEmpty((CharSequence) v)).test(val)), + /** + * NOT_BLANK 非空白字符串 例: "" -> false, " " -> false, "\r" -> false, "abc" -> true ... + */ + NOT_BLANK(val -> NOT_NULL.and(v -> v instanceof CharSequence).and(v -> MPJStringUtils.isNotBlank((CharSequence) v)).test(val)); + + private final Predicate predicate; + + IfAbsentEnum(Predicate predicate) { + this.predicate = predicate; + } + + @Override + public boolean test(Object obj) { + return this.predicate.test(obj); + } +} diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/kt/KtAbstractWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/kt/KtAbstractWrapper.java index b5bcb31..c8b05a8 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/kt/KtAbstractWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/kt/KtAbstractWrapper.java @@ -11,7 +11,9 @@ import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; import com.baomidou.mybatisplus.core.toolkit.*; import com.baomidou.mybatisplus.core.toolkit.sql.SqlUtils; import com.baomidou.mybatisplus.core.toolkit.sql.StringEscape; -import com.github.yulichang.kt.interfaces.Compare; +import com.github.yulichang.config.ConfigProperties; +import com.github.yulichang.config.MybatisPlusJoinIfAbsent; +import com.github.yulichang.kt.interfaces.CompareIfAbsent; import com.github.yulichang.kt.interfaces.Func; import com.github.yulichang.kt.interfaces.OnCompare; import com.github.yulichang.toolkit.KtUtils; @@ -20,7 +22,7 @@ import com.github.yulichang.toolkit.Ref; import com.github.yulichang.toolkit.TableList; import com.github.yulichang.toolkit.sql.SqlScriptUtils; import com.github.yulichang.wrapper.enums.PrefixEnum; -import com.github.yulichang.wrapper.interfaces.CompareStr; +import com.github.yulichang.wrapper.interfaces.CompareStrIfAbsent; import com.github.yulichang.wrapper.interfaces.FuncStr; import com.github.yulichang.wrapper.interfaces.Join; import kotlin.reflect.KProperty; @@ -44,8 +46,8 @@ import static java.util.stream.Collectors.joining; */ @SuppressWarnings({"unused", "unchecked", "DuplicatedCode"}) public abstract class KtAbstractWrapper> extends Wrapper - implements Compare, Nested, Join, Func, OnCompare, - CompareStr, FuncStr { + implements CompareIfAbsent, Nested, Join, Func, OnCompare, + CompareStrIfAbsent, FuncStr { /** * 占位符 @@ -121,6 +123,12 @@ public abstract class KtAbstractWrapper, ?> params, boolean null2IsNull) { if (condition && CollectionUtils.isNotEmpty(params)) { @@ -630,6 +643,7 @@ public abstract class KtAbstractWrapper extends Compare { + + MybatisPlusJoinIfAbsent getIfAbsent(); + + default Children eqIfAbsent(KProperty column, Object val) { + return eq(getIfAbsent().test(val), null, column, val); + } + + default Children eqIfAbsent(String alias, KProperty column, Object val) { + return eq(getIfAbsent().test(val), alias, column, val); + } + + default Children neIfAbsent(KProperty column, Object val) { + return ne(getIfAbsent().test(val), null, column, val); + } + + default Children neIfAbsent(String alias, KProperty column, Object val) { + return ne(getIfAbsent().test(val), alias, column, val); + } + + default Children gtIfAbsent(KProperty column, Object val) { + return gt(getIfAbsent().test(val), null, column, val); + } + + default Children gtIfAbsent(String alias, KProperty column, Object val) { + return gt(getIfAbsent().test(val), alias, column, val); + } + + + default Children geIfAbsent(KProperty column, Object val) { + return ge(getIfAbsent().test(val), null, column, val); + } + + default Children geIfAbsent(String alias, KProperty column, Object val) { + return ge(getIfAbsent().test(val), alias, column, val); + } + + default Children ltIfAbsent(KProperty column, Object val) { + return lt(getIfAbsent().test(val), null, column, val); + } + + default Children ltIfAbsent(String alias, KProperty column, Object val) { + return lt(getIfAbsent().test(val), alias, column, val); + } + + default Children leIfAbsent(KProperty column, Object val) { + return le(getIfAbsent().test(val), null, column, val); + } + + default Children leIfAbsent(String alias, KProperty column, Object val) { + return le(getIfAbsent().test(val), alias, column, val); + } + + default Children likeIfAbsent(KProperty column, Object val) { + return like(getIfAbsent().test(val), null, column, val); + } + + default Children likeIfAbsent(String alisa, KProperty column, Object val) { + return like(getIfAbsent().test(val), alisa, column, val); + } + + default Children notLikeIfAbsent(KProperty column, Object val) { + return notLike(getIfAbsent().test(val), null, column, val); + } + + default Children notLikeIfAbsent(String alias, KProperty column, Object val) { + return notLike(getIfAbsent().test(val), alias, column, val); + } + + default Children likeLeftIfAbsent(KProperty column, Object val) { + return likeLeft(getIfAbsent().test(val), null, column, val); + } + + default Children likeLeftIfAbsent(String alias, KProperty column, Object val) { + return likeLeft(getIfAbsent().test(val), alias, column, val); + } + + default Children likeRightIfAbsent(KProperty column, Object val) { + return likeRight(getIfAbsent().test(val), null, column, val); + } + + default Children likeRightIfAbsent(String alias, KProperty column, Object val) { + return likeRight(getIfAbsent().test(val), alias, column, val); + } +} diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java index df2069f..f2ee99a 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java @@ -6,18 +6,22 @@ import com.baomidou.mybatisplus.core.conditions.query.Query; import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments; import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; import com.baomidou.mybatisplus.core.metadata.TableInfo; -import com.baomidou.mybatisplus.core.toolkit.ArrayUtils; -import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; -import com.baomidou.mybatisplus.core.toolkit.StringPool; -import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.core.toolkit.*; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.github.yulichang.config.ConfigProperties; +import com.github.yulichang.config.MybatisPlusJoinIfAbsent; +import com.github.yulichang.query.interfaces.CompareIfAbsent; import com.github.yulichang.query.interfaces.StringJoin; import com.github.yulichang.toolkit.Asserts; import com.github.yulichang.toolkit.TableHelper; +import com.github.yulichang.toolkit.ThrowOptional; +import lombok.Getter; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -30,7 +34,8 @@ import java.util.stream.Collectors; */ @SuppressWarnings("unused") public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper> - implements Query, T, SFunction>, StringJoin, T> { + implements Query, T, SFunction>, StringJoin, T>, + CompareIfAbsent, SFunction> { /** * 查询字段 @@ -45,7 +50,8 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper extends AbstractLambdaWrapper tableNameFunc; + + @Getter + private MybatisPlusJoinIfAbsent ifAbsent = ConfigProperties.ifAbsent; /** * 不建议直接 new 该实例,使用 Wrappers.lambdaQuery(entity) @@ -75,9 +92,10 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper entityClass, SharedString from, SharedString sqlSelect, AtomicInteger paramNameSeq, Map paramNameValuePairs, MergeSegments mergeSegments, SharedString lastSql, SharedString sqlComment, SharedString sqlFirst, - List selectColumns, List ignoreColumns, boolean selectDistinct) { + List selectColumns, List ignoreColumns, boolean selectDistinct, + MybatisPlusJoinIfAbsent ifAbsent) { super.setEntity(entity); - super.setEntityClass(entityClass); + setEntityClass(entityClass); this.paramNameSeq = paramNameSeq; this.paramNameValuePairs = paramNameValuePairs; this.expression = mergeSegments; @@ -85,10 +103,11 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper this.sqlFirst = sqlFirst).catchDo(); this.selectColumns = selectColumns; this.ignoreColumns = ignoreColumns; this.selectDistinct = selectDistinct; + this.ifAbsent = ifAbsent; } /** @@ -214,7 +233,8 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper stringQuery() { return new MPJQueryWrapper<>(getEntity(), getEntityClass(), paramNameSeq, paramNameValuePairs, - expression, sqlSelect, from, lastSql, sqlComment, sqlFirst, selectColumns, ignoreColumns, selectDistinct); + expression, sqlSelect, from, lastSql, sqlComment, sqlFirst, selectColumns, ignoreColumns, + selectDistinct, ifAbsent); } @Override @@ -241,15 +261,86 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper setAlias(String alias) { + Assert.isTrue(StringUtils.isNotBlank(alias), "别名不能为空"); + this.alias = alias; + return typedThis; } + /** + * 逻辑删除 + */ + public String getSubLogicSql() { + return StringPool.EMPTY; + } + + /** + * 关闭主表逻辑删除 + */ + public MPJLambdaQueryWrapper disableLogicDel() { + this.logicSql = false; + return typedThis; + } + + /** + * 启用主表逻辑删除 + */ + public MPJLambdaQueryWrapper enableLogicDel() { + this.logicSql = true; + return typedThis; + } + + /** + * 逻辑删除 + */ + public boolean getLogicSql() { + return logicSql; + } + + public boolean getSelectDistinct() { return selectDistinct; } + /** + * 动态表名 + * 如果主表需要动态表名,主表实体必须添加 @DynamicTableName 注解 + * 关联表则不需要 加不加注解都会生效 + *

+ * + * @see com.github.yulichang.annotation.DynamicTableName + */ + public MPJLambdaQueryWrapper setTableName(Function func) { + this.tableNameFunc = func; + return typedThis; + } + + public String getTableName(String tableName) { + if (this.tableNameFunc == null) { + return tableName; + } + return this.tableNameFunc.apply(tableName); + } + + @SuppressWarnings("DuplicatedCode") + public String getTableNameEnc(String tableName) { + String decode; + try { + decode = URLDecoder.decode(tableName, "UTF-8"); + } catch (UnsupportedEncodingException e) { + decode = tableName; + } + if (this.tableNameFunc == null) { + return decode; + } + return this.tableNameFunc.apply(decode); + } + + public MPJLambdaQueryWrapper setIfAbsent(MybatisPlusJoinIfAbsent ifAbsent) { + this.ifAbsent = ifAbsent; + return typedThis; + } + /** * 用于生成嵌套 sql *

故 sqlSelect selectColumn ignoreColumns from不向下传递

@@ -257,7 +348,34 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper instance() { return new MPJLambdaQueryWrapper<>(getEntity(), getEntityClass(), null, null, paramNameSeq, paramNameValuePairs, - new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), null, null, selectDistinct); + new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), + null, null, selectDistinct, ifAbsent); + } + + @Override + public Class getEntityClass() { + try { + return super.getEntityClass(); + } catch (Throwable throwable) { + return null; + } + } + + @Override + public MPJLambdaQueryWrapper setEntityClass(Class entityClass) { + try { + return super.setEntityClass(entityClass); + } catch (Throwable throwable) { + return this; + } + } + + public SharedString getSqlFirstField() { + try { + return sqlSelect; + } catch (Throwable throwable) { + return SharedString.emptyString(); + } } @Override @@ -267,6 +385,7 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper extends AbstractWrapper> implements - Query, T, String>, StringJoin, T>, Chain { + Query, T, String>, StringJoin, T>, Chain, + CompareIfAbsent, String> { /** * 查询字段 @@ -85,6 +89,9 @@ public class MPJQueryWrapper extends AbstractWrapper extends AbstractWrapper paramNameValuePairs, MergeSegments mergeSegments, SharedString sqlSelect, SharedString from, SharedString lastSql, SharedString sqlComment, SharedString sqlFirst, - List selectColumns, List ignoreColumns, boolean selectDistinct) { + List selectColumns, List ignoreColumns, boolean selectDistinct, + MybatisPlusJoinIfAbsent ifAbsent) { super.setEntity(entity); - super.setEntityClass(entityClass); + setEntityClass(entityClass); this.paramNameSeq = paramNameSeq; this.paramNameValuePairs = paramNameValuePairs; this.expression = mergeSegments; @@ -125,10 +133,11 @@ public class MPJQueryWrapper extends AbstractWrapper this.sqlFirst = sqlFirst).catchDo(); this.selectColumns = selectColumns; this.ignoreColumns = ignoreColumns; this.selectDistinct = selectDistinct; + this.ifAbsent = ifAbsent; } /** @@ -139,6 +148,11 @@ public class MPJQueryWrapper extends AbstractWrapper setIfAbsent(MybatisPlusJoinIfAbsent ifAbsent) { + this.ifAbsent = ifAbsent; + return this; + } + @Override protected String columnToString(String column) { if (checkSqlInjection && MPJSqlInjectionUtils.check(column)) { @@ -315,6 +329,7 @@ public class MPJQueryWrapper extends AbstractWrapper extends AbstractWrapper lambda() { return new MPJLambdaQueryWrapper<>(getEntity(), getEntityClass(), from, sqlSelect, paramNameSeq, paramNameValuePairs, - expression, lastSql, sqlComment, sqlFirst, selectColumns, ignoreColumns, selectDistinct); + expression, lastSql, sqlComment, getSqlFirstField(), selectColumns, ignoreColumns, selectDistinct, ifAbsent); + } + + @Override + public Class getEntityClass() { + try { + return super.getEntityClass(); + } catch (Throwable throwable) { + return null; + } + } + + @Override + public MPJQueryWrapper setEntityClass(Class entityClass) { + try { + return super.setEntityClass(entityClass); + } catch (Throwable throwable) { + return this; + } + } + + public SharedString getSqlFirstField() { + try { + return sqlSelect; + } catch (Throwable throwable) { + return SharedString.emptyString(); + } } /** @@ -343,7 +384,8 @@ public class MPJQueryWrapper extends AbstractWrapper instance() { return new MPJQueryWrapper<>(getEntity(), getEntityClass(), paramNameSeq, paramNameValuePairs, new MergeSegments(), - null, null, SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), null, null, selectDistinct); + null, null, SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), + null, null, selectDistinct, ifAbsent); } @@ -354,6 +396,7 @@ public class MPJQueryWrapper extends AbstractWrapper比较值

+ * + * @author yulichang + * @since 1.4.9 + */ +@SuppressWarnings("unused") +public interface CompareIfAbsent extends Compare { + + MybatisPlusJoinIfAbsent getIfAbsent(); + + /** + * 等于 = + * + * @param column 字段 + * @param val 值 + * @return children + */ + default Children eqIfAbsent(R column, Object val) { + return eq(getIfAbsent().test(val), column, val); + } + + /** + * 不等于 <> + * + * @param column 字段 + * @param val 值 + * @return children + */ + default Children neIfAbsent(R column, Object val) { + return ne(getIfAbsent().test(val), column, val); + } + + /** + * 大于 > + * + * @param column 字段 + * @param val 值 + * @return children + */ + default Children gtIfAbsent(R column, Object val) { + return gt(getIfAbsent().test(val), column, val); + } + + /** + * 大于等于 >= + * + * @param column 字段 + * @param val 值 + * @return children + */ + default Children geIfAbsent(R column, Object val) { + return ge(getIfAbsent().test(val), column, val); + } + + /** + * 小于 < + * + * @param column 字段 + * @param val 值 + * @return children + */ + default Children ltIfAbsent(R column, Object val) { + return lt(getIfAbsent().test(val), column, val); + } + + /** + * 小于等于 <= + * + * @param column 字段 + * @param val 值 + * @return children + */ + default Children leIfAbsent(R column, Object val) { + return le(getIfAbsent().test(val), column, val); + } + + /** + * LIKE '%值%' + * + * @param column 字段 + * @param val 值 + * @return children + */ + default Children likeIfAbsent(R column, Object val) { + return like(getIfAbsent().test(val), column, val); + } + + /** + * NOT LIKE '%值%' + * + * @param column 字段 + * @param val 值 + * @return children + */ + default Children notLikeIfAbsent(R column, Object val) { + return notLike(getIfAbsent().test(val), column, val); + } + + /** + * NOT LIKE '%值' + * + * @param column 字段 + * @param val 值 + * @return children + */ + default Children notLikeLeftIfAbsent(R column, Object val) { + return notLikeLeft(getIfAbsent().test(val), column, val); + } + + /** + * NOT LIKE '值%' + * + * @param column 字段 + * @param val 值 + * @return children + */ + default Children notLikeRightIfAbsent(R column, Object val) { + return notLikeRight(getIfAbsent().test(val), column, val); + } + + /** + * LIKE '%值' + * + * @param column 字段 + * @param val 值 + * @return children + */ + default Children likeLeftIfAbsent(R column, Object val) { + return likeLeft(getIfAbsent().test(val), column, val); + } + + /** + * LIKE '值%' + * + * @param column 字段 + * @param val 值 + * @return children + */ + default Children likeRightIfAbsent(R column, Object val) { + return likeRight(getIfAbsent().test(val), column, val); + } +} diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/toolkit/MPJStringUtils.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/toolkit/MPJStringUtils.java index 0a8b55e..8506652 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/toolkit/MPJStringUtils.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/toolkit/MPJStringUtils.java @@ -598,10 +598,25 @@ public final class MPJStringUtils { /** * 过滤sql黑名单字符,存在 SQL 注入,去除空白内容 */ - Matcher matcher = REPLACE_BLANK.matcher(str); - str = matcher.replaceAll(""); + str = replaceAllBlank(str); } return str; } + + /** + * 字符串去除空白内容: + *
    + *
  • \n 回车
  • + *
  • \t 水平制表符
  • + *
  • \s 空格
  • + *
  • \r 换行
  • + *
+ * + * @param str 字符串 + */ + public static String replaceAllBlank(String str) { + Matcher matcher = REPLACE_BLANK.matcher(str); + return matcher.replaceAll(""); + } } diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/toolkit/ThrowOptional.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/toolkit/ThrowOptional.java new file mode 100644 index 0000000..f0fcc39 --- /dev/null +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/toolkit/ThrowOptional.java @@ -0,0 +1,53 @@ +package com.github.yulichang.toolkit; + +import java.util.Objects; +import java.util.function.Consumer; + +/** + * @author yulichang + * @since 1.4.9 + */ +@SuppressWarnings("unused") +public class ThrowOptional { + + private ThrowOptional() { + } + + private DoSomething doSomething; + + public static ThrowOptional tryDo(DoSomething doSomething) { + ThrowOptional optional = new ThrowOptional(); + Objects.requireNonNull(doSomething); + optional.doSomething = doSomething; + return optional; + } + + public void catchDo() { + try { + this.doSomething.doSomething(); + } catch (Throwable ignored) { + } + } + + public void catchDo(DoSomething doSomething) { + try { + this.doSomething.doSomething(); + } catch (Throwable ignored) { + doSomething.doSomething(); + } + } + + public void catchDo(Consumer consumer) { + try { + this.doSomething.doSomething(); + } catch (Throwable throwable) { + consumer.accept(throwable); + } + } + + + @FunctionalInterface + public interface DoSomething { + void doSomething(); + } +} diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJAbstractWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJAbstractWrapper.java index d8ee2e4..d8d8b85 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJAbstractWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJAbstractWrapper.java @@ -12,6 +12,8 @@ import com.baomidou.mybatisplus.core.toolkit.*; import com.baomidou.mybatisplus.core.toolkit.sql.SqlUtils; import com.baomidou.mybatisplus.core.toolkit.sql.StringEscape; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; +import com.github.yulichang.config.ConfigProperties; +import com.github.yulichang.config.MybatisPlusJoinIfAbsent; import com.github.yulichang.toolkit.LambdaUtils; import com.github.yulichang.toolkit.MPJSqlInjectionUtils; import com.github.yulichang.toolkit.Ref; @@ -39,8 +41,8 @@ import static java.util.stream.Collectors.joining; */ @SuppressWarnings({"unchecked", "unused", "DuplicatedCode"}) public abstract class MPJAbstractWrapper> extends Wrapper - implements Compare, Nested, Join, Func, OnCompare, - CompareStr, FuncStr { + implements CompareIfAbsent, Nested, Join, Func, OnCompare, + CompareStrIfAbsent, FuncStr { /** * 占位符 @@ -116,6 +118,12 @@ public abstract class MPJAbstractWrapper val != null && StringUtils.isNotBlank(val)) + * + * @param ifAbsent 判断 + * @return Children + */ + public Children setIfAbsent(MybatisPlusJoinIfAbsent ifAbsent) { + this.ifAbsent = ifAbsent; + return typedThis; + } + @Override public Children allEq(boolean condition, Map, V> params, boolean null2IsNull) { if (condition && CollectionUtils.isNotEmpty(params)) { @@ -400,7 +420,7 @@ public abstract class MPJAbstractWrapper Children groupBy(boolean condition, String alias, List> columns) { return maybeDo(condition, () -> { if (CollectionUtils.isNotEmpty(columns)) { - final String finalOne = columnsToString(index, isOn ? PrefixEnum.ON_FIRST : PrefixEnum.CD_FIRST, alias, columns); + final String finalOne = columnsToString(index, isOn ? PrefixEnum.ON_FIRST : PrefixEnum.CD_FIRST, alias, columns); appendSqlSegments(GROUP_BY, () -> finalOne); } }); @@ -737,6 +757,7 @@ public abstract class MPJAbstractWrapper extends MPJAbstractLambdaWrapper entityClass, SharedString sqlSelect, AtomicInteger paramNameSeq, Map paramNameValuePairs, MergeSegments mergeSegments, SharedString paramAlias, SharedString lastSql, SharedString sqlComment, SharedString sqlFirst, - TableList tableList, Integer index, String keyWord, Class joinClass, String tableName) { + TableList tableList, Integer index, String keyWord, Class joinClass, String tableName, + MybatisPlusJoinIfAbsent ifAbsent) { super.setEntity(entity); super.setEntityClass(entityClass); this.paramNameSeq = paramNameSeq; @@ -139,6 +141,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper extends MPJAbstractLambdaWrapper wrapper = new MPJLambdaWrapper(null, clazz, SharedString.emptyString(), paramNameSeq, paramNameValuePairs, new MergeSegments(), new SharedString(this.paramAlias .getStringValue()), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), - new TableList(), null, null, null, null) { + new TableList(), null, null, null, null, ifAbsent) { }; wrapper.tableList.setAlias(st); wrapper.tableList.setRootClass(clazz); @@ -402,7 +405,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper instance(Integer index, String keyWord, Class joinClass, String tableName) { return new MPJLambdaWrapper<>(getEntity(), getEntityClass(), null, paramNameSeq, paramNameValuePairs, new MergeSegments(), this.paramAlias, SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), - this.tableList, index, keyWord, joinClass, tableName); + this.tableList, index, keyWord, joinClass, tableName, ifAbsent); } @Override @@ -415,5 +418,6 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper extends Compare { + + MybatisPlusJoinIfAbsent getIfAbsent(); + + default Children eqIfAbsent(SFunction column, Object val) { + return eq(getIfAbsent().test(val), null, column, val); + } + + default Children eqIfAbsent(String alias, SFunction column, Object val) { + return eq(getIfAbsent().test(val), alias, column, val); + } + + default Children neIfAbsent(SFunction column, Object val) { + return ne(getIfAbsent().test(val), null, column, val); + } + + default Children neIfAbsent(String alias, SFunction column, Object val) { + return ne(getIfAbsent().test(val), alias, column, val); + } + + default Children gtIfAbsent(SFunction column, Object val) { + return gt(getIfAbsent().test(val), null, column, val); + } + + default Children gtIfAbsent(String alias, SFunction column, Object val) { + return gt(getIfAbsent().test(val), alias, column, val); + } + + default Children geIfAbsent(SFunction column, Object val) { + return ge(getIfAbsent().test(val), null, column, val); + } + + default Children geIfAbsent(String alias, SFunction column, Object val) { + return ge(getIfAbsent().test(val), alias, column, val); + } + + default Children ltIfAbsent(SFunction column, Object val) { + return lt(getIfAbsent().test(val), null, column, val); + } + + default Children ltIfAbsent(String alias, SFunction column, Object val) { + return lt(getIfAbsent().test(val), alias, column, val); + } + + default Children leIfAbsent(SFunction column, Object val) { + return le(getIfAbsent().test(val), null, column, val); + } + + default Children leIfAbsent(String alias, SFunction column, Object val) { + return le(getIfAbsent().test(val), alias, column, val); + } + + default Children likeIfAbsent(SFunction column, Object val) { + return like(getIfAbsent().test(val), null, column, val); + } + + default Children likeIfAbsent(String alias, SFunction column, Object val) { + return like(getIfAbsent().test(val), alias, column, val); + } + + default Children notLikeIfAbsent(SFunction column, Object val) { + return notLike(getIfAbsent().test(val), null, column, val); + } + + default Children notLikeIfAbsent(String alias, SFunction column, Object val) { + return notLike(getIfAbsent().test(val), alias, column, val); + } + + default Children likeLeftIfAbsent(SFunction column, Object val) { + return likeLeft(getIfAbsent().test(val), null, column, val); + } + + default Children likeLeftIfAbsent(String alias, SFunction column, Object val) { + return likeLeft(getIfAbsent().test(val), alias, column, val); + } + + default Children likeRightIfAbsent(SFunction column, Object val) { + return likeRight(getIfAbsent().test(val), null, column, val); + } + + default Children likeRightIfAbsent(String alias, SFunction column, Object val) { + return likeRight(getIfAbsent().test(val), alias, column, val); + } +} diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/interfaces/CompareStrIfAbsent.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/interfaces/CompareStrIfAbsent.java new file mode 100644 index 0000000..c9f5922 --- /dev/null +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/interfaces/CompareStrIfAbsent.java @@ -0,0 +1,55 @@ +package com.github.yulichang.wrapper.interfaces; + +import com.github.yulichang.config.MybatisPlusJoinIfAbsent; + +/** + * {@link com.baomidou.mybatisplus.core.conditions.interfaces.Compare} + * + * @author yulichang + * @since 1.4.9 + */ +@SuppressWarnings("unused") +public interface CompareStrIfAbsent extends CompareStr { + + MybatisPlusJoinIfAbsent getIfAbsent(); + + default Children eqIfAbsent(R column, Object val) { + return eq(getIfAbsent().test(val), column, val); + } + + default Children neIfAbsent(R column, Object val) { + return ne(getIfAbsent().test(val), column, val); + } + + default Children gtIfAbsent(R column, Object val) { + return gt(getIfAbsent().test(val), column, val); + } + + default Children geIfAbsent(R column, Object val) { + return ge(getIfAbsent().test(val), column, val); + } + + default Children ltIfAbsent(R column, Object val) { + return lt(getIfAbsent().test(val), column, val); + } + + default Children leIfAbsent(R column, Object val) { + return le(getIfAbsent().test(val), column, val); + } + + default Children likeIfAbsent(R column, Object val) { + return like(getIfAbsent().test(val), column, val); + } + + default Children notLikeIfAbsent(R column, Object val) { + return notLike(getIfAbsent().test(val), column, val); + } + + default Children likeLeftIfAbsent(R column, Object val) { + return likeLeft(getIfAbsent().test(val), column, val); + } + + default Children likeRightIfAbsent(R column, Object val) { + return likeRight(getIfAbsent().test(val), column, val); + } +} diff --git a/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/QueryWrapperTest.java b/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/QueryWrapperTest.java index 43ec2cc..afce143 100644 --- a/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/QueryWrapperTest.java +++ b/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/QueryWrapperTest.java @@ -115,4 +115,35 @@ class QueryWrapperTest { System.out.println(joinMaps); } + @Test + void test5() { + ThreadLocalUtils.set("SELECT t.id, t.pid, t.`name`, t.`json`, t.sex, t.head_img, t.create_time, t.address_id, " + + "t.address_id2, t.del, t.create_by, t.update_by FROM `user` t LEFT JOIN address t2 ON t2.user_id = t.id " + + "WHERE t.del = false AND (t.id <= ?)"); + List userDO = userMapper.selectJoinList(UserDO.class, new MPJQueryWrapper() + .selectAll(UserDO.class) + .leftJoin("address t2 on t2.user_id = t.id") + .le("t.id ", 10).lambda()); + System.out.println(userDO); + + ThreadLocalUtils.set("SELECT t.id, t.pid, t.`name`, t.`json`, t.sex, t.head_img, t.create_time, t.address_id, " + + "t.address_id2, t.del, t.create_by, t.update_by, t2.address AS userAddress FROM `user` t " + + "LEFT JOIN address t2 ON t2.user_id = t.id WHERE t.del = false AND (t.id <= ?)"); + List dto = userMapper.selectJoinList(UserDTO.class, new MPJQueryWrapper() + .selectAll(UserDO.class) + .select("t2.address AS userAddress") + .leftJoin("address t2 on t2.user_id = t.id") + .le("t.id ", 10).lambda()); + System.out.println(dto); + } + + @Test + void test6() { + ThreadLocalUtils.set("SELECT t.id AS idea, t.user_id AS uuid, t.tenant_id FROM user_tenant t WHERE (t.id <= ?) AND t.tenant_id = 1"); + List userDO = userTenantMapper.selectJoinList(UserTenantDO.class, new MPJQueryWrapper() + .selectAll(UserTenantDO.class) + .le("t.id ", 10).lambda()); + System.out.println(userDO); + } + } diff --git a/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/m/IfAbsentTest.java b/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/m/IfAbsentTest.java new file mode 100644 index 0000000..fe46ba4 --- /dev/null +++ b/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/m/IfAbsentTest.java @@ -0,0 +1,66 @@ +package com.github.yulichang.test.join.m; + +import com.github.yulichang.config.enums.IfAbsentEnum; +import com.github.yulichang.test.join.entity.UserDO; +import com.github.yulichang.test.util.Reset; +import com.github.yulichang.test.util.ThreadLocalUtils; +import com.github.yulichang.toolkit.JoinWrappers; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; + +@SpringBootTest +public class IfAbsentTest { + + @BeforeEach + void setUp() { + Reset.reset(); + } + + @Test + void ifAbsent() { + ThreadLocalUtils.set("SELECT t.id, t.pid, t.`name`, t.`json`, t.sex, t.head_img, t.create_time, t.address_id, " + + "t.address_id2, t.del, t.create_by, t.update_by FROM `user` t " + + "WHERE t.del = false AND (t.id = ? AND t.head_img = ? AND t.`name` = ?)"); + MPJLambdaWrapper wrapper = JoinWrappers.lambda(UserDO.class) + .selectAll(UserDO.class) + .eq(UserDO::getId, 1) + .eqIfAbsent(UserDO::getPid, null) + .eqIfAbsent(UserDO::getAddressId, "") + .eqIfAbsent(UserDO::getImg, "\t") + .eqIfAbsent(UserDO::getName, "张三 1"); + List list = wrapper.list(); + list.forEach(System.out::println); + + ThreadLocalUtils.set("SELECT t.id, t.pid, t.`name`, t.`json`, t.sex, t.head_img, t.create_time, t.address_id, " + + "t.address_id2, t.del, t.create_by, t.update_by FROM `user` t " + + "WHERE t.del = false AND (t.id = ? AND t.`name` = ?)"); + MPJLambdaWrapper wrapper1 = JoinWrappers.lambda(UserDO.class) + .selectAll(UserDO.class) + .setIfAbsent(IfAbsentEnum.NOT_BLANK) + .eq(UserDO::getId, 1) + .eqIfAbsent(UserDO::getPid, null) + .eqIfAbsent(UserDO::getAddressId, "") + .eqIfAbsent(UserDO::getImg, "\t") + .eqIfAbsent(UserDO::getName, "张三 1"); + List list1 = wrapper1.list(); + list1.forEach(System.out::println); + + ThreadLocalUtils.set("SELECT t.id, t.pid, t.`name`, t.`json`, t.sex, t.head_img, t.create_time, t.address_id, " + + "t.address_id2, t.del, t.create_by, t.update_by FROM `user` t " + + "WHERE t.del = false AND (t.id = ? AND t.pid = ? AND t.`name` = ? AND t.head_img = ? AND t.`name` = ?)"); + MPJLambdaWrapper wrapper2 = JoinWrappers.lambda(UserDO.class) + .selectAll(UserDO.class) + .setIfAbsent(o -> true) + .eq(UserDO::getId, 1) + .eqIfAbsent(UserDO::getPid, null) + .eqIfAbsent(UserDO::getName, "") + .eqIfAbsent(UserDO::getImg, "\t") + .eqIfAbsent(UserDO::getName, "张三 1"); + List list2 = wrapper2.list(); + list2.forEach(System.out::println); + } +}