添加union方法

This commit is contained in:
yulichang 2023-05-09 18:33:29 +08:00
parent 2d481241c4
commit 69fa6a8bc2
16 changed files with 209 additions and 14 deletions

View File

@ -15,4 +15,8 @@ public interface MPJBaseJoin<T> {
default String getDeleteLogicSql() {
return StringPool.EMPTY;
}
default String getUnionSql(){
return StringPool.EMPTY;
}
}

View File

@ -1,6 +1,10 @@
package com.github.yulichang.method;
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.sql.SqlScriptUtils;
import com.github.yulichang.interfaces.MPJBaseJoin;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
@ -30,4 +34,10 @@ public class SelectJoinList extends MPJAbstractMethod {
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, MPJResultType.class);
}
@Override
protected String sqlComment() {
return super.sqlComment() + StringPool.NEWLINE + SqlScriptUtils.convertIf("${ew.unionSql}", String.format("%s != null and (%s instanceof %s)",
Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()), true);
}
}

View File

@ -1,6 +1,10 @@
package com.github.yulichang.method;
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.sql.SqlScriptUtils;
import com.github.yulichang.interfaces.MPJBaseJoin;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
@ -31,4 +35,10 @@ public class SelectJoinMap extends MPJAbstractMethod {
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class);
}
@Override
protected String sqlComment() {
return super.sqlComment() + StringPool.NEWLINE + SqlScriptUtils.convertIf("${ew.unionSql}", String.format("%s != null and (%s instanceof %s)",
Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()), true);
}
}

View File

@ -1,6 +1,10 @@
package com.github.yulichang.method;
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.sql.SqlScriptUtils;
import com.github.yulichang.interfaces.MPJBaseJoin;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
@ -32,4 +36,10 @@ public class SelectJoinMaps extends MPJAbstractMethod {
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class);
}
@Override
protected String sqlComment() {
return super.sqlComment() + StringPool.NEWLINE + SqlScriptUtils.convertIf("${ew.unionSql}", String.format("%s != null and (%s instanceof %s)",
Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()), true);
}
}

View File

@ -1,6 +1,10 @@
package com.github.yulichang.method;
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.sql.SqlScriptUtils;
import com.github.yulichang.interfaces.MPJBaseJoin;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
@ -32,4 +36,10 @@ public class SelectJoinMapsPage extends MPJAbstractMethod {
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class);
}
@Override
protected String sqlComment() {
return super.sqlComment() + StringPool.NEWLINE + SqlScriptUtils.convertIf("${ew.unionSql}", String.format("%s != null and (%s instanceof %s)",
Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()), true);
}
}

View File

@ -1,6 +1,10 @@
package com.github.yulichang.method;
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.sql.SqlScriptUtils;
import com.github.yulichang.interfaces.MPJBaseJoin;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
@ -29,4 +33,10 @@ public class SelectJoinOne extends MPJAbstractMethod {
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, MPJResultType.class);
}
@Override
protected String sqlComment() {
return super.sqlComment() + StringPool.NEWLINE + SqlScriptUtils.convertIf("${ew.unionSql}", String.format("%s != null and (%s instanceof %s)",
Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()), true);
}
}

View File

@ -1,6 +1,10 @@
package com.github.yulichang.method;
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.sql.SqlScriptUtils;
import com.github.yulichang.interfaces.MPJBaseJoin;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
@ -30,4 +34,10 @@ public class SelectJoinPage extends MPJAbstractMethod {
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, MPJResultType.class);
}
@Override
protected String sqlComment() {
return super.sqlComment() + StringPool.NEWLINE + SqlScriptUtils.convertIf("${ew.unionSql}", String.format("%s != null and (%s instanceof %s)",
Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()), true);
}
}

View File

@ -45,4 +45,10 @@ public class SelectList extends com.baomidou.mybatisplus.core.injector.methods.S
return SqlScriptUtils.convertChoose(String.format("%s == null or !(%s instanceof %s)", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()),
selectColumns, mpjSqlSelectColumns() + StringPool.SPACE + selectColumns);
}
@Override
protected String sqlComment() {
return super.sqlComment() + StringPool.NEWLINE + SqlScriptUtils.convertIf("${ew.unionSql}", String.format("%s != null and (%s instanceof %s)",
Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()), true);
}
}

View File

