package com.github.yulichang.query; import com.baomidou.mybatisplus.core.conditions.SharedString; import com.baomidou.mybatisplus.core.conditions.query.Query; import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments; 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.ArrayUtils; import com.baomidou.mybatisplus.core.toolkit.Assert; 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.query.interfaces.MyJoin; import com.github.yulichang.toolkit.Constant; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Predicate; import java.util.stream.Collectors; /** * copy {@link com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper} *

* sqlSelect 由覆盖改为追加 */ @SuppressWarnings("all") public class MyLambdaQueryWrapper extends MyAbstractLambdaWrapper> implements Query, T, SFunction>, MyJoin> { /** * 查询字段 */ private SharedString sqlSelect = new SharedString(); /** * 连表字段 */ private SharedString from = SharedString.emptyString(); /** * 主表别名 */ private final SharedString alias = new SharedString(Constant.TABLE_ALIAS); /** * 不建议直接 new 该实例,使用 Wrappers.lambdaQuery(entity) */ public MyLambdaQueryWrapper() { this((T) null); } /** * 不建议直接 new 该实例,使用 Wrappers.lambdaQuery(entity) */ public MyLambdaQueryWrapper(T entity) { super.setEntity(entity); super.initNeed(); } /** * 不建议直接 new 该实例,使用 Wrappers.lambdaQuery(entity) */ public MyLambdaQueryWrapper(Class entityClass) { super.setEntityClass(entityClass); super.initNeed(); } /** * 不建议直接 new 该实例,使用 Wrappers.lambdaQuery(...) */ MyLambdaQueryWrapper(T entity, Class entityClass, SharedString from, SharedString sqlSelect, AtomicInteger paramNameSeq, Map paramNameValuePairs, MergeSegments mergeSegments, SharedString lastSql, SharedString sqlComment, SharedString sqlFirst) { super.setEntity(entity); super.setEntityClass(entityClass); this.paramNameSeq = paramNameSeq; this.paramNameValuePairs = paramNameValuePairs; this.expression = mergeSegments; this.sqlSelect = sqlSelect; this.from = from; this.lastSql = lastSql; this.sqlComment = sqlComment; this.sqlFirst = sqlFirst; } /** * SELECT 部分 SQL 设置 * * @param columns 查询字段 */ @SafeVarargs @Override public final MyLambdaQueryWrapper select(SFunction... columns) { return select(true, columns); } @SafeVarargs public final MyLambdaQueryWrapper select(boolean condition, SFunction... columns) { if (condition && ArrayUtils.isNotEmpty(columns)) { String s = columnsToString(false, columns); if (StringUtils.isBlank(sqlSelect.getStringValue())) { this.sqlSelect.setStringValue(s); } else { this.sqlSelect.setStringValue(this.getSqlSelect() + StringPool.COMMA + s); } } return typedThis; } @SafeVarargs public final MyLambdaQueryWrapper select(String... columns) { return select(true, columns); } @SafeVarargs public final MyLambdaQueryWrapper select(boolean condition, String... columns) { if (condition && ArrayUtils.isNotEmpty(columns)) { String s = String.join(StringPool.COMMA, columns); if (StringUtils.isBlank(sqlSelect.getStringValue())) { this.sqlSelect.setStringValue(s); } else { this.sqlSelect.setStringValue(this.getSqlSelect() + StringPool.COMMA + s); } } return typedThis; } /** * 过滤查询的字段信息(主键除外!) *

例1: 只要 java 字段名以 "test" 开头的 -> select(i -> i.getProperty().startsWith("test"))

*

例2: 只要 java 字段属性是 CharSequence 类型的 -> select(TableFieldInfo::isCharSequence)

*

例3: 只要 java 字段没有填充策略的 -> select(i -> i.getFieldFill() == FieldFill.DEFAULT)

*

例4: 要全部字段 -> select(i -> true)

*

例5: 只要主键字段 -> select(i -> false)

* * @param predicate 过滤方式 * @return this */ @Override public MyLambdaQueryWrapper select(Class entityClass, Predicate predicate) { return select(true, entityClass, predicate); } public MyLambdaQueryWrapper select(boolean condition, Class entityClass, Predicate predicate) { if (condition) { if (entityClass == null) { entityClass = getEntityClass(); } else { setEntityClass(entityClass); } Assert.notNull(entityClass, "entityClass can not be null"); String s = TableInfoHelper.getTableInfo(entityClass).chooseSelect(predicate); List list = Arrays.stream(s.split(StringPool.COMMA)).map(i -> Constant.TABLE_ALIAS + StringPool.DOT + i).collect(Collectors.toList()); String join = String.join(StringPool.COMMA, list); if (StringUtils.isBlank(sqlSelect.getStringValue())) { this.sqlSelect.setStringValue(join); } else { this.sqlSelect.setStringValue(this.getSqlSelect() + StringPool.COMMA + join); } } return typedThis; } public final MyLambdaQueryWrapper selectAll(Class clazz) { return selectAll(true, clazz); } public final MyLambdaQueryWrapper selectAll(boolean condition, Class clazz) { if (condition) { TableInfo info = TableInfoHelper.getTableInfo(clazz); List list = new ArrayList<>(); if (info.havePK()) { list.add(Constant.TABLE_ALIAS + StringPool.DOT + info.getKeyColumn()); } list.addAll(info.getFieldList().stream().map(i -> Constant.TABLE_ALIAS + StringPool.DOT + i.getColumn()).collect(Collectors.toList())); String join = String.join(StringPool.COMMA, list); if (StringUtils.isBlank(sqlSelect.getStringValue())) { this.sqlSelect.setStringValue(join); } else { this.sqlSelect.setStringValue(this.getSqlSelect() + StringPool.COMMA + join); } } return typedThis; } /** * 返回一个支持 lambda 函数写法的 wrapper */ public MyQueryWrapper stringQuery() { return new MyQueryWrapper<>(getEntity(), getEntityClass(), paramNameSeq, paramNameValuePairs, expression, sqlSelect, from, lastSql, sqlComment, sqlFirst); } @Override public String getSqlSelect() { return sqlSelect.getStringValue(); } public String getFrom() { return from.getStringValue(); } public String getAlias() { return alias.getStringValue(); } /** * 用于生成嵌套 sql *

故 sqlSelect from不向下传递

*/ @Override protected MyLambdaQueryWrapper instance() { return new MyLambdaQueryWrapper<>(getEntity(), getEntityClass(), null, null, paramNameSeq, paramNameValuePairs, new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString()); } @Override public void clear() { super.clear(); sqlSelect.toNull(); } @Override public MyLambdaQueryWrapper join(String keyWord, boolean condition, String joinSql) { if (condition) { from.setStringValue(from.getStringValue() + keyWord + joinSql); } return typedThis; } }