package com.qianwen.smartman.common.utils;
|
|
import cn.hutool.core.util.StrUtil;
|
import com.baomidou.mybatisplus.annotation.DbType;
|
import com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper;
|
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.MergeSegments;
|
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
|
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
|
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.support.SFunction;
|
import java.io.Serializable;
|
import java.text.MessageFormat;
|
import java.time.LocalDate;
|
import java.util.Collection;
|
import java.util.Map;
|
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.function.Predicate;
|
import java.util.function.Supplier;
|
import java.util.stream.Collectors;
|
import javax.validation.constraints.NotNull;
|
import com.qianwen.core.tool.utils.DateUtil;
|
import com.qianwen.core.tool.utils.SpringUtil;
|
import com.qianwen.core.tool.utils.StringUtil;
|
|
|
public class ExtraLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, ExtraLambdaQueryWrapper<T>> implements Query<ExtraLambdaQueryWrapper<T>, T, SFunction<T, ?>> {
|
/**
|
*
|
*/
|
private static final long serialVersionUID = 7355848306213787157L;
|
|
public static final DbType MASTER_DB_TYPE;
|
private SharedString sqlSelect = new SharedString();
|
private static final String ORACLE_NUM = "ROWNUM <= {}";
|
private static final String MYSQL_NUM = "limit {}";
|
private DbType dbType;
|
|
|
static {
|
String type = SpringUtil.getContext().getEnvironment().getProperty("datasource.type");
|
MASTER_DB_TYPE = type == null ? DbType.MYSQL : DbType.getDbType(type);
|
}
|
|
public ExtraLambdaQueryWrapper() {
|
this(MASTER_DB_TYPE);
|
}
|
|
public ExtraLambdaQueryWrapper(final DbType dbType) {
|
this((T)null);
|
this.dbType = dbType;
|
}
|
|
private ExtraLambdaQueryWrapper(T entity) {
|
//this.sqlSelect = new SharedString();
|
|
setEntity(entity);
|
initNeed();
|
}
|
|
private ExtraLambdaQueryWrapper(Class<T> entityClass) {
|
|
super.setEntityClass(entityClass);
|
super.initNeed();
|
}
|
|
ExtraLambdaQueryWrapper(T entity, Class<T> entityClass, SharedString sqlSelect, AtomicInteger paramNameSeq, Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments, SharedString paramAlias, SharedString lastSql, SharedString sqlComment, SharedString sqlFirst) {
|
//this.sqlSelect = new SharedString();
|
super.setEntity(entity);
|
super.setEntityClass(entityClass);
|
this.paramNameSeq = paramNameSeq;
|
this.paramNameValuePairs = paramNameValuePairs;
|
this.expression = mergeSegments;
|
this.sqlSelect = sqlSelect;
|
this.paramAlias = paramAlias;
|
this.lastSql = lastSql;
|
this.sqlComment = sqlComment;
|
this.sqlFirst = sqlFirst;
|
}
|
|
@SafeVarargs
|
public final ExtraLambdaQueryWrapper<T> select(SFunction<T, ?>... columns) {
|
if (ArrayUtils.isNotEmpty(columns)) {
|
this.sqlSelect.setStringValue(columnsToString(false, columns));
|
}
|
return this.typedThis;
|
|
}
|
|
public ExtraLambdaQueryWrapper<T> select(Class<T> entityClass, Predicate<TableFieldInfo> predicate) {
|
if (entityClass == null) {
|
entityClass = getEntityClass();
|
} else {
|
setEntityClass(entityClass);
|
}
|
Assert.notNull(entityClass, "entityClass can not be null", new Object[0]);
|
this.sqlSelect.setStringValue(TableInfoHelper.getTableInfo(entityClass).chooseSelect(predicate));
|
return this.typedThis;
|
}
|
|
public String getSqlSelect() {
|
return this.sqlSelect.getStringValue();
|
}
|
|
protected ExtraLambdaQueryWrapper<T> instance() {
|
return new ExtraLambdaQueryWrapper<>(getEntity(), getEntityClass(), null, this.paramNameSeq, this.paramNameValuePairs, new MergeSegments(), this.paramAlias,
|
SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString());
|
}
|
|
public void clear() {
|
super.clear();
|
this.sqlSelect.toNull();
|
}
|
|
public ExtraLambdaQueryWrapper<T> limit() {
|
return limit(1);
|
}
|
|
public ExtraLambdaQueryWrapper<T> limit(Serializable num) {
|
|
func(wrapper -> {
|
switch (this.dbType) {
|
case ORACLE:
|
wrapper.and(q->{q.last(StrUtil.format("ROWNUM <= {}", new Object[]{num}));});
|
return;
|
default:
|
wrapper.last(StrUtil.format("limit {}", new Object[] { num }));
|
return;
|
}
|
|
});
|
return this;
|
|
/*
|
func(wrapper -> {
|
switch (AnonymousClass1.$SwitchMap$com$baomidou$mybatisplus$annotation$DbType[this.dbType.ordinal()]) {
|
case 1:
|
wrapper.and(q -> {
|
ExtraLambdaQueryWrapper extraLambdaQueryWrapper = (ExtraLambdaQueryWrapper) q.last(StrUtil.format("ROWNUM <= {}", new Object[]{num}));
|
});
|
return;
|
default:
|
wrapper.last(StrUtil.format("limit {}", new Object[]{num}));
|
return;
|
}
|
});
|
return this;
|
*/
|
}
|
|
public ExtraLambdaQueryWrapper<T> findIn(SFunction<T, ?> f, String data) {
|
return findIn(true, f, data, ",");
|
}
|
|
public ExtraLambdaQueryWrapper<T> findIn(SFunction<T, ?> f, String data, String separator) {
|
return findIn(true, f, data, separator);
|
}
|
|
public ExtraLambdaQueryWrapper<T> findIn(boolean condition, SFunction<T, ?> f, String data, @NotNull final String separator) {
|
String paramName = columnsToString(new SFunction[] { f });
|
|
Supplier<String> supplier = () -> {
|
switch (this.dbType) {
|
case ORACLE:
|
case DM:
|
return MessageFormat.format("instr(''{2}''||{0}||''{2}'' , ''{2}''||''{1}''||''{2}'') <> 0", new Object[] { paramName, data, separator });
|
default:
|
return separator.equals(",") ? MessageFormat.format("find_in_set(''{0}'', {1})", new Object[] { data, paramName }) : MessageFormat.format("find_in_set(''{0}'', replace({1},''{2}'','',''))", new Object[] { data, paramName, separator });
|
}
|
|
};
|
apply(condition, supplier.get(), new Object[0]);
|
return this;
|
/*
|
String paramName = columnsToString(new SFunction[]{f});
|
Supplier supplier = () -> {
|
switch (AnonymousClass1.$SwitchMap$com$baomidou$mybatisplus$annotation$DbType[this.dbType.ordinal()]) {
|
case 1:
|
case 2:
|
return MessageFormat.format("instr(''{2}''||{0}||''{2}'' , ''{2}''||''{1}''||''{2}'') <> 0", paramName, data, separator);
|
default:
|
if (separator.equals(",")) {
|
return MessageFormat.format("find_in_set(''{0}'', {1})", data, paramName);
|
}
|
return MessageFormat.format("find_in_set(''{0}'', replace({1},''{2}'','',''))", data, paramName, separator);
|
}
|
};
|
apply(condition, (String) supplier.get(), new Object[0]);
|
return this;
|
*/
|
}
|
|
public ExtraLambdaQueryWrapper<T> orderByAsc(SFunction<T, ?> column, Collection<?> values) {
|
return orderBy(true, column, true, values);
|
}
|
|
public ExtraLambdaQueryWrapper<T> orderBy(boolean condition, SFunction<T, ?> column, boolean isAsc, Collection<?> values) {
|
String param = columnsToString(column );
|
//String param = columnsToString(new SFunction[] { column });
|
String sqlData = String.format(values
|
.stream().map(it -> (it instanceof String) ? "'%s'" : "%s").collect(Collectors.joining(",")), values
|
.toArray());
|
|
ISqlSegment v1 = () -> {
|
switch (this.dbType) {
|
case ORACLE:
|
return String.format(" DECODE(%s, %s ) ", param, sqlData);
|
default:
|
return String.format(" field(%s,%s) ", param, sqlData);
|
}
|
};
|
maybeDo(condition, () -> appendSqlSegments(new ISqlSegment[] { (ISqlSegment)SqlKeyword.ORDER_BY, v1, isAsc ? (ISqlSegment)SqlKeyword.ASC : (ISqlSegment)SqlKeyword.DESC }));
|
return this;
|
|
/*
|
String param = columnsToString(new SFunction[]{column});
|
String sqlData = String.format((String) values.stream().map(it -> {
|
return it instanceof String ? "'%s'" : "%s";
|
}).collect(Collectors.joining(",")), values.toArray());
|
maybeDo(condition, () -> {
|
ISqlSegment[] iSqlSegmentArr = new ISqlSegment[3];
|
iSqlSegmentArr[0] = SqlKeyword.ORDER_BY;
|
iSqlSegmentArr[1] = () -> {
|
switch (AnonymousClass1.$SwitchMap$com$baomidou$mybatisplus$annotation$DbType[this.dbType.ordinal()]) {
|
case 1:
|
return String.format(" DECODE(%s, %s ) ", param, sqlData);
|
default:
|
return String.format(" field(%s,%s) ", param, sqlData);
|
}
|
};
|
iSqlSegmentArr[2] = isAsc ? SqlKeyword.ASC : SqlKeyword.DESC;
|
appendSqlSegments(iSqlSegmentArr);
|
});
|
return this;
|
*/
|
}
|
|
|
|
private String left(SFunction<T, ?> column, int len) {
|
String param = columnsToString(new SFunction[] { column });
|
switch (this.dbType) {
|
case ORACLE:
|
return StringUtil.format("substr(to_char({},'yyyy-MM-dd HH:mm:ss'),0, {})", new Object[] { param, Integer.valueOf(len) });
|
default:
|
return StringUtil.format("left({},{})", new Object[] { param, Integer.valueOf(len) });
|
}
|
|
|
/*
|
String param = columnsToString(new SFunction[]{column});
|
switch (AnonymousClass1.$SwitchMap$com$baomidou$mybatisplus$annotation$DbType[this.dbType.ordinal()]) {
|
case 1:
|
return StringUtil.format("substr(to_char({},'yyyy-MM-dd HH:mm:ss'),0, {})", new Object[]{param, Integer.valueOf(len)});
|
default:
|
return StringUtil.format("left({},{})", new Object[]{param, Integer.valueOf(len)});
|
}
|
*/
|
}
|
|
public ExtraLambdaQueryWrapper<T> dayBetween(LocalDate date, SFunction<T, ?> column1, SFunction<T, ?> column2) {
|
String time = date == null ? null : DateUtil.formatDate(date);
|
String formatSQL = String.format("'%s' between %s and %s", time, left(column1, 10), left(column2, 10));
|
apply(time != null, formatSQL, new Object[0]);
|
return this;
|
}
|
}
|