fix selectSub多次调用报错和优化union

This commit is contained in:
yulichang 2023-11-17 23:41:14 +08:00
parent 630c320cd3
commit aa0f9e87bf
35 changed files with 554 additions and 187 deletions

View File

@ -16,6 +16,7 @@ import com.github.yulichang.kt.interfaces.Func;
import com.github.yulichang.kt.interfaces.OnCompare;
import com.github.yulichang.toolkit.KtUtils;
import com.github.yulichang.toolkit.MPJSqlInjectionUtils;
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;
@ -29,6 +30,7 @@ import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Supplier;
import static com.baomidou.mybatisplus.core.enums.SqlKeyword.*;
import static com.baomidou.mybatisplus.core.enums.WrapperKeyword.APPLY;
@ -146,6 +148,21 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
return typedThis;
}
/**
* 转为子类方便自定义继承扩展
*/
public <C extends Children> C toChildren(Ref<C> children) {
return (C) this;
}
/**
* 转为子类方便自定义继承扩展
* 需要子类自定义字段
*/
public <C extends Children> C toChildren(Supplier<C> s) {
return (C) this;
}
/**
* 开启检查 SQL 注入
*/
@ -670,7 +687,6 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
*/
public Children setParamAlias(String paramAlias) {
Assert.notEmpty(paramAlias, "paramAlias can not be empty!");
Assert.isNull(this.paramAlias.getStringValue(), "Please do not call the method repeatedly!");
this.paramAlias.setStringValue(paramAlias);
return typedThis;
}

View File

