
icu.mhb.mybatisplus.plugln.core.JoinLambdaWrapper Maven / Gradle / Ivy
package icu.mhb.mybatisplus.plugln.core;
import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.baomidou.mybatisplus.core.conditions.ISqlSegment;
import com.baomidou.mybatisplus.core.conditions.SharedString;
import com.baomidou.mybatisplus.core.conditions.query.Query;
import com.baomidou.mybatisplus.core.conditions.segments.*;
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import icu.mhb.mybatisplus.plugln.base.mapper.JoinBaseMapper;
import icu.mhb.mybatisplus.plugln.constant.JoinConstant;
import icu.mhb.mybatisplus.plugln.core.func.JoinMethodFunc;
import icu.mhb.mybatisplus.plugln.core.func.JoinQueryFunc;
import icu.mhb.mybatisplus.plugln.core.support.SupportJoinLambdaWrapper;
import icu.mhb.mybatisplus.plugln.entity.*;
import icu.mhb.mybatisplus.plugln.keyword.DefaultFuncKeyWord;
import icu.mhb.mybatisplus.plugln.keyword.IFuncKeyWord;
import icu.mhb.mybatisplus.plugln.tookit.IdUtil;
import lombok.Getter;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionUtils;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static com.baomidou.mybatisplus.core.enums.SqlKeyword.*;
import static com.baomidou.mybatisplus.core.toolkit.StringPool.COMMA;
import static com.baomidou.mybatisplus.core.toolkit.StringPool.NEWLINE;
/**
* 构建条件对象
*
* @author mahuibo
* @Title: JoinLambdaWrapper
* @time 8/21/21 5:17 PM
*/
@SuppressWarnings("all")
public class JoinLambdaWrapper extends SupportJoinLambdaWrapper>
implements Query, T, SFunction>, JoinMethodFunc, JoinQueryFunc> {
/**
* 关键字获取
*/
private IFuncKeyWord funcKeyWord;
/**
* 关联表的查询子段
*/
private List joinSqlSelect = new ArrayList<>();
/**
* 关联表SQL
*/
private List joinSql = new ArrayList<>();
/**
* 关联表条件SQL
*/
private List joinConditionSql = new ArrayList<>();
/**
* 一对一 构建列表
*/
@Getter
private List oneToOneSelectBuildList = null;
/**
* 多对多 构建列表
*/
@Getter
private List manyToManySelectBuildList = null;
/**
* 判断SQL是否缓存过
*/
private boolean sqlCacheFlag;
/**
* SQL缓存
*/
private SharedString sqlCache = new SharedString();
/**
* 查询字段是否缓存过
*/
private boolean sqlSelectFlag;
/**
* 查询字段缓存
*/
private SharedString sqlSelectCahce = new SharedString();
/**
* 是否查询主表全部字段 该条件是在没有指定查询字段的时候生效
*/
private boolean notDefaultSelectAll = false;
/**
* 是否添加去重关键字
*/
private boolean hasDistinct = false;
/**
* 不建议直接 new 该实例,使用 Wrappers.lambdaQuery(entity)
*/
public JoinLambdaWrapper(T entity, String alias) {
super.setEntity(entity);
this.initNeed();
setAlias(alias);
}
public JoinLambdaWrapper(T entity) {
super.setEntity(entity);
this.initNeed();
}
/**
* 不建议直接 new 该实例,使用 Wrappers.lambdaQuery(entity)
*/
public JoinLambdaWrapper(Class entityClass, String alias) {
super.setEntityClass(entityClass);
this.initNeed();
setAlias(alias);
}
public JoinLambdaWrapper(Class entityClass) {
super.setEntityClass(entityClass);
this.initNeed();
}
/**
* 不建议直接 new 该实例,使用 Wrappers.lambdaQuery(...)
*/
JoinLambdaWrapper(T entity, Class entityClass, SharedString sqlSelect, AtomicInteger paramNameSeq,
Map paramNameValuePairs, MergeSegments mergeSegments,
Map, String> aliasMap,
SharedString lastSql, SharedString sqlComment, SharedString sqlFirst) {
super.setEntity(entity);
super.setEntityClass(entityClass);
this.paramNameSeq = paramNameSeq;
this.aliasMap = aliasMap;
this.paramNameValuePairs = paramNameValuePairs;
this.expression = mergeSegments;
this.sqlSelect = sqlSelect;
this.lastSql = lastSql;
this.sqlComment = sqlComment;
this.sqlFirst = sqlFirst;
}
/**
* SELECT 部分 SQL 设置
*
* @param columns 查询字段
*/
@SafeVarargs
@Override
public final JoinLambdaWrapper select(SFunction... columns) {
if (ArrayUtils.isNotEmpty(columns)) {
this.sqlSelect.setStringValue(columnsToString(false, true, columns));
}
return typedThis;
}
/**
* 添加去重函数
*/
public JoinLambdaWrapper distinct() {
this.hasDistinct = true;
return typedThis;
}
/**
* 过滤查询的字段信息(主键除外!)
* 例1: 只要 java 字段名以 "test" 开头的 -> select(i -> i.getProperty().startsWith("test"))
* 例2: 只要 java 字段属性是 CharSequence 类型的 -> select(TableFieldInfoExt::isCharSequence)
* 例3: 只要 java 字段没有填充策略的 -> select(i -> i.getFieldFill() == FieldFill.DEFAULT)
* 例4: 要全部字段 -> select(i -> true)
* 例5: 只要主键字段 -> select(i -> false)
*
* @param predicate 过滤方式
* @return this
*/
@Override
public JoinLambdaWrapper select(Class entityClass, Predicate predicate) {
super.setEntityClass(entityClass);
this.sqlSelect.setStringValue(new TableInfoExt(TableInfoHelper.getTableInfo(getEntityOrMasterClass())).chooseSelect(predicate, getAlias()));
return typedThis;
}
@Override
public String getSqlSelect() {
if (sqlSelectFlag) {
return sqlSelectCahce.getStringValue();
}
if (StringUtils.isBlank(sqlSelect.getStringValue()) && !this.notDefaultSelectAll) {
selectAll();
}
StringBuilder stringValue = new StringBuilder(sqlSelect.getStringValue());
String joinSelectSql = joinSqlSelect.stream()
.map(SharedString::getStringValue)
.filter(StringUtils::isNotBlank)
.collect(Collectors.joining(COMMA));
// 只有在拥有主表查询字段并且有子表查询的时候才需要加上','分隔符
if (stringValue.length() > 0 && StringUtils.isNotBlank(joinSelectSql)) {
stringValue.append(COMMA);
}
stringValue.append(joinSelectSql);
String selectSql = stringValue.toString();
sqlSelectFlag = true;
if (hasDistinct) {
selectSql = getFuncKeyWord().distinct() + " " + selectSql;
}
sqlSelectCahce.setStringValue(selectSql);
return selectSql;
}
/**
* 在没有指定查询主表字段的情况下,不进行查询字段
*/
public JoinLambdaWrapper notDefaultSelectAll() {
this.notDefaultSelectAll = true;
return typedThis;
}
/**
* 转换查询Wrapper 会把 查询条件,group,order by,having转换来
* 注意该方法无法给 多个入参添加别名,例如 orderByDesc("id","id2")
* 这种别名就会添加错误
*
* @param queryWrapper
* @return
*/
public JoinLambdaWrapper changeQueryWrapper(AbstractWrapper queryWrapper) {
MergeSegments mergeSegments = queryWrapper.getExpression();
String id = IdUtil.getSimpleUUID();
for (int i = 0; i < mergeSegments.getNormal().size(); i++) {
ISqlSegment iSqlSegment = mergeSegments.getNormal().get(i);
if (iSqlSegment instanceof SqlKeyword) {
continue;
}
String sqlSegment = iSqlSegment.getSqlSegment();
if (!sqlSegment.contains("#{")) {
mergeSegments.getNormal().remove(iSqlSegment);
mergeSegments.getNormal().add(i, () -> getAliasAndField(sqlSegment));
} else {
// 替换外联表中的参数名字为唯一的
mergeSegments.getNormal().remove(iSqlSegment);
mergeSegments.getNormal().add(i, () -> sqlSegment.replaceAll(JoinConstant.MP_PARAMS_NAME, JoinConstant.MP_PARAMS_NAME + StringPool.DOT + id));
}
}
expressionAdd(mergeSegments.getNormal(), null);
GroupBySegmentList groupBy = mergeSegments.getGroupBy();
for (int i = 0; i < groupBy.size(); i++) {
ISqlSegment iSqlSegment = groupBy.get(i);
if (iSqlSegment instanceof SqlKeyword) {
continue;
}
String sqlSegment = iSqlSegment.getSqlSegment();
if (!sqlSegment.contains("#{")) {
mergeSegments.getGroupBy().remove(iSqlSegment);
mergeSegments.getGroupBy().add(i, () -> getAliasAndField(sqlSegment));
}
}
expressionAdd(mergeSegments.getGroupBy(), GROUP_BY);
HavingSegmentList having = mergeSegments.getHaving();
for (int i = 0; i < having.size(); i++) {
ISqlSegment iSqlSegment = having.get(i);
if (iSqlSegment instanceof SqlKeyword) {
continue;
}
String sqlSegment = iSqlSegment.getSqlSegment();
if (sqlSegment.contains("#{")) {
// 替换外联表中的参数名字为唯一的
mergeSegments.getHaving().remove(iSqlSegment);
mergeSegments.getHaving().add(i, () -> sqlSegment.replaceAll(JoinConstant.MP_PARAMS_NAME, JoinConstant.MP_PARAMS_NAME + StringPool.DOT + id));
}
}
expressionAdd(mergeSegments.getHaving(), HAVING);
OrderBySegmentList orderBy = mergeSegments.getOrderBy();
for (int i = 0; i < orderBy.size(); i++) {
ISqlSegment iSqlSegment = orderBy.get(i);
if (iSqlSegment instanceof SqlKeyword) {
continue;
}
String sqlSegment = iSqlSegment.getSqlSegment();
if (!sqlSegment.contains("#{")) {
mergeSegments.getOrderBy().remove(iSqlSegment);
mergeSegments.getOrderBy().add(i, () -> getAliasAndField(sqlSegment));
}
}
expressionAdd(mergeSegments.getOrderBy(), ORDER_BY);
getParamNameValuePairs().put(id, queryWrapper.getParamNameValuePairs());
return typedThis;
}
private void expressionAdd(AbstractISegmentList list, SqlKeyword sqlKeyword) {
if (!list.isEmpty()) {
if (null != sqlKeyword) {
list.add(0, sqlKeyword);
}
ISqlSegment[] iSqlSegmentArrays = new ISqlSegment[list.size()];
for (int i = 0; i < list.size(); i++) {
ISqlSegment sqlSegment = list.get(i);
iSqlSegmentArrays[i] = sqlSegment;
}
getExpression().add(iSqlSegmentArrays);
}
}
/**
* 用于生成嵌套 sql
* 故 sqlSelect 不向下传递
*/
@Override
protected JoinLambdaWrapper instance() {
return new JoinLambdaWrapper<>(getEntity(), getEntityClass(), null, paramNameSeq, paramNameValuePairs,
new MergeSegments(), this.getAliasMap(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString());
}
@Override
public void clear() {
super.clear();
sqlSelect.toEmpty();
sqlSelectCahce.toEmpty();
sqlSelectFlag = false;
sqlCache.toEmpty();
sqlCacheFlag = false;
joinSql.clear();
joinSqlSelect.clear();
joinConditionSql.clear();
aliasMap.clear();
orderByBuildList.clear();
fieldMappingList.clear();
}
/**
* 条件SQL
*
* @return
*/
@Override
public String getSqlSegment() {
// 如果存在缓存就返回
if (sqlCacheFlag) {
return sqlCache.getStringValue();
}
if (this.orderByBuildList.size() > 0) {
// 顺序重排
this.orderByBuildList = this.orderByBuildList.stream()
.sorted(Comparator.comparing(OrderByBuild::getIndex))
.collect(Collectors.toList());
this.orderByBuildList.forEach(i -> {
// 如果是手写的SQL则不需要 asc desc 排序 开发者自己写
if (i.isSql()) {
maybeDo(i.isCondition(), () -> appendSqlSegments(ORDER_BY, i.getColumn()));
} else {
maybeDo(i.isCondition(), () -> appendSqlSegments(ORDER_BY, i.getColumn(),
i.isAsc() ? ASC : DESC));
}
});
}
String sql = expression.getSqlSegment();
StringBuilder sqlBuilder = new StringBuilder();
// 判断实体是否不为空
boolean nonEmptyOfEntity = this.nonEmptyOfEntity();
// 判断主表执行SQL是否为空
boolean sqlIsBlank = StringUtils.isBlank(sql) || expression.getNormal().size() == 0;
// 判断连表SQL是否为空
boolean conditionSqlIsNotEmpty = CollectionUtils.isNotEmpty(joinConditionSql);
TableInfo tableInfo = TableInfoHelper.getTableInfo(getEntityClass());
// 如果SQL不为空或者实体不为空就是会创建where字句 否则需要自己手动创建,并且不开启逻辑删除
if ((sqlIsBlank && !nonEmptyOfEntity) && conditionSqlIsNotEmpty && !tableInfo.isWithLogicDelete()) {
sqlBuilder.append(Constants.WHERE);
} else if ((sqlIsBlank && !nonEmptyOfEntity) && conditionSqlIsNotEmpty && tableInfo.isWithLogicDelete()) {
sqlBuilder.append(Constants.AND);
} else if (conditionSqlIsNotEmpty && nonEmptyOfEntity && sqlIsBlank) {
sqlBuilder.append(Constants.AND);
}
if (conditionSqlIsNotEmpty) {
for (int i = 0; i < joinConditionSql.size(); i++) {
String conditionSql = joinConditionSql.get(i);
sqlBuilder.append(StringPool.SPACE);
if (i > 0) {
sqlBuilder.append(Constants.AND);
}
sqlBuilder.append(conditionSql);
}
}
if (!sqlIsBlank) {
// 如果条件不为空代表前面已经有后面就跟and
if (conditionSqlIsNotEmpty) {
sqlBuilder.append(StringPool.SPACE).append(Constants.AND)
.append(StringPool.SPACE);
}
sqlBuilder.append(sql);
}
// 如果查询条件为空,并且 排序 、分组、 having 不为空就添加
if (sqlIsBlank && (expression.getOrderBy().size() > 0 || expression.getGroupBy().size() > 0 || expression.getHaving().size() > 0)) {
sqlBuilder.append(NEWLINE)
.append(sql);
}
sqlBuilder.append(NEWLINE).append(lastSql.getStringValue());
String sqlBuilderStr = sqlBuilder.toString();
sqlCache.setStringValue(sqlBuilderStr);
sqlCacheFlag = true;
return sqlBuilderStr;
}
@Override
public JoinWrapper join(Class clz, String alias, boolean logicDelete) {
return new JoinWrapper<>(clz, this, alias, logicDelete);
}
/**
* 存入外联表 join 查询条件
*
* @param sql 条件SQL
* @param key 此次外联表唯一标识码
* @param joinParamNameValuePairs 条件SQL对应的值
*/
void setJoinConditionSql(String sql, String key, Map joinParamNameValuePairs) {
if (StringUtils.isNotBlank(sql)) {
// 向当前参数map存入外联表的值
paramNameValuePairs.put(key, joinParamNameValuePairs);
// 外联表如果执行了条件会存在where标签,需要祛除
sql = sql.replace(Constants.WHERE, StringPool.SPACE);
// 替换外联表中的参数名字为唯一的
sql = sql.replaceAll(JoinConstant.MP_PARAMS_NAME, JoinConstant.MP_PARAMS_NAME + StringPool.DOT + key);
joinConditionSql.add(sql);
}
}
/**
* 存入外联表join SQL
*
* @param sql SQL
*/
void setJoinSql(List sql) {
if (CollectionUtils.isNotEmpty(sql)) {
joinSql.addAll(sql);
}
}
/**
* 存入排序
*
* @param orderBy 排序列表
*/
void setOrderBy(OrderBySegmentList orderBy) {
if (!orderBy.isEmpty()) {
for (ISqlSegment iSqlSegment : orderBy) {
this.maybeDo(true, () -> appendSqlSegments(ORDER_BY, iSqlSegment));
}
}
}
/**
* 存入分组数据
*
* @param groupBy 分组列表
*/
void setGroupBy(GroupBySegmentList groupBy) {
if (!groupBy.isEmpty()) {
for (ISqlSegment iSqlSegment : groupBy) {
this.maybeDo(true, () -> appendSqlSegments(GROUP_BY, iSqlSegment));
}
}
}
/**
* 存入having数据
*
* @param havingBuildList having 构建列表
*/
void setHaving(List havingBuildList) {
if (havingBuildList != null && !havingBuildList.isEmpty()) {
for (HavingBuild havingBuild : havingBuildList) {
having(havingBuild.isCondition(), havingBuild.getSql(), havingBuild.getParams());
}
}
}
/**
* 存入外联表查询子段
*
* @param select 查询字段
*/
void setJoinSelect(SharedString... select) {
joinSqlSelect.addAll(Arrays.asList(select));
}
void setAliasMap(Map, String> aliasCacheMap) {
if (CollectionUtils.isNotEmpty(aliasCacheMap)) {
aliasCacheMap.forEach((k, v) -> aliasMap.put(k, v));
}
}
/**
* 存入最后一位的SQL 只能存在一个
*
* @param last 外联表传入last数据
*/
void setLastSql(SharedString last) {
if (StringUtils.isNotBlank(last.getStringValue())) {
lastSql = last;
}
}
protected void setFieldMappingList(List fieldMappingList) {
if (CollectionUtils.isNotEmpty(fieldMappingList)) {
this.fieldMappingList.addAll(fieldMappingList);
}
}
void setOderByBuildList(List orderByBuildList) {
if (CollectionUtils.isNotEmpty(orderByBuildList)) {
this.orderByBuildList.addAll(orderByBuildList);
}
}
void setOneToOneSelect(OneToOneSelectBuild oneToOneSelect) {
if (null == oneToOneSelect) {
return;
}
if (null == oneToOneSelectBuildList) {
oneToOneSelectBuildList = new ArrayList<>();
}
oneToOneSelectBuildList.add(oneToOneSelect);
}
void setManyToManySelect(ManyToManySelectBuild manyToManySelect) {
if (null == manyToManySelect) {
return;
}
if (null == manyToManySelectBuildList) {
manyToManySelectBuildList = new ArrayList<>();
}
manyToManySelectBuildList.add(manyToManySelect);
}
/**
* 获取join SQL语句
*
* @return 构建好的SQL
*/
public String getJoinSql() {
StringBuilder sql = new StringBuilder();
if (CollectionUtils.isNotEmpty(joinSql)) {
for (SharedString sharedString : joinSql) {
sql.append(sharedString.getStringValue()).append(NEWLINE);
}
}
return sql.toString();
}
@Override
public String getCustomSqlSegment() {
return super.getCustomSqlSegment();
}
@Override
protected void initNeed() {
super.initNeed();
final Class entityClass = getEntityClass();
}
public List getFieldMappingList() {
return this.fieldMappingList;
}
public IFuncKeyWord getFuncKeyWord() {
if (this.funcKeyWord == null) {
this.funcKeyWord = new DefaultFuncKeyWord();
}
return funcKeyWord;
}
public JoinLambdaWrapper setFuncKeyWord(IFuncKeyWord funcKeyWord) {
this.funcKeyWord = funcKeyWord;
return typedThis;
}
@Override
public R executeQuery(SFunction, R> function) {
SqlSession sqlSession = SqlHelper.sqlSession(getEntityOrMasterClass());
try {
return function.apply((JoinBaseMapper) SqlHelper.getMapper(getEntityOrMasterClass(), sqlSession));
} finally {
SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(getEntityOrMasterClass()));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy