mirror of
https://gitee.com/best_handsome/mybatis-plus-join
synced 2025-07-11 00:02:22 +08:00
添加子查询
This commit is contained in:
parent
679c647253
commit
2d481241c4
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -43,6 +43,10 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
|
|||||||
* 主表别名
|
* 主表别名
|
||||||
*/
|
*/
|
||||||
protected String alias = ConfigProperties.tableAlias;
|
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;
|
instance.isMain = false;
|
||||||
onWrappers.add(instance);
|
onWrappers.add(instance);
|
||||||
if (StringUtils.isBlank(tableAlias)) {
|
if (StringUtils.isBlank(tableAlias)) {
|
||||||
tableList.put(oldIndex, clazz, false, ConfigProperties.tableAlias, newIndex);
|
tableList.put(oldIndex, clazz, false, subTableAlias, newIndex);
|
||||||
instance.alias = ConfigProperties.tableAlias;
|
instance.alias = subTableAlias;
|
||||||
instance.hasAlias = false;
|
instance.hasAlias = false;
|
||||||
} else {
|
} else {
|
||||||
tableList.put(oldIndex, clazz, true, tableAlias, newIndex);
|
tableList.put(oldIndex, clazz, true, tableAlias, newIndex);
|
||||||
|
@ -51,6 +51,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
|||||||
/**
|
/**
|
||||||
* 必要度量
|
* 必要度量
|
||||||
*/
|
*/
|
||||||
|
@Getter
|
||||||
protected AtomicInteger paramNameSeq;
|
protected AtomicInteger paramNameSeq;
|
||||||
protected Map<String, Object> paramNameValuePairs;
|
protected Map<String, Object> paramNameValuePairs;
|
||||||
/**
|
/**
|
||||||
@ -103,6 +104,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
|||||||
/**
|
/**
|
||||||
* 关联的表
|
* 关联的表
|
||||||
*/
|
*/
|
||||||
|
@Getter
|
||||||
protected TableList tableList;
|
protected TableList tableList;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
|||||||
import com.github.yulichang.toolkit.Constant;
|
import com.github.yulichang.toolkit.Constant;
|
||||||
import com.github.yulichang.toolkit.LambdaUtils;
|
import com.github.yulichang.toolkit.LambdaUtils;
|
||||||
import com.github.yulichang.toolkit.TableList;
|
import com.github.yulichang.toolkit.TableList;
|
||||||
|
import com.github.yulichang.toolkit.WrapperUtils;
|
||||||
import com.github.yulichang.toolkit.support.ColumnCache;
|
import com.github.yulichang.toolkit.support.ColumnCache;
|
||||||
import com.github.yulichang.wrapper.interfaces.Chain;
|
import com.github.yulichang.wrapper.interfaces.Chain;
|
||||||
import com.github.yulichang.wrapper.interfaces.Query;
|
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.Select;
|
||||||
import com.github.yulichang.wrapper.segments.SelectCache;
|
import com.github.yulichang.wrapper.segments.SelectCache;
|
||||||
import com.github.yulichang.wrapper.segments.SelectNormal;
|
import com.github.yulichang.wrapper.segments.SelectNormal;
|
||||||
|
import com.github.yulichang.wrapper.segments.SelectString;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,6 +177,24 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
|||||||
return typedThis;
|
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 片段
|
* 查询条件 SQL 片段
|
||||||
*/
|
*/
|
||||||
|
@ -1011,4 +1011,20 @@ class LambdaWrapperTest {
|
|||||||
//忽略异常 h2不支持连表删除
|
//忽略异常 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user