@ -7,10 +7,7 @@ import com.baomidou.mybatisplus.core.toolkit.*;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.kt.interfaces.Query;
import com.github.yulichang.kt.interfaces.QueryLabel;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.KtUtils;
import com.github.yulichang.toolkit.KtWrapperUtils;
import com.github.yulichang.toolkit.TableList;
import com.github.yulichang.toolkit.*;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.wrapper.interfaces.Chain;
import com.github.yulichang.wrapper.interfaces.SelectWrapper;
@ -31,7 +28,7 @@ import java.util.stream.Collectors;
* @author yulichang
* @since 1.4.6
*/
@SuppressWarnings({"unused", "unchecked", "rawtypes"})
@SuppressWarnings({"unused", "unchecked", "rawtypes", "DuplicatedCode"})
public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapper<T>> implements
Query<KtLambdaWrapper<T>>, QueryLabel<KtLambdaWrapper<T>>, Chain<T>, SelectWrapper<T, KtLambdaWrapper<T>> {
@ -205,11 +202,12 @@ public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapp
/**
* 子查询
*/
@SuppressWarnings("DuplicatedCode")
public KtLambdaWrapper<T> selectSub(Class<?> clazz, String st, Consumer<KtLambdaWrapper<?>> consumer, KProperty<?> alias) {
KtLambdaWrapper<?> wrapper = new KtLambdaWrapper(null, clazz, SharedString.emptyString(), paramNameSeq, paramNameValuePairs,
new MergeSegments(), SharedString.emptyString(), this.paramAlias, SharedString.emptyString(), SharedString.emptyString(),
new TableList(), null, null, null, null) {
public KtLambdaWrapper<T> selectSub(Class<?> clazz, String st,
Consumer<KtLambdaWrapper<?>> consumer, KProperty<?> alias) {
KtLambdaWrapper<?> wrapper = new KtLambdaWrapper(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) {
};
wrapper.tableList.setAlias(st);
wrapper.tableList.setRootClass(clazz);
@ -218,22 +216,29 @@ public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapp
wrapper.subTableAlias = st;
consumer.accept(wrapper);
addCustomWrapper(wrapper);
this.selectColumns.add(new SelectSub(() -> KtWrapperUtils.buildSubSqlByWrapper(clazz, wrapper, alias.getName()), hasAlias, this.alias));
this.selectColumns.add(new SelectSub(() -> KtWrapperUtils.buildSubSqlByWrapper(
clazz, wrapper, alias.getName()), hasAlias, this.alias));
return typedThis;
}
/**
* union
* <p>
* 推荐使用 union(Class<U> clazz, Consumer<MPJLambdaWrapper<U>> consumer)
* wrapper.union(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @see #union(Class, Consumer)
* @deprecated union 不支持子查询
*/
@SuppressWarnings("UnusedReturnValue")
@Deprecated
@SuppressWarnings("DeprecatedIsStillUsed")
public final KtLambdaWrapper<T> union(KtLambdaWrapper<?>... wrappers) {
StringBuilder sb = new StringBuilder();
for (KtLambdaWrapper<?> wrapper : wrappers) {
addCustomWrapper(wrapper);
Class<?> entityClass = wrapper.getEntityClass();
Assert.notNull(entityClass, "请使用 new MPJLambdaWrapper(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
sb.append(" UNION ")
.append(KtWrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
sb.append(" UNION ").append(KtWrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
}
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
@ -243,17 +248,45 @@ public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapp
}
/**
* union all
* union
* <p>
* wrapper.union(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @param clazz union语句的主表类型
* @since 1.4.7.3
*/
@SafeVarargs
public final <E, F> KtLambdaWrapper<T> unionAll(KtLambdaWrapper<T>... wrappers) {
public <U> KtLambdaWrapper<T> union(Class<U> clazz, Consumer<KtLambdaWrapper<U>> consumer) {
KtLambdaWrapper<U> unionWrapper = KtWrappers.query(clazz);
addCustomWrapper(unionWrapper);
consumer.accept(unionWrapper);
String sb = " UNION " + KtWrapperUtils.buildUnionSqlByWrapper(clazz, unionWrapper);
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
}
unionSql.setStringValue(unionSql.getStringValue() + sb);
return typedThis;
}
/**
* union
* <p>
* 推荐使用 unionAll(Class<U> clazz, Consumer<MPJLambdaWrapper<U>> consumer)
* wrapper.unionAll(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @see #unionAll(Class, Consumer)
* @deprecated union 不支持子查询
*/
@Deprecated
@SuppressWarnings("DeprecatedIsStillUsed")
public final KtLambdaWrapper<T> unionAll(KtLambdaWrapper<?>... wrappers) {
StringBuilder sb = new StringBuilder();
for (KtLambdaWrapper<?> wrapper : wrappers) {
addCustomWrapper(wrapper);
Class<?> entityClass = wrapper.getEntityClass();
Assert.notNull(entityClass, "请使用 new MPJLambdaWrapper(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
sb.append(" UNION ALL ")
.append(KtWrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
sb.append(" UNION ALL ").append(KtWrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
}
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
@ -262,7 +295,28 @@ public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapp
return typedThis;
}
@SuppressWarnings("DuplicatedCode")
/**
* union
* <p>
* wrapper.unionAll(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @param clazz union语句的主表类型
* @since 1.4.7.3
*/
public <U> KtLambdaWrapper<T> unionAll(Class<U> clazz, Consumer<KtLambdaWrapper<U>> consumer) {
KtLambdaWrapper<U> unionWrapper = KtWrappers.query(clazz);
addCustomWrapper(unionWrapper);
consumer.accept(unionWrapper);
String sb = " UNION ALL " + KtWrapperUtils.buildUnionSqlByWrapper(clazz, unionWrapper);
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
}
unionSql.setStringValue(unionSql.getStringValue() + sb);
return typedThis;
}
private void addCustomWrapper(KtLambdaWrapper<?> wrapper) {
if (Objects.isNull(wrapperIndex)) {
wrapperIndex = new AtomicInteger(0);
@ -280,7 +334,6 @@ public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapp
* 查询条件 SQL 片段
*/
@Override
@SuppressWarnings("DuplicatedCode")
public String getSqlSelect() {
if (StringUtils.isBlank(sqlSelect.getStringValue()) && CollectionUtils.isNotEmpty(selectColumns)) {
String s = selectColumns.stream().map(i -> {
@ -349,7 +402,7 @@ public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapp
@Override
protected KtLambdaWrapper<T> instance(Integer index, String keyWord, Class<?> joinClass, String tableName) {
return new KtLambdaWrapper<>(getEntity(), getEntityClass(), null, paramNameSeq, paramNameValuePairs,
new MergeSegments(), SharedString.emptyString(), this.paramAlias, SharedString.emptyString(), SharedString.emptyString(),
new MergeSegments(), this.paramAlias, SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
this.tableList, index, keyWord, joinClass, tableName);
}

View File

@ -16,9 +16,9 @@ import java.util.Optional;
* @author yulichang
* @since 1.4.6
*/
@SuppressWarnings("DuplicatedCode")
public class KtWrapperUtils {
@SuppressWarnings("DuplicatedCode")
public static String buildSubSqlByWrapper(Class<?> clazz, KtLambdaWrapper<?> wrapper, String alias) {
TableInfo tableInfo = TableHelper.get(clazz);
Asserts.hasTable(tableInfo, clazz);
@ -53,7 +53,6 @@ public class KtWrapperUtils {
alias);
}
@SuppressWarnings("DuplicatedCode")
public static String buildUnionSqlByWrapper(Class<?> clazz, KtLambdaWrapper<?> wrapper) {
TableInfo tableInfo = TableHelper.get(clazz);
Asserts.hasTable(tableInfo, clazz);
@ -94,7 +93,6 @@ public class KtWrapperUtils {
return SqlScriptUtils.safeParam(paramStr, null);
}
@SuppressWarnings("DuplicatedCode")
private static String getEntitySql(TableInfo tableInfo, KtLambdaWrapper<?> wrapper) {
Object obj = wrapper.getEntity();
if (Objects.isNull(obj)) {
@ -126,6 +124,9 @@ public class KtWrapperUtils {
}
private static String mainLogic(boolean hasWhere, Class<?> clazz, KtLambdaWrapper<?> wrapper) {
if (!wrapper.getLogicSql()) {
return StringPool.EMPTY;
}
String info = LogicInfoUtils.getLogicInfo(null, clazz, true, wrapper.getAlias());
if (StringUtils.isNotBlank(info)) {
if (hasWhere) {

View File

@ -700,7 +700,6 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
*/
public Children setParamAlias(String paramAlias) {
Assert.notEmpty(paramAlias, "paramAlias can not be empty!");
Assert.isTrue(StringUtils.isBlank(this.paramAlias.getStringValue()), "Please do not call the method repeatedly!");
this.paramAlias.setStringValue(paramAlias);
return typedThis;
}

View File

@ -6,10 +6,8 @@ import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.TableList;
import com.github.yulichang.toolkit.WrapperUtils;
import com.github.yulichang.toolkit.*;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.wrapper.interfaces.Chain;
import com.github.yulichang.wrapper.interfaces.Query;
@ -30,7 +28,7 @@ import java.util.stream.Collectors;
*
* @author yulichang
*/
@SuppressWarnings({"unused"})
@SuppressWarnings({"unused", "DuplicatedCode"})
public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWrapper<T>> implements
Query<MPJLambdaWrapper<T>>, QueryLabel<MPJLambdaWrapper<T>>, Chain<T>, SelectWrapper<T, MPJLambdaWrapper<T>> {
@ -205,10 +203,10 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
/**
* 子查询
*/
@SuppressWarnings("DuplicatedCode")
public <E, F> MPJLambdaWrapper<T> selectSub(Class<E> clazz, String st, Consumer<MPJLambdaWrapper<E>> consumer, SFunction<F, ?> alias) {
MPJLambdaWrapper<E> wrapper = new MPJLambdaWrapper<E>(null, clazz, SharedString.emptyString(), paramNameSeq, paramNameValuePairs,
new MergeSegments(), this.paramAlias, SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
MPJLambdaWrapper<E> wrapper = new MPJLambdaWrapper<E>(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) {
};
wrapper.tableList.setAlias(st);
@ -224,16 +222,22 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
/**
* union
* <p>
* 推荐使用 union(Class<U> clazz, Consumer<MPJLambdaWrapper<U>> consumer)
* wrapper.union(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @see #union(Class, Consumer)
* @deprecated union 不支持子查询
*/
@SuppressWarnings("UnusedReturnValue")
@Deprecated
@SuppressWarnings({"UnusedReturnValue", "DeprecatedIsStillUsed"})
public final MPJLambdaWrapper<T> union(MPJLambdaWrapper<?>... wrappers) {
StringBuilder sb = new StringBuilder();
for (MPJLambdaWrapper<?> wrapper : wrappers) {
addCustomWrapper(wrapper);
Class<?> entityClass = wrapper.getEntityClass();
Assert.notNull(entityClass, "请使用 new MPJLambdaWrapper(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
sb.append(" UNION ")
.append(WrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
sb.append(" UNION ").append(WrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
}
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
@ -243,17 +247,45 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
}
/**
* union all
* union
* <p>
* wrapper.union(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @param clazz union语句的主表类型
* @since 1.4.7.3
*/
@SuppressWarnings("UnusedReturnValue")
public final MPJLambdaWrapper<T> unionAll(MPJLambdaWrapper<?>... wrappers) {
public <U> MPJLambdaWrapper<T> union(Class<U> clazz, Consumer<MPJLambdaWrapper<U>> consumer) {
MPJLambdaWrapper<U> unionWrapper = JoinWrappers.lambda(clazz);
addCustomWrapper(unionWrapper);
consumer.accept(unionWrapper);
String sb = " UNION " + WrapperUtils.buildUnionSqlByWrapper(clazz, unionWrapper);
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
}
unionSql.setStringValue(unionSql.getStringValue() + sb);
return typedThis;
}
/**
* union
* <p>
* 推荐使用 unionAll(Class<U> clazz, Consumer<MPJLambdaWrapper<U>> consumer)
* wrapper.unionAll(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @see #unionAll(Class, Consumer)
* @deprecated union 不支持子查询
*/
@Deprecated
@SuppressWarnings("DeprecatedIsStillUsed")
public MPJLambdaWrapper<T> unionAll(MPJLambdaWrapper<?>... wrappers) {
StringBuilder sb = new StringBuilder();
for (MPJLambdaWrapper<?> wrapper : wrappers) {
addCustomWrapper(wrapper);
Class<?> entityClass = wrapper.getEntityClass();
Assert.notNull(entityClass, "请使用 new MPJLambdaWrapper(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
sb.append(" UNION ALL ")
.append(WrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
sb.append(" UNION ALL ").append(WrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
}
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
@ -262,7 +294,28 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
return typedThis;
}
@SuppressWarnings("DuplicatedCode")
/**
* union
* <p>
* wrapper.unionAll(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @param clazz union语句的主表类型
* @since 1.4.7.3
*/
public <U> MPJLambdaWrapper<T> unionAll(Class<U> clazz, Consumer<MPJLambdaWrapper<U>> consumer) {
MPJLambdaWrapper<U> unionWrapper = JoinWrappers.lambda(clazz);
addCustomWrapper(unionWrapper);
consumer.accept(unionWrapper);
String sb = " UNION ALL " + WrapperUtils.buildUnionSqlByWrapper(clazz, unionWrapper);
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
}
unionSql.setStringValue(unionSql.getStringValue() + sb);
return typedThis;
}
private void addCustomWrapper(MPJLambdaWrapper<?> wrapper) {
if (Objects.isNull(wrapperIndex)) {
wrapperIndex = new AtomicInteger(0);
@ -280,7 +333,6 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
* 查询条件 SQL 片段
*/
@Override
@SuppressWarnings("DuplicatedCode")
public String getSqlSelect() {
if (StringUtils.isBlank(sqlSelect.getStringValue()) && CollectionUtils.isNotEmpty(selectColumns)) {
String s = selectColumns.stream().map(i -> {

View File

@ -1074,30 +1074,6 @@ class LambdaWrapperTest {
}
}
/**
* select 子查询
*/
@Test
void sub() {
ThreadLocalUtils.set("SELECT (SELECT st.id FROM `user` st WHERE st.del = false AND (st.id = t.id) LIMIT 1) AS id FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE t.del = false AND t1.del = false AND (t.id <= ?)");
MPJLambdaWrapper<UserDO> wrapper = JoinWrappers.lambda(UserDO.class)
.selectSub(UserDO.class, w -> w.select(UserDO::getId)
.eq(UserDO::getId, UserDO::getId)
.last("limit 1"), UserDO::getId)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.le(UserDO::getId, 100);
wrapper.list();
ThreadLocalUtils.set("SELECT (SELECT st.id FROM area st WHERE st.del = false AND (st.id = t1.id) LIMIT 1) AS id FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE t.del = false AND t1.del = false AND (t.id <= ?)");
MPJLambdaWrapper<UserDO> wrapper1 = JoinWrappers.lambda(UserDO.class)
.selectSub(AreaDO.class, w -> w.select(AreaDO::getId)
.eq(AreaDO::getId, AddressDO::getId)
.last("limit 1"), UserDO::getId)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.le(UserDO::getId, 100);
wrapper1.list();
}
/**
* select 子查询
*/
@ -1111,45 +1087,4 @@ class LambdaWrapperTest {
.orderByDesc("t.id");
wrapper.list();
}
/**
* select 子查询
*/
@Test
void union() {
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 = ?) UNION 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.`name` = ? AND (t.`name` = ?)) UNION 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.pid = ?)");
MPJLambdaWrapper<UserDO> wrapper = JoinWrappers.lambda(UserDO.class)
.selectAll(UserDO.class)
.eq(UserDO::getId, 1);
MPJLambdaWrapper<UserDO> wrapper1 = JoinWrappers.lambda(UserDO.class)
.selectAll(UserDO.class)
.disableLogicDel()
.eq(UserDO::getName, "张三 2")
.and(w -> w.eq(UserDO::getName, "张三 2"));
MPJLambdaWrapper<UserDO> wrapper2 = JoinWrappers.lambda(UserDO.class)
.selectAll(UserDO.class)
.eq(UserDO::getPid, 2);
wrapper.union(wrapper1, wrapper2);
List<UserDO> list = wrapper.list();
assert list.size() == 7;
}
@Test
void unionAll() {
ThreadLocalUtils.set("SELECT t.id FROM `user` t WHERE t.del = false AND (t.id = ?) UNION ALL SELECT t.id FROM address t UNION ALL SELECT t.id FROM area t WHERE t.del = false AND (t.id = ?)");
MPJLambdaWrapper<UserDO> wrapper = JoinWrappers.lambda(UserDO.class)
.select(UserDO::getId)
.eq(UserDO::getId, 1);
MPJLambdaWrapper<AddressDO> wrapper1 = JoinWrappers.lambda(AddressDO.class)
.select(AddressDO::getId)
.disableLogicDel();
MPJLambdaWrapper<AreaDO> wrapper2 = JoinWrappers.lambda(AreaDO.class)
.select(AreaDO::getId)
.eq(AreaDO::getId, 2);
wrapper.unionAll(wrapper1, wrapper2);
List<UserDO> list = wrapper.list();
assert list.size() == 23 && list.get(0).getId() != null;
}
}

View File

@ -0,0 +1,51 @@
package com.github.yulichang.test.join.m;
import com.github.yulichang.test.join.entity.AddressDO;
import com.github.yulichang.test.join.entity.AreaDO;
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;
@SpringBootTest
public class SelectSubTest {
@BeforeEach
void setUp() {
Reset.reset();
}
/**
* select 子查询
*/
@Test
void sub() {
ThreadLocalUtils.set("SELECT (SELECT st.id FROM `user` st WHERE st.del = false AND (st.id = t.id AND st.id = ?) LIMIT 1) AS id, (SELECT st.id FROM `user` st WHERE st.del = false AND (st.id = t.id AND st.id = ?) LIMIT 1) AS name FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE t.del = false AND t1.del = false AND (t.id <= ?)");
MPJLambdaWrapper<UserDO> wrapper = JoinWrappers.lambda(UserDO.class)
.selectSub(UserDO.class, w -> w.select(UserDO::getId)
.eq(UserDO::getId, UserDO::getId)
.eq(UserDO::getId, 2)
.last("limit 1"), UserDO::getId)
.selectSub(UserDO.class, w -> w.select(UserDO::getId)
.eq(UserDO::getId, UserDO::getId)
.eq(UserDO::getId, 3)
.last("limit 1"), UserDO::getName)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.le(UserDO::getId, 100);
wrapper.list();
ThreadLocalUtils.set("SELECT (SELECT st.id FROM area st WHERE st.del = false AND (st.id = t1.id) LIMIT 1) AS id FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE t.del = false AND t1.del = false AND (t.id <= ?)");
MPJLambdaWrapper<UserDO> wrapper1 = JoinWrappers.lambda(UserDO.class)
.selectSub(AreaDO.class, w -> w.select(AreaDO::getId)
.eq(AreaDO::getId, AddressDO::getId)
.last("limit 1"), UserDO::getId)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.le(UserDO::getId, 100);
wrapper1.list();
}
}

View File

@ -0,0 +1,85 @@
package com.github.yulichang.test.join.m;
import com.github.yulichang.test.join.entity.AddressDO;
import com.github.yulichang.test.join.entity.AreaDO;
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;
@SuppressWarnings("deprecation")
@SpringBootTest
public class UnionTest {
@BeforeEach
void setUp() {
Reset.reset();
}
@Test
void union() {
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 = ?) UNION 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.`name` = ? AND (t.`name` = ?)) UNION 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.pid = ?)");
MPJLambdaWrapper<UserDO> wrapper = JoinWrappers.lambda(UserDO.class)
.selectAll(UserDO.class)
.eq(UserDO::getId, 1);
MPJLambdaWrapper<UserDO> wrapper1 = JoinWrappers.lambda(UserDO.class)
.selectAll(UserDO.class)
.disableLogicDel()
.eq(UserDO::getName, "张三 2")
.and(w -> w.eq(UserDO::getName, "张三 2"));
MPJLambdaWrapper<UserDO> wrapper2 = JoinWrappers.lambda(UserDO.class)
.selectAll(UserDO.class)
.eq(UserDO::getPid, 2);
wrapper.union(wrapper1, wrapper2);
List<UserDO> list = wrapper.list();
System.out.println(wrapper.getUnionSql());
assert list.size() == 7 && list.get(0).getId() != null;
}
@Test
void unionAll() {
ThreadLocalUtils.set("SELECT t.id FROM `user` t WHERE t.del = false AND (t.id = ?) UNION ALL SELECT t.id FROM address t UNION ALL SELECT t.id FROM area t WHERE t.del = false AND (t.id = ?)");
MPJLambdaWrapper<UserDO> wrapper = JoinWrappers.lambda(UserDO.class)
.select(UserDO::getId)
.eq(UserDO::getId, 1);
MPJLambdaWrapper<AddressDO> wrapper1 = JoinWrappers.lambda(AddressDO.class)
.select(AddressDO::getId)
.disableLogicDel();
MPJLambdaWrapper<AreaDO> wrapper2 = JoinWrappers.lambda(AreaDO.class)
.select(AreaDO::getId)
.eq(AreaDO::getId, 2);
wrapper.unionAll(wrapper1, wrapper2);
List<UserDO> list = wrapper.list();
assert list.size() == 23 && list.get(0).getId() != null;
}
@Test
void unionAll1() {
ThreadLocalUtils.set("SELECT t.id FROM `user` t WHERE t.del = false AND (t.id = ?) UNION ALL SELECT t.id FROM address t WHERE (t.id = ?) UNION ALL SELECT (SELECT st.id FROM area st WHERE st.del = false AND (st.id = ? AND (st.id = ?))) AS id FROM area t WHERE t.del = false AND (t.id = ? AND (t.id = ?))");
MPJLambdaWrapper<UserDO> wrapper = JoinWrappers.lambda(UserDO.class)
.select(UserDO::getId)
.eq(UserDO::getId, 1)
.unionAll(AddressDO.class, union -> union
.select(AddressDO::getId)
.disableLogicDel()
.eq(UserDO::getId, 2))
.unionAll(AreaDO.class, union -> union
.selectSub(AreaDO.class, sub -> sub
.select(AreaDO::getId)
.eq(AreaDO::getId, 3)
.and(and -> and.eq(AreaDO::getId, 4)), AreaDO::getId)
.eq(AreaDO::getId, 5)
.and(and -> and.eq(AreaDO::getId, 6)));
List<UserDO> list = wrapper.list();
assert list.size() == 2 && list.get(0).getId() != null;
}
}

View File

@ -0,0 +1,12 @@
package com.github.yulichang.test.kt.dto
@Suppress("unused")
class AreaDTO {
val id: Int? = null
val province: String? = null
val city: String? = null
val area: String? = null
val postcode: String? = null
val del: Boolean? = null
}

View File

@ -13,7 +13,7 @@ class AreaDO : Serializable {
var province: String? = null
var city: String? = null
var area: String? = null
var postcode: String? = null
var Postcode: String? = null
@TableLogic
var del: Boolean? = null

View File

@ -1,12 +0,0 @@
package com.github.yulichang.test.kt.dto
@Suppress("unused")
class AreaDTO {
private val id: Int? = null
private val province: String? = null
private val city: String? = null
private val area: String? = null
private val postcode: String? = null
private val del: Boolean? = null
}

View File

@ -698,7 +698,9 @@ class LambdaWrapperTest {
.eq(UserDO::name, "ref")
userMapper!!.selectList(wrapper)
try {
userMapper.insertBatchSomeColumn(ArrayList())
val arr = ArrayList<UserDO>()
arr.add(UserDO())
userMapper.insertBatchSomeColumn(arr)
} catch (ignored: BadSqlGrammarException) {
}
}
@ -821,7 +823,9 @@ class LambdaWrapperTest {
.setTableName { name -> name + "bbbbbbb" }
try {
userMapper!!.selectJoinList(UserDTO::class.java, wrapper)
} catch (_: BadSqlGrammarException) {
} catch (a: Exception) {
if (a.message!!.contains("sql error"))
throw a
}
}
@ -1092,67 +1096,4 @@ class LambdaWrapperTest {
//忽略异常 h2不支持连表删除
}
}
/**
* select 子查询
*/
@Test
fun sub() {
ThreadLocalUtils.set("SELECT ( SELECT st.id FROM `user` st WHERE st.del=false AND (st.id = t.id) limit 1 ) AS id FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE t.del=false AND t1.del=false AND (t.id <= ?)")
val wrapper: KtLambdaWrapper<UserDO> = KtWrappers.query(UserDO::class.java)
.selectSub(
UserDO::class.java, { w ->
w.select(UserDO::id)
.eq(UserDO::id, UserDO::id)
.last("limit 1")
}, UserDO::id
)
.leftJoin(AddressDO::class.java, AddressDO::userId, UserDO::id)
.le(UserDO::id, 100)
wrapper.list()
ThreadLocalUtils.set("SELECT ( SELECT st.id FROM area st WHERE st.del=false AND (st.id = t1.id) limit 1 ) AS id FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE t.del=false AND t1.del=false AND (t.id <= ?)")
val wrapper1: KtLambdaWrapper<UserDO> = KtWrappers.query(UserDO::class.java)
.selectSub(AreaDO::class.java, { w ->
w.select(AreaDO::id)
.eq(AreaDO::id, AddressDO::id)
.last("limit 1")
}, UserDO::id)
.leftJoin(AddressDO::class.java, AddressDO::userId, UserDO::id)
.le(UserDO::id, 100)
wrapper1.list()
ThreadLocalUtils.set("SELECT ( SELECT st.id FROM address st WHERE st.del=false AND (st.id = t1.id) limit 1 ) AS id FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE t.del=false AND t1.del=false AND (t.id <= ?)")
val wrapper2: KtLambdaWrapper<UserDO> = KtWrappers.query(UserDO::class.java)
.selectSub(AddressDO::class.java, { w ->
w.select(AddressDO::id)
.eq(AddressDO::id, AddressDO::id)
.last("limit 1")
}, UserDO::id)
.leftJoin(AddressDO::class.java, AddressDO::userId, UserDO::id)
.le(UserDO::id, 100)
wrapper2.list()
}
/**
* select 子查询
*/
@Test
fun union() {
val wrapper: KtLambdaWrapper<UserDO> = KtWrappers.query(UserDO::class.java)
.selectAll(UserDO::class.java)
.eq(UserDO::id, 1)
val wrapper1: KtLambdaWrapper<UserDO> = KtWrappers.query(UserDO::class.java)
.selectAll(UserDO::class.java)
.eq(UserDO::name, "张三 2")
.and { a -> a.eq(UserDO::name, "张三 2") }
val wrapper2: KtLambdaWrapper<UserDO> = KtWrappers.query(UserDO::class.java)
.selectAll(UserDO::class.java)
.eq(UserDO::pid, 2)
wrapper.union(wrapper1, wrapper2)
val list = wrapper.list()
assert(list.size == 7)
}
}

View File

@ -0,0 +1,57 @@
package com.github.yulichang.test.kt.m
import com.github.yulichang.kt.KtLambdaWrapper
import com.github.yulichang.test.kt.entity.UserDO
import com.github.yulichang.test.kt.mapper.UserMapper
import com.github.yulichang.test.util.Reset
import com.github.yulichang.test.util.ThreadLocalUtils
import com.github.yulichang.toolkit.Ref
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import java.util.*
import kotlin.reflect.KProperty
@SpringBootTest
class CustomWrapperTest {
@Autowired
private val userMapper: UserMapper? = null
@BeforeEach
fun setUp() {
Reset.reset()
}
//自定义wrapper扩展
class CWrapper<T> : KtLambdaWrapper<T>() {
fun eqIfAbsent(column: KProperty<*>, `val`: Any?): CWrapper<T> {
super.eq(Objects.nonNull(`val`), column, `val`)
return this
}
companion object {
fun <T> toCWrapper(): CWrapper<T>? {
return null
}
}
}
@Test
fun testWrapperCustomer() {
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 = ?)")
val wrapper: CWrapper<UserDO> = CWrapper<UserDO>()
.selectAll(UserDO::class.java)
.toChildren<CWrapper<UserDO>> { CWrapper.toCWrapper() }
.eqIfAbsent(UserDO::id, 1)
val dos = userMapper?.selectList(wrapper)
dos?.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")
val wrapper1: CWrapper<UserDO> = CWrapper<UserDO>()
.selectAll(UserDO::class.java)
.toChildren(Ref<CWrapper<UserDO>>())
.eqIfAbsent(UserDO::id, null)
val dos1 = userMapper?.selectList(wrapper1)
dos1?.forEach(System.out::println)
}
}

View File

@ -0,0 +1,41 @@
package com.github.yulichang.test.kt.m
import com.github.yulichang.test.kt.dto.AreaDTO
import com.github.yulichang.test.kt.entity.AreaDO
import com.github.yulichang.test.kt.entity.UserDto
import com.github.yulichang.test.kt.mapper.AreaMapper
import com.github.yulichang.test.util.Reset
import com.github.yulichang.toolkit.KtWrappers
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
@SpringBootTest
class FieldNameTest {
@Autowired
private val areaMapper: AreaMapper? = null
@BeforeEach
fun setUp() {
Reset.reset()
}
@Test
fun testFieldName() {
val list = areaMapper?.selectJoinList(AreaDO::class.java, KtWrappers.query(AreaDO::class.java)
.select(AreaDO::Postcode)
.leftJoin(UserDto::class.java, UserDto::id, AreaDO::id))
list?.forEach(System.out::println)
assert(list?.get(0)?.Postcode != null)
}
@Test
fun testFieldName1() {
val list = areaMapper?.selectJoinList(AreaDTO::class.java, KtWrappers.query(AreaDO::class.java)
.selectAs(AreaDO::Postcode, AreaDTO::postcode)
.leftJoin(UserDto::class.java, UserDto::id, AreaDO::id))
list?.forEach(System.out::println)
assert(list?.get(0)?.postcode != null)
}
}

View File

@ -0,0 +1,53 @@
package com.github.yulichang.test.kt.m
import com.github.yulichang.test.kt.entity.AddressDO
import com.github.yulichang.test.kt.entity.AreaDO
import com.github.yulichang.test.kt.entity.UserDO
import com.github.yulichang.test.util.ThreadLocalUtils
import com.github.yulichang.toolkit.KtWrappers
import org.junit.jupiter.api.BeforeEach
import org.springframework.boot.test.context.SpringBootTest
@SpringBootTest
class SelectSubTest {
@BeforeEach
fun setUp() {
com.github.yulichang.test.util.Reset.reset()
}
/**
* select 子查询
*/
@org.junit.jupiter.api.Test
fun sub() {
ThreadLocalUtils.set("SELECT (SELECT st.id FROM `user` st WHERE st.del = false AND (st.id = t.id AND st.id = ?) LIMIT 1) AS id, (SELECT st.id FROM `user` st WHERE st.del = false AND (st.id = t.id AND st.id = ?) LIMIT 1) AS name FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE t.del = false AND t1.del = false AND (t.id <= ?)")
val wrapper = KtWrappers.query(UserDO::class.java)
.selectSub(UserDO::class.java, { w ->
w.select(UserDO::id)
.eq(UserDO::id, UserDO::id)
.eq(UserDO::id, 2)
.last("limit 1")
}, UserDO::id)
.selectSub(UserDO::class.java, { w ->
w.select(UserDO::id)
.eq(UserDO::id, UserDO::id)
.eq(UserDO::id, 3)
.last("limit 1")
}, UserDO::name)
.leftJoin(AddressDO::class.java, AddressDO::userId, UserDO::id)
.le(UserDO::id, 100)
wrapper.list()
ThreadLocalUtils.set("SELECT (SELECT st.id FROM area st WHERE st.del = false AND (st.id = t1.id) LIMIT 1) AS id FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE t.del = false AND t1.del = false AND (t.id <= ?)")
val wrapper1 = KtWrappers.query(UserDO::class.java)
.selectSub(AreaDO::class.java, { w ->
w.select(AreaDO::id)
.eq(AreaDO::id, AddressDO::id)
.last("limit 1")
}, UserDO::id)
.leftJoin(AddressDO::class.java, AddressDO::userId, UserDO::id)
.le(UserDO::id, 100)
wrapper1.list()
}
}

View File

@ -0,0 +1,83 @@
package com.github.yulichang.test.kt.m
import com.github.yulichang.test.kt.entity.AddressDO
import com.github.yulichang.test.kt.entity.AreaDO
import com.github.yulichang.test.kt.entity.UserDO
import com.github.yulichang.test.util.Reset
import com.github.yulichang.test.util.ThreadLocalUtils
import com.github.yulichang.toolkit.KtWrappers
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest
@Suppress("DEPRECATION")
@SpringBootTest
class UnionTest {
@BeforeEach
fun setUp() {
Reset.reset()
}
@Test
fun union() {
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 = ?) UNION 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.`name` = ? AND (t.`name` = ?)) UNION 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.pid = ?)")
val wrapper = KtWrappers.query(UserDO::class.java)
.selectAll(UserDO::class.java)
.eq(UserDO::id, 1)
val wrapper1 = KtWrappers.query(UserDO::class.java)
.selectAll(UserDO::class.java)
.disableLogicDel()
.eq(UserDO::name, "张三 2")
.and { w -> w.eq(UserDO::name, "张三 2") }
val wrapper2 = KtWrappers.query(UserDO::class.java)
.selectAll(UserDO::class.java)
.eq(UserDO::pid, 2)
wrapper.union(wrapper1, wrapper2)
val list: List<UserDO> = wrapper.list()
println(wrapper.unionSql)
assert(list.size == 7 && list[0].id != null)
}
@Test
fun unionAll() {
ThreadLocalUtils.set("SELECT t.id FROM `user` t WHERE t.del = false AND (t.id = ?) UNION ALL SELECT t.id FROM address t UNION ALL SELECT t.id FROM area t WHERE t.del = false AND (t.id = ?)")
val wrapper = KtWrappers.query(UserDO::class.java)
.select(UserDO::id)
.eq(UserDO::id, 1)
val wrapper1 = KtWrappers.query(AddressDO::class.java)
.select(AddressDO::id)
.disableLogicDel()
val wrapper2 = KtWrappers.query(AreaDO::class.java)
.select(AreaDO::id)
.eq(AreaDO::id, 2)
wrapper.unionAll(wrapper1, wrapper2)
val list: List<UserDO> = wrapper.list()
assert(list.size == 23 && list[0].id != null)
}
@Test
fun unionAll1() {
ThreadLocalUtils.set("SELECT t.id FROM `user` t WHERE t.del = false AND (t.id = ?) UNION ALL SELECT t.id FROM address t WHERE (t.id = ?) UNION ALL SELECT (SELECT st.id FROM area st WHERE st.del = false AND (st.id = ? AND (st.id = ?))) AS id FROM area t WHERE t.del = false AND (t.id = ? AND (t.id = ?))")
val wrapper = KtWrappers.query(UserDO::class.java)
.select(UserDO::id)
.eq(UserDO::id, 1)
.unionAll(AddressDO::class.java) { union ->
union.select(AddressDO::id)
.disableLogicDel()
.eq(UserDO::id, 2)
}
.unionAll(AreaDO::class.java) { union ->
union.selectSub(AreaDO::class.java, { sub ->
sub.select(AreaDO::id)
.eq(AreaDO::id, 3)
.and { and -> and.eq(AreaDO::id, 4) }
}, AreaDO::id)
.eq(AreaDO::id, 5)
.and { and -> and.eq(AreaDO::id, 6) }
}
println(wrapper.unionSql)
val list: List<UserDO> = wrapper.list()
assert(list.size == 2 && list[0].id != null)
}
}