添加子查询

This commit is contained in:
yulichang 2023-05-09 17:42:50 +08:00
parent 679c647253
commit 2d481241c4
5 changed files with 159 additions and 2 deletions

View File

@ -0,0 +1,114 @@
package com.github.yulichang.toolkit;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.adapter.AdapterHelper;
import com.github.yulichang.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import java.util.Objects;
import java.util.Optional;
/**
* @author yulichang
* @since 1.4.5
*/
public class WrapperUtils {
public static <T, R> String buildSqlByWrapper(Class<T> clazz, MPJLambdaWrapper<T> wrapper, SFunction<R, ?> alias) {
TableInfo tableInfo = TableHelper.get(clazz);
Asserts.hasTable(tableInfo, clazz);
String first = Optional.ofNullable(wrapper.getSqlFirst()).orElse(StringPool.EMPTY);
boolean hasWhere = false;
String entityWhere = getEntitySql(tableInfo, wrapper);
if (StringUtils.isNotBlank(entityWhere)) {
hasWhere = true;
}
String mainLogic = mainLogic(hasWhere, clazz, wrapper);
if (StringUtils.isNotBlank(mainLogic)) {
hasWhere = true;
}
String subLogic = subLogic(hasWhere, wrapper);
if (StringUtils.isNotBlank(subLogic)) {
hasWhere = true;
}
String sqlSegment = (wrapper.getSqlSegment() != null && StringUtils.isNotBlank(wrapper.getSqlSegment())) ?
((wrapper.isEmptyOfNormal() ? StringPool.EMPTY : (hasWhere ? " AND " : " WHERE ")) + wrapper.getSqlSegment()) : StringPool.EMPTY;
String sqlComment = Optional.ofNullable(wrapper.getSqlComment()).orElse(StringPool.EMPTY);
return String.format("(%s SELECT %s FROM %s %s %s %s %s %s %s) AS %s",
first,
wrapper.getSqlSelect(),
tableInfo.getTableName(),
wrapper.getAlias(),
wrapper.getFrom(),
mainLogic,
subLogic,
sqlSegment,
sqlComment,
LambdaUtils.getName(alias));
}
private static <T> String formatParam(MPJLambdaWrapper<T> wrapper, Object param) {
final String genParamName = Constants.WRAPPER_PARAM + wrapper.getParamNameSeq().incrementAndGet();
final String paramStr = wrapper.getParamAlias() + ".paramNameValuePairs." + genParamName;
wrapper.getParamNameValuePairs().put(genParamName, param);
return SqlScriptUtils.safeParam(paramStr, null);
}
private static <T> String getEntitySql(TableInfo tableInfo, MPJLambdaWrapper<T> wrapper) {
T obj = wrapper.getEntity();
if (Objects.isNull(obj)) {
return StringPool.EMPTY;
}
StringBuilder sb = new StringBuilder(StringPool.EMPTY);
for (TableFieldInfo fieldInfo : tableInfo.getFieldList()) {
if (AdapterHelper.getTableInfoAdapter().mpjHasLogic(tableInfo) && fieldInfo.isLogicDelete()) {
continue;
}
Object val;
try {
val = fieldInfo.getField().get(obj);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
if (Objects.isNull(val)) {
continue;
}
sb.append(" AND ").append(wrapper.getTableList().getPrefixByClass(obj.getClass())).append(Constants.DOT)
.append(fieldInfo.getColumn()).append(Constants.EQUALS).append(formatParam(wrapper, val));
}
//条件不为空 加上 where
if (sb.length() > 0) {
sb.delete(0, 4);
sb.insert(0, " WHERE ");
}
return sb.toString();
}
private static <T> String mainLogic(boolean hasWhere, Class<T> clazz, MPJLambdaWrapper<T> wrapper) {
String info = LogicInfoUtils.getLogicInfo(null, clazz, true, wrapper.getAlias());
if (StringUtils.isNotBlank(info)) {
if (hasWhere) {
return " AND " + info;
}
return " WHERE " + info.substring(4);
}
return StringPool.EMPTY;
}
private static <T> String subLogic(boolean hasWhere, MPJLambdaWrapper<T> wrapper) {
String sql = wrapper.getSubLogicSql();
if (StringUtils.isNotBlank(sql)) {
if (hasWhere) {
return sql;
}
return " WHERE " + sql.substring(4);
}
return StringPool.EMPTY;
}
}

View File

@ -43,6 +43,10 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
* 主表别名
*/
protected String alias = ConfigProperties.tableAlias;
/**
* 副表别名
*/
protected String subTableAlias = ConfigProperties.tableAlias;
/**
* 是否构建是否存在一对多
*/
@ -378,8 +382,8 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
instance.isMain = false;
onWrappers.add(instance);
if (StringUtils.isBlank(tableAlias)) {
tableList.put(oldIndex, clazz, false, ConfigProperties.tableAlias, newIndex);
instance.alias = ConfigProperties.tableAlias;
tableList.put(oldIndex, clazz, false, subTableAlias, newIndex);
instance.alias = subTableAlias;
instance.hasAlias = false;
} else {
tableList.put(oldIndex, clazz, true, tableAlias, newIndex);

View File

@ -51,6 +51,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
/**
* 必要度量
*/
@Getter
protected AtomicInteger paramNameSeq;
protected Map<String, Object> paramNameValuePairs;
/**
@ -103,6 +104,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
/**
* 关联的表
*/
@Getter
protected TableList tableList;
@Override

View File

@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
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.support.ColumnCache;
import com.github.yulichang.wrapper.interfaces.Chain;
import com.github.yulichang.wrapper.interfaces.Query;
@ -18,10 +19,12 @@ import com.github.yulichang.wrapper.resultmap.Label;
import com.github.yulichang.wrapper.segments.Select;
import com.github.yulichang.wrapper.segments.SelectCache;
import com.github.yulichang.wrapper.segments.SelectNormal;
import com.github.yulichang.wrapper.segments.SelectString;
import lombok.Getter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.stream.Collectors;
/**
@ -174,6 +177,24 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
return typedThis;
}
/**
* 子查询
*/
public <E, F> MPJLambdaWrapper<T> selectSub(Class<E> clazz, Consumer<MPJLambdaWrapper<E>> consumer, SFunction<F, ?> alias) {
MPJLambdaWrapper<E> wrapper = new MPJLambdaWrapper<E>(null, clazz, SharedString.emptyString(), paramNameSeq, paramNameValuePairs,
new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
new TableList(), null, null, null, null) {
};
String st = "st";
wrapper.tableList.setAlias(st);
wrapper.alias = st;
wrapper.subTableAlias = st;
consumer.accept(wrapper);
String sql = WrapperUtils.buildSqlByWrapper(clazz, wrapper, alias);
this.selectColumns.add(new SelectString(sql, hasAlias, this.alias));
return typedThis;
}
/**
* 查询条件 SQL 片段
*/

View File

@ -1011,4 +1011,20 @@ class LambdaWrapperTest {
//忽略异常 h2不支持连表删除
}
}
/**
* select 子查询
*/
@Test
void sub() {
ThreadLocalUtils.set("SELECT ( SELECT st.id FROM `user` st WHERE st.del=false AND (st.id <= ?) limit 1 ) AS pid 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)
.le(UserDO::getId,1000)
.last("limit 1"), UserDO::getPid)
.leftJoin(AddressDO.class,AddressDO::getUserId,UserDO::getId)
.le(UserDO::getId,100);
wrapper.list();
System.out.println(1);
}
}