@ -45,4 +45,10 @@ public class SelectMaps extends com.baomidou.mybatisplus.core.injector.methods.S
return SqlScriptUtils.convertChoose(String.format("%s == null or !(%s instanceof %s)", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()),
selectColumns, mpjSqlSelectColumns() + StringPool.SPACE + selectColumns);
}
@Override
protected String sqlComment() {
return super.sqlComment() + StringPool.NEWLINE + SqlScriptUtils.convertIf("${ew.unionSql}", String.format("%s != null and (%s instanceof %s)",
Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()), true);
}
}

View File

@ -45,4 +45,10 @@ public class SelectMapsPage extends com.baomidou.mybatisplus.core.injector.metho
return SqlScriptUtils.convertChoose(String.format("%s == null or !(%s instanceof %s)", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()),
selectColumns, mpjSqlSelectColumns() + StringPool.SPACE + selectColumns);
}
@Override
protected String sqlComment() {
return super.sqlComment() + StringPool.NEWLINE + SqlScriptUtils.convertIf("${ew.unionSql}", String.format("%s != null and (%s instanceof %s)",
Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()), true);
}
}

View File

@ -39,4 +39,10 @@ public class SelectObjs extends com.baomidou.mybatisplus.core.injector.methods.S
return SqlScriptUtils.convertChoose(String.format("%s == null or !(%s instanceof %s)", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()),
selectColumns, mpjSqlSelectColumns() + StringPool.SPACE + selectColumns);
}
@Override
protected String sqlComment() {
return super.sqlComment() + StringPool.NEWLINE + SqlScriptUtils.convertIf("${ew.unionSql}", String.format("%s != null and (%s instanceof %s)",
Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()), true);
}
}

View File

@ -44,4 +44,10 @@ public class SelectOne extends com.baomidou.mybatisplus.core.injector.methods.Se
return SqlScriptUtils.convertChoose(String.format("%s == null or !(%s instanceof %s)", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()),
selectColumns, mpjSqlSelectColumns() + StringPool.SPACE + selectColumns);
}
@Override
protected String sqlComment() {
return super.sqlComment() + StringPool.NEWLINE + SqlScriptUtils.convertIf("${ew.unionSql}", String.format("%s != null and (%s instanceof %s)",
Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()), true);
}
}

View File

@ -45,4 +45,10 @@ public class SelectPage extends com.baomidou.mybatisplus.core.injector.methods.S
return SqlScriptUtils.convertChoose(String.format("%s == null or !(%s instanceof %s)", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()),
selectColumns, mpjSqlSelectColumns() + StringPool.SPACE + selectColumns);
}
@Override
protected String sqlComment() {
return super.sqlComment() + StringPool.NEWLINE + SqlScriptUtils.convertIf("${ew.unionSql}", String.format("%s != null and (%s instanceof %s)",
Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()), true);
}
}

View File

