package com.vci.ubcs.starter.util;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
import com.vci.ubcs.starter.exception.VciBaseException;
|
import org.springblade.core.mp.support.SqlKeyword;
|
import org.springblade.core.tool.utils.BeanUtil;
|
import org.springframework.util.ObjectUtils;
|
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* in 参数截取,返回wrapper/或者where条件字符串
|
*
|
* @author ludc
|
* @date 2023/5/5
|
*/
|
public class MybatisParameterUtil {
|
|
/**
|
* Oracle IN 查询的最大参数限制
|
*/
|
private static final int MAX_IN_CLAUSE_SIZE = 1000;
|
|
/**
|
* 将给定的 ID 列表转换为适合 Oracle 的查询条件
|
*
|
* @param ids ID 列表
|
* @return 适合 Oracle 的查询条件
|
*/
|
public static String convertToOrConditions(String filed,List<String> ids) {
|
if (ids == null || ids.isEmpty()) {
|
return "";
|
}
|
|
StringBuilder queryBuilder = new StringBuilder();
|
int size = ids.size();
|
|
// 分批处理,避免超过 Oracle IN 查询的最大限制
|
for (int i = 0; i < size; i += MAX_IN_CLAUSE_SIZE) {
|
int end = Math.min(i + MAX_IN_CLAUSE_SIZE, size);
|
List<String> subList = ids.subList(i, end);
|
if (queryBuilder.length() > 0) {
|
queryBuilder.append(" OR ");
|
}
|
queryBuilder.append("(")
|
.append(getInClause(filed,subList)).append(")");
|
}
|
|
return queryBuilder.toString();
|
}
|
|
/*
|
* 获取 IN 查询条件字符串
|
* @param ids ID 列表
|
* @return IN 查询条件字符串
|
*/
|
private static String getInClause(String filed,List<String> ids) {
|
StringBuilder inClauseBuilder = new StringBuilder();
|
inClauseBuilder.append(filed + " IN (");
|
|
for (int i = 0; i < ids.size(); i++) {
|
inClauseBuilder.append("'").append(ids.get(i)).append("'");
|
if (i < ids.size() - 1) {
|
inClauseBuilder.append(", ");
|
}
|
}
|
inClauseBuilder.append(")");
|
|
return inClauseBuilder.toString();
|
}
|
|
/**
|
* 获取 IN 查询条件字符串(不包含in)
|
*
|
* @param ids ID 列表
|
* @return IN 查询条件字符串
|
*/
|
public static String getInClause(List<String> ids) {
|
StringBuilder inClauseBuilder = new StringBuilder();
|
for (int i = 0; i < ids.size(); i++) {
|
inClauseBuilder.append("'").append(ids.get(i)).append("'");
|
if (i < ids.size() - 1) {
|
inClauseBuilder.append(", ");
|
}
|
}
|
return inClauseBuilder.toString();
|
}
|
|
/**
|
* in作为查询条件时,防止大于1000出现报错,对条件进行截取,连表查询的wrapper
|
* @param wrapper MPJLambdaWrapper,不进行连表查询时使用
|
* @param column 作为in的条件列
|
* @param coll 查询参数
|
* @param <T> LambdaQueryWrapper的泛型
|
* @param <F> 查询参数类型
|
* @return
|
* @throws VciBaseException
|
*/
|
public static <T, F> MPJLambdaWrapper<T> cutInParameter(MPJLambdaWrapper<T> wrapper, SFunction<T, ?> column, List<F> coll) throws VciBaseException {
|
List<List<F>> newList = splitList(coll, 900);
|
if (ObjectUtils.isEmpty(newList)) {
|
throw new VciBaseException("参数错误");
|
} else if (newList.size() == 1) {
|
wrapper.in(column, newList.get(0));
|
return wrapper;
|
}
|
wrapper.and(i -> {
|
i.in(column, newList.get(0));
|
newList.remove(0);
|
for (List<F> objects : newList) {
|
i.or().in(column, objects);
|
}
|
});
|
return wrapper;
|
}
|
|
/**
|
* in作为查询条件时,防止大于1000出现报错,对条件进行截取,不具备连表查询的wrapper
|
* @param wrapper LambdaQueryWrapper,不进行连表查询时使用
|
* @param column 作为in的条件列
|
* @param coll 查询参数
|
* @param <T> LambdaQueryWrapper的泛型
|
* @param <F> 查询参数类型
|
* @return
|
* @throws VciBaseException
|
*/
|
public static <T, F> LambdaQueryWrapper<T> cutInParameter(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> column, List<F> coll) throws VciBaseException {
|
List<List<F>> newList = splitList(coll, 900);
|
if (ObjectUtils.isEmpty(newList)) {
|
throw new VciBaseException("参数错误");
|
} else if (newList.size() == 1) {
|
wrapper.in(column, newList.get(0));
|
return wrapper;
|
}
|
wrapper.and(i -> {
|
i.in(column, newList.get(0));
|
newList.remove(0);
|
for (List<F> objects : newList) {
|
i.or().in(column, objects);
|
}
|
});
|
return wrapper;
|
}
|
|
/**
|
* notin作为查询条件时,防止大于1000出现报错,对条件进行截取,连表查询的wrapper
|
* @param wrapper MPJLambdaWrapper,不进行连表查询时使用
|
* @param column 作为in的条件列
|
* @param coll 查询参数
|
* @param <T> LambdaQueryWrapper的泛型
|
* @param <F> 查询参数类型
|
* @return
|
* @throws VciBaseException
|
*/
|
public static <T, F> MPJLambdaWrapper<T> cutNotInParameter(MPJLambdaWrapper<T> wrapper, SFunction<T, ?> column, List<F> coll) throws VciBaseException {
|
List<List<F>> newList = splitList(coll, 900);
|
if (ObjectUtils.isEmpty(newList)) {
|
throw new VciBaseException("参数错误");
|
} else if (newList.size() == 1) {
|
wrapper.notIn(column, newList.get(0));
|
return wrapper;
|
}
|
wrapper.and(i -> {
|
i.in(column, newList.get(0));
|
newList.remove(0);
|
for (List<F> objects : newList) {
|
i.or().notIn(column, objects);
|
}
|
});
|
return wrapper;
|
}
|
|
/**
|
* notin作为查询条件时,防止大于1000出现报错,对条件进行截取,不具备连表查询的wrapper
|
* @param wrapper LambdaQueryWrapper,不进行连表查询时使用
|
* @param column 作为in的条件列
|
* @param coll 查询参数
|
* @param <T> LambdaQueryWrapper的泛型
|
* @param <F> 查询参数类型
|
* @return
|
* @throws VciBaseException
|
*/
|
public static <T, F> LambdaQueryWrapper<T> cutNotInParameter(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> column, List<F> coll) throws VciBaseException {
|
List<List<F>> newList = splitList(coll, 900);
|
if (ObjectUtils.isEmpty(newList)) {
|
throw new VciBaseException("参数错误");
|
} else if (newList.size() == 1) {
|
wrapper.notIn(column, newList.get(0));
|
return wrapper;
|
}
|
wrapper.and(i -> {
|
i.in(column, newList.get(0));
|
newList.remove(0);
|
for (List<F> objects : newList) {
|
i.or().notIn(column, objects);
|
}
|
});
|
return wrapper;
|
}
|
|
public static <F> List<List<F>> splitList(List<F> list, int groupSize) {
|
int length = list.size();
|
// 计算可以分成多少组
|
int num = (length + groupSize - 1) / groupSize;
|
List<List<F>> newList = new ArrayList<>(num);
|
for (int i = 0; i < num; i++) {
|
// 开始位置
|
int fromIndex = i * groupSize;
|
// 结束位置
|
int toIndex = Math.min((i + 1) * groupSize, length);
|
newList.add(list.subList(fromIndex, toIndex));
|
}
|
return newList;
|
}
|
|
}
|