org.zodiac.mybatisplus.binding.query.dynamic.DynamicSqlProvider Maven / Gradle / Ivy
package org.zodiac.mybatisplus.binding.query.dynamic;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.jdbc.SQL;
import org.zodiac.commons.util.Colls;
import org.zodiac.commons.util.lang.Strings;
import org.zodiac.mybatisplus.binding.QueryBuilder;
import org.zodiac.mybatisplus.binding.parser.ParserCache;
import org.zodiac.mybatisplus.util.MyBatisPlusSpringBootUtil;
import org.zodiac.sdk.toolkit.util.lang.StrUtil;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 动态SQL构建Provider。
*
*/
public class DynamicSqlProvider {
/**.
* select中的占位列前缀标识
*/
public static final String PLACEHOLDER_COLUMN_FLAG = "__";
public DynamicSqlProvider() {
super();
}
/**
* 构建动态SQL。
*
* @param ew 条件
* @return 结果
*/
public String buildSqlForList(QueryWrapper ew) {
return buildDynamicSql(null, ew);
}
/**
* 构建动态SQL。
*
* @param DTO类型
* @param page 分页参数,用于MP分页插件AOP,不可删除
* @param ew 条件
* @return 结果
*/
public String buildSqlForListWithPage(Page> page, QueryWrapper ew) {
return buildDynamicSql(page, ew);
}
/**
* 构建动态SQL。
*
* @param DTO类型
* @param page 分页参数,用于MP分页插件AOP,不可删除
* @param ew 条件
* @return 结果
*/
private String buildDynamicSql(Page> page, QueryWrapper ew) {
DynamicJoinQueryWrapper wrapper = (DynamicJoinQueryWrapper)ew;
return new SQL() {
{
SELECT_DISTINCT(formatSqlSelect(ew.getSqlSelect(), page));
FROM(wrapper.getEntityTable() + " self");
/*提取字段,根据查询条件中涉及的表,动态join。*/
List annoJoinerList = wrapper.getAnnoJoiners();
if (Colls.notEmptyColl(annoJoinerList)) {
Set tempSet = new HashSet<>();
StringBuilder sb = new StringBuilder();
for (AnnoJoiner joiner : annoJoinerList) {
if (StrUtil.isNotBlank(joiner.getJoin()) && StrUtil.isNotBlank(joiner.getOnSegment())) {
if (joiner.getMiddleTable() != null) {
sb.setLength(0);
sb.append(joiner.getMiddleTable()).append(" ").append(joiner.getMiddleTableAlias())
.append(" ON ").append(joiner.getMiddleTableOnSegment());
String deletedCol = ParserCache.getDeletedColumn(joiner.getMiddleTable());
if (deletedCol != null
&& StrUtil.containsIgnoreCase(joiner.getMiddleTable(), " " + deletedCol) == false) {
sb.append(" AND ").append(joiner.getMiddleTableAlias()).append(".")
.append(deletedCol).append(" = ").append(MyBatisPlusSpringBootUtil.getActiveFlagValue());
}
String joinSegment = sb.toString();
if (!tempSet.contains(joinSegment)) {
LEFT_OUTER_JOIN(joinSegment);
tempSet.add(joinSegment);
}
}
sb.setLength(0);
sb.append(joiner.getJoin()).append(" ").append(joiner.getAlias()).append(" ON ")
.append(joiner.getOnSegment());
String deletedCol = ParserCache.getDeletedColumn(joiner.getJoin());
if (deletedCol != null
&& StrUtil.containsIgnoreCase(joiner.getOnSegment(), " " + deletedCol) == false) {
sb.append(" AND ").append(joiner.getAlias()).append(".").append(deletedCol)
.append(" = ").append(MyBatisPlusSpringBootUtil.getActiveFlagValue());
}
String joinSegment = sb.toString();
if (!tempSet.contains(joinSegment)) {
LEFT_OUTER_JOIN(joinSegment);
tempSet.add(joinSegment);
}
}
}
tempSet = null;
}
MergeSegments segments = ew.getExpression();
if (segments != null) {
String normalSql = segments.getNormal().getSqlSegment();
if (StrUtil.isNotBlank(normalSql)) {
WHERE(formatNormalSql(normalSql));
/*动态为主表添加is_deleted=0 。*/
String isDeletedCol = ParserCache.getDeletedColumn(wrapper.getEntityTable());
String isDeletedSection = "self." + isDeletedCol;
if (isDeletedCol != null
&& QueryBuilder.checkHasColumn(segments.getNormal(), isDeletedSection) == false) {
WHERE(isDeletedSection + " = " + MyBatisPlusSpringBootUtil.getActiveFlagValue());
}
if (segments.getOrderBy() != null && !segments.getOrderBy().isEmpty()) {
String orderBySql = segments.getOrderBy().getSqlSegment();
int beginIndex = StrUtil.indexOfNoCase(orderBySql, "ORDER BY ");
if (beginIndex >= 0) {
orderBySql = StrUtil.subStr(orderBySql, beginIndex + "ORDER BY ".length());
ORDER_BY(orderBySql);
}
}
} else if (Colls.notEmptyColl(annoJoinerList)) {
/*存在联表且无where条件。*/
/*动态为主表添加is_deleted=0 。*/
String isDeletedCol = ParserCache.getDeletedColumn(wrapper.getEntityTable());
String isDeletedSection = "self." + isDeletedCol;
if (isDeletedCol != null
&& QueryBuilder.checkHasColumn(segments.getNormal(), isDeletedSection) == false) {
WHERE(isDeletedSection + " = " + MyBatisPlusSpringBootUtil.getActiveFlagValue());
}
}
}
}
}.toString();
}
/**
* 格式化SQL select
列语句。
*
* @param sqlSelect SQL语句
* @param page 分页对象
* @return 结果
*/
private String formatSqlSelect(String sqlSelect, Page> page) {
Set columnSets = null;
StringBuilder sb = new StringBuilder();
if (StrUtil.isBlank(sqlSelect)) {
sb.append("self.*");
} else {
String[] columns = StrUtil.splitToArray(sqlSelect);
for (int i = 0; i < columns.length; i++) {
String column = StrUtil.removeDuplicateBlank(columns[i]).trim();
if (i > 0) {
sb.append(Strings.COMMA);
}
sb.append("self.").append(column);
if (columnSets == null) {
columnSets = new HashSet<>();
}
columnSets.add("self." + column);
}
}
if (page != null && page.orders() != null) {
for (OrderItem orderItem : page.orders()) {
if ((StrUtil.isBlank(sqlSelect) && StrUtil.notStartsWith(orderItem.getColumn(), "self."))
|| (columnSets != null && !columnSets.contains(orderItem.getColumn()))) {
sb.append(Strings.COMMA).append(orderItem.getColumn()).append(" AS ")
.append(Strings.replace(orderItem.getColumn(), ".", "_")).append(PLACEHOLDER_COLUMN_FLAG);
}
}
}
return sb.toString();
}
/**
* 格式化where条件的SQL。
*
* @param normalSql SQL语句
* @return 结果
*/
private String formatNormalSql(String normalSql) {
if (normalSql.startsWith("(") && normalSql.endsWith(")")) {
return StrUtil.subStr(normalSql, 1, normalSql.length() - 1);
}
return normalSql;
}
}