@ -19,7 +19,7 @@ import java.util.Optional;
*/
public class WrapperUtils {
public static <T, R> String buildSqlByWrapper(Class<T> clazz, MPJLambdaWrapper<T> wrapper, SFunction<R, ?> alias) {
public static <T, R> String buildSubSqlByWrapper(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);
@ -40,7 +40,7 @@ public class WrapperUtils {
((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",
return String.format(" (%s SELECT %s FROM %s %s %s %s %s %s %s) AS %s ",
first,
wrapper.getSqlSelect(),
tableInfo.getTableName(),
@ -53,6 +53,39 @@ public class WrapperUtils {
LambdaUtils.getName(alias));
}
public static String buildUnionSqlByWrapper(Class<?> clazz, MPJLambdaWrapper<?> wrapper) {
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 ",
first,
wrapper.getSqlSelect(),
tableInfo.getTableName(),
wrapper.getAlias(),
wrapper.getFrom(),
mainLogic,
subLogic,
sqlSegment,
sqlComment);
}
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;
@ -60,8 +93,8 @@ public class WrapperUtils {
return SqlScriptUtils.safeParam(paramStr, null);
}
private static <T> String getEntitySql(TableInfo tableInfo, MPJLambdaWrapper<T> wrapper) {
T obj = wrapper.getEntity();
private static String getEntitySql(TableInfo tableInfo, MPJLambdaWrapper<?> wrapper) {
Object obj = wrapper.getEntity();
if (Objects.isNull(obj)) {
return StringPool.EMPTY;
}
@ -90,7 +123,7 @@ public class WrapperUtils {
return sb.toString();
}
private static <T> String mainLogic(boolean hasWhere, Class<T> clazz, MPJLambdaWrapper<T> wrapper) {
private static String mainLogic(boolean hasWhere, Class<?> clazz, MPJLambdaWrapper<?> wrapper) {
String info = LogicInfoUtils.getLogicInfo(null, clazz, true, wrapper.getAlias());
if (StringUtils.isNotBlank(info)) {
if (hasWhere) {
@ -101,7 +134,7 @@ public class WrapperUtils {
return StringPool.EMPTY;
}
private static <T> String subLogic(boolean hasWhere, MPJLambdaWrapper<T> wrapper) {
private static String subLogic(boolean hasWhere, MPJLambdaWrapper<?> wrapper) {
String sql = wrapper.getSubLogicSql();
if (StringUtils.isNotBlank(sql)) {
if (hasWhere) {

View File

@ -2,10 +2,7 @@ package com.github.yulichang.wrapper;
import com.baomidou.mybatisplus.core.conditions.SharedString;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
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.toolkit.Constant;
import com.github.yulichang.toolkit.LambdaUtils;
@ -56,6 +53,11 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
@Getter
private final List<Label<?>> resultMapMybatisLabel = new ArrayList<>();
/**
* union sql
*/
private SharedString unionSql;
/**
* 推荐使用 class 的构造方法
@ -190,11 +192,49 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
wrapper.alias = st;
wrapper.subTableAlias = st;
consumer.accept(wrapper);
String sql = WrapperUtils.buildSqlByWrapper(clazz, wrapper, alias);
String sql = WrapperUtils.buildSubSqlByWrapper(clazz, wrapper, alias);
this.selectColumns.add(new SelectString(sql, hasAlias, this.alias));
return typedThis;
}
/**
* union
*/
@SuppressWarnings("UnusedReturnValue")
public final MPJLambdaWrapper<T> union(MPJLambdaWrapper<?>... wrappers) {
StringBuilder sb = new StringBuilder();
for (MPJLambdaWrapper<?> wrapper : wrappers) {
Class<?> entityClass = wrapper.getEntityClass();
Assert.notNull(entityClass, "请使用 new MPJLambdaWrapper(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
sb.append(" UNION ")
.append(WrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
}
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
}
unionSql.setStringValue(unionSql.getStringValue() + sb);
return typedThis;
}
/**
* union all
*/
@SafeVarargs
public final <E, F> MPJLambdaWrapper<T> unionAll(MPJLambdaWrapper<T>... wrappers) {
StringBuilder sb = new StringBuilder();
for (MPJLambdaWrapper<?> wrapper : wrappers) {
Class<?> entityClass = wrapper.getEntityClass();
Assert.notNull(entityClass, "请使用 new MPJLambdaWrapper(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
sb.append(" UNION ALL ")
.append(WrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
}
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
}
unionSql.setStringValue(unionSql.getStringValue() + sb);
return typedThis;
}
/**
* 查询条件 SQL 片段
*/
@ -242,6 +282,10 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
return sqlSelect.getStringValue();
}
@Override
public String getUnionSql() {
return Optional.ofNullable(unionSql).map(SharedString::getStringValue).orElse(StringPool.EMPTY);
}
public boolean getSelectDistinct() {
return selectDistinct;

View File

@ -1020,10 +1020,28 @@ class LambdaWrapperTest {
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)
.le(UserDO::getId, 1000)
.last("limit 1"), UserDO::getPid)
.leftJoin(AddressDO.class,AddressDO::getUserId,UserDO::getId)
.le(UserDO::getId,100);
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.le(UserDO::getId, 100);
wrapper.list();
System.out.println(1);
}
/**
* select 子查询
*/
@Test
void union() {
MPJLambdaWrapper<UserDO> wrapper = JoinWrappers.lambda(UserDO.class)
.selectAll(UserDO.class);
MPJLambdaWrapper<UserDO> wrapper1 = JoinWrappers.lambda(UserDO.class)
.selectAll(UserDO.class);
MPJLambdaWrapper<UserDO> wrapper2 = JoinWrappers.lambda(UserDO.class)
.selectAll(UserDO.class);
wrapper.union(wrapper1, wrapper2);
wrapper.list();
System.out.println(1);
}