yui.comn.mybatisx.extension.methods.AbstractSoftMethod Maven / Gradle / Ivy
package yui.comn.mybatisx.extension.methods;
import static java.util.stream.Collectors.joining;
import java.lang.reflect.Field;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.apache.ibatis.executor.keygen.NoKeyGenerator;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.SqlSource;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import yui.comn.mybatisx.core.InjectorMapperAnnotationAssistant;
import yui.comn.mybatisx.core.enums.SoftSqlMethod;
import yui.comn.mybatisx.core.toolkit.MybatisLinkConstants;
/**
*
* 抽象的注入方法类
*
*
* @author yuyi ([email protected])
*/
public abstract class AbstractSoftMethod extends AbstractMethod {
private static final long serialVersionUID = -8889492920740410293L;
/**
* 注入自定义方法
*/
public void inject(MapperBuilderAssistant builderAssistant, Class> mapperClass, Class> modelClass, TableInfo tableInfo) {
this.configuration = builderAssistant.getConfiguration();
this.builderAssistant = builderAssistant;
this.languageDriver = configuration.getDefaultScriptingLanguageInstance();
parseResultMap(builderAssistant, mapperClass, modelClass, tableInfo);
injectMappedStatement(mapperClass, modelClass, tableInfo);
}
/**
* 通过反射机制,通过属性名称,实例化对象中的对象(该对象不是基本类型,一般是自定义对象)
*/
public void parseResultMap(MapperBuilderAssistant builderAssistant, Class> mapperClass,
Class> modelClass, TableInfo tableInfo) {
if (StringUtils.isNotBlank(tableInfo.getResultMap())) {
return;
}
InjectorMapperAnnotationAssistant resultMapBuilder = new InjectorMapperAnnotationAssistant(
configuration, builderAssistant, mapperClass);
String resultMapId = resultMapBuilder.parseResultMapp(modelClass);
logger.debug("resultMapId --> " + resultMapId);
// tableInfo.setResultMap(resultMapId);
initTableResultMap(tableInfo, resultMapId);
}
@SuppressWarnings("rawtypes")
private void initTableResultMap(TableInfo tableInfo, String resultMapId) {
try {
// 获取obj类的字节文件对象
Class c = tableInfo.getClass();
// 获取该类的成员变量
Field f = c.getDeclaredField("resultMap");
// 取消语言访问检查
f.setAccessible(true);
// 给变量赋值
f.set(tableInfo, resultMapId);
} catch (Exception e) {
}
}
/**
* 插入resultMap查询ms
*/
protected MappedStatement addSelectMappedStatement(Class> mapperClass, String id, SqlSource sqlSource, String resultMap) {
return addMappedStatement(mapperClass, id, sqlSource, SqlCommandType.SELECT, null, resultMap, null,
new NoKeyGenerator(), null, null);
}
/**
* 插入resultType查询ms
*/
protected MappedStatement addSelectMappedStatement(Class> mapperClass, String id, SqlSource sqlSource, Class> resultType) {
return addMappedStatement(mapperClass, id, sqlSource, SqlCommandType.SELECT, null, null, resultType,
new NoKeyGenerator(), null, null);
}
/**
*
* SQL 更新 set 语句
*
*
* @param table 表信息
* @return sql set 片段
*/
protected String sqlLogicSet(TableInfo table) {
return "SET " + table.getLogicDeleteSql(false, true);
}
protected String getAliasTable(TableInfo table) {
return table.getTableName() + StringPool.SPACE + table.getTableName();
}
protected String getAliasLogicDeleteSql(TableInfo table) {
String logicDeleteSql = table.getLogicDeleteSql(false, false);
if (StringUtils.isNotBlank(logicDeleteSql)) {
return " AND " + logicDeleteSql;
}
return "";
}
/**
*
* SQL 查询所有 表名.字段
* 如 t_sys_user.username
*
*
* @param table 表信息
* @param queryWrapper 是否为使用 queryWrapper 查询
* @return sql 脚本
*/
protected String sqlSelectAliasColumns(TableInfo table, boolean queryWrapper) {
/* 假设存在 resultMap 映射返回 */
String selectColumns = StringPool.ASTERISK;
/* 普通查询 */
selectColumns = table.getAllSqlSelect();
StringBuffer aliasColums = new StringBuffer();
String[] columns = selectColumns.split(StringPool.COMMA);
for (String column : columns) {
if (aliasColums.length() > 0) {
aliasColums.append(StringPool.COMMA).append(StringPool.SPACE);
}
aliasColums.append(table.getTableName()).append(StringPool.DOT)
// .append(StringPool.BACKTICK)
.append(column)
// .append(StringPool.BACKTICK)
.append(StringPool.SPACE).append(table.getTableName())
.append(StringPool.UNDERSCORE).append(StringPool.UNDERSCORE)
.append(column);
}
selectColumns = aliasColums.toString();
if (!queryWrapper) {
return selectColumns;
}
return SqlScriptUtils.convertChoose(String.format("%s != null and %s != null",
Constants.WRAPPER, Constants.Q_WRAPPER_SQL_SELECT),
SqlScriptUtils.unSafeParam(Constants.Q_WRAPPER_SQL_SELECT), selectColumns);
}
protected String sqlWhereWrapper(boolean newLine, TableInfo table, String prefix) {
String sqlScript;
if (table.isWithLogicDelete()) {
sqlScript = table.getLogicDeleteSql(true, true) + "\n";
String normalSqlScript = SqlScriptUtils.convertIf(String.format("AND ${%s}", prefix + ".sqlSegment"),
String.format("%s != null and %s != '' and %s", prefix + ".sqlSegment", prefix + ".sqlSegment", prefix + ".nonEmptyOfNormal"), true);
normalSqlScript = normalSqlScript + "\n";
normalSqlScript = normalSqlScript + SqlScriptUtils.convertIf(String.format(" ${%s}", prefix + ".sqlSegment"),
String.format("%s != null and %s != '' and %s", prefix + ".sqlSegment", prefix + ".sqlSegment", prefix + ".emptyOfNormal"), true);
sqlScript = sqlScript + normalSqlScript;
sqlScript = SqlScriptUtils.convertChoose(String.format("%s != null", prefix), sqlScript, table.getLogicDeleteSql(false, true));
sqlScript = SqlScriptUtils.convertWhere(sqlScript);
return newLine ? "\n" + sqlScript : sqlScript;
} else {
sqlScript = SqlScriptUtils.convertIf(String.format(SqlScriptUtils.convertIf(" AND",
String.format("%s and %s", prefix + ".nonEmptyOfEntity", prefix + ".nonEmptyOfNormal"), false) + " ${%s}", prefix + ".sqlSegment"),
String.format("%s != null and %s != '' and %s", prefix + ".sqlSegment", prefix + ".sqlSegment", prefix + ".nonEmptyOfWhere"), true);
sqlScript = SqlScriptUtils.convertWhere(sqlScript) + "\n";
sqlScript = sqlScript + SqlScriptUtils.convertIf(String.format(" ${%s}", prefix + ".sqlSegment"),
String.format("%s != null and %s != '' and %s", prefix + ".sqlSegment", prefix + ".sqlSegment", prefix + ".emptyOfWhere"), true);
sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", prefix), true);
return newLine ? "\n" + sqlScript : sqlScript;
}
}
/*// ------------ 处理逻辑删除条件过滤 ------------
@Override
protected String sqlWhereEntityWrapper(boolean newLine, TableInfo table) {
return sqlWhereEntityWrapper(newLine, table, null);
}
protected String sqlWhereEntityWrapper(boolean newLine, TableInfo table, Class> modelClass) {
if (table.isLogicDelete()) {
String sqlScript = table.getAllSqlWhere(true, true, Constants.WRAPPER_ENTITY_DOT);
sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", Constants.WRAPPER_ENTITY), true);
sqlScript += StringPool.NEWLINE + getAliasLogicDeleteSql(table) + StringPool.NEWLINE;
// //如果租户ID存在, 增加租户ID过滤
// if (null != modelClass && null != TableUtils.getTenantId(modelClass)) {
// String sqlTntId = " AND " + TableUtils.getTenantId(modelClass) + " = ${%s}";
// sqlScript += SqlScriptUtils.convertIf(String.format(sqlTntId, Constants.WRAPPER_DOT + MybatisxConstants.TNT_ID),
// String.format("%s != null", Constants.WRAPPER_DOT + MybatisxConstants.TNT_ID,
// Constants.WRAPPER_DOT + MybatisxConstants.TNT_ID), true);
// sqlScript += StringPool.NEWLINE;
// }
sqlScript += SqlScriptUtils.convertIf(String.format(" AND ${%s}", WRAPPER_SQLSEGMENT),
String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT,
WRAPPER_NONEMPTYOFWHERE), true);
sqlScript += StringPool.NEWLINE;
// sqlScript = SqlScriptUtils.convertWhere(sqlScript) + NEWLINE;
sqlScript += SqlScriptUtils.convertIf(String.format(" ${%s}", WRAPPER_SQLSEGMENT),
String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT,
WRAPPER_EMPTYOFWHERE), true);
//sqlScript += StringPool.NEWLINE;
sqlScript = SqlScriptUtils.convertChoose("ew != null", sqlScript, table.getLogicDeleteSql(true, false));
sqlScript = SqlScriptUtils.convertTrim(sqlScript, "WHERE", null, "AND|OR", null);
return newLine ? NEWLINE + sqlScript : sqlScript;
}
// 正常逻辑
return super.sqlWhereEntityWrapper(newLine, table);
}*/
/*@Override
protected String sqlWhereByMap(TableInfo table) {
if (table.isLogicDelete()) {
// 逻辑删除
String sqlScript = SqlScriptUtils.convertChoose("v == null", " ${k} IS NULL ",
" ${k} = #{v} ");
sqlScript = SqlScriptUtils.convertForeach(sqlScript, "cm", "k", "v", "AND");
sqlScript = SqlScriptUtils.convertIf(sqlScript, "cm != null and !cm.isEmpty", true);
sqlScript += (StringPool.NEWLINE + table.getLogicDeleteSql(true, false));
sqlScript = SqlScriptUtils.convertTrim(sqlScript, "WHERE", null, "AND", null);
return sqlScript;
}
return super.sqlWhereByMap(table);
}*/
/**
*
* SQL 更新 set 语句
*
*
* @param logic 是否逻辑删除注入器
* @param ew 是否存在 UpdateWrapper 条件
* @param table 表信息
* @param alias 别名
* @param prefix 前缀
* @return sql
*/
protected String sqlAllSet(boolean logic, boolean ew, TableInfo table, String alias, String prefix) {
// String sqlScript = SqlScriptUtils.convertIf(table.getAllSqlSet(logic, prefix), String.format("%s != null", alias), true);
String sqlScript = getAllSqlSet(logic, prefix, table);
if (ew) {
sqlScript += NEWLINE + "";
sqlScript += SqlScriptUtils.convertIf(SqlScriptUtils.unSafeParam(U_WRAPPER_SQL_SET),
String.format("%s != null and %s != null", WRAPPER, U_WRAPPER_SQL_SET), false);
}
sqlScript = SqlScriptUtils.convertSet(sqlScript);
return sqlScript;
}
private String getAllSqlSet(boolean ignoreLogicDelFiled, final String prefix, TableInfo table) {
final String newPrefix = prefix == null ? EMPTY : prefix;
return table.getFieldList().stream()
.filter(i -> {
if (i.getFieldFill() == FieldFill.INSERT) {
return false;
}
if (ignoreLogicDelFiled) {
return !(table.isWithLogicDelete() && i.isLogicDelete());
}
return true;
}).map(i -> getSqlSet(newPrefix, i)).collect(joining(NEWLINE));
}
/**
* 获取 set sql 片段
*
* @param prefix 前缀
* @return sql 脚本片段
*/
protected String getSqlSet(final String prefix, TableFieldInfo tableField) {
// if (tableField.getFieldFill() == FieldFill.INSERT || tableField.getFieldFill() == FieldFill.INSERT_UPDATE) {
// return "";
// }
final String newPrefix = prefix == null ? EMPTY : prefix;
// 默认: column=
String sqlSet = tableField.getColumn() + EQUALS;
if (StringUtils.isNotBlank(tableField.getUpdate())) {
sqlSet += String.format(tableField.getUpdate(), tableField.getColumn());
} else {
sqlSet += SqlScriptUtils.safeParam(newPrefix + tableField.getEl());
}
sqlSet += COMMA;
// if (tableField.getFieldFill() == FieldFill.UPDATE || tableField.getFieldFill() == FieldFill.INSERT_UPDATE) {
// 不进行 if 包裹
// return sqlSet;
// }
return sqlSet;
}
/**
* 支持获取动态表名
*
* @param tableInfo
* @return
*/
protected String getDynamicTableName(TableInfo tableInfo) {
return SqlScriptUtils.convertChoose(
String.format("%s != null and %s != null", WRAPPER, WRAPPER_DOT + MybatisLinkConstants.TABLE_NAME),
String.format("${%s} %s", WRAPPER_DOT + MybatisLinkConstants.TABLE_NAME, tableInfo.getTableName()),
tableInfo.getTableName());
// return SqlScriptUtils.convertChoose(
// String.format("%s != null and %s != null and %s != null",
// Constants.WRAPPER,
// Constants.WRAPPER_DOT + MybatisxConstants.TABLE_NAME_MAP,
// Constants.WRAPPER_DOT + MybatisxConstants.TABLE_NAME_MAP + Constants.DOT + tableInfo.getTableName()),
// String.format("${%s} %s", Constants.WRAPPER_DOT + MybatisxConstants.TABLE_NAME_MAP
// + Constants.DOT + tableInfo.getTableName(), tableInfo.getTableName()),
// tableInfo.getTableName() + Constants.SPACE + tableInfo.getTableName());
}
/**
* 获取自定义方法名,未设置采用默认方法名
* https://gitee.com/baomidou/mybatis-plus/pulls/88
*
* @return method
* @author 义陆无忧
*/
public String getMethod(SoftSqlMethod sqlMethod) {
return sqlMethod.getMethod();
}
// /**
// *
// * 支持获取动态表名和别名
// * 例如 t_sys_user t_sys_user
// *
// */
// protected String getDynamicTableName(TableInfo tableInfo) {
// String tableName = tableInfo.getTableName();
// return SqlScriptUtils.convertChoose(
// String.format("%s != null and %s != null and %s != null",
// Constants.WRAPPER,
// Constants.WRAPPER_DOT + MybatisxConstants.TB_MAP,
// Constants.WRAPPER_DOT + MybatisxConstants.TB_MAP + Constants.DOT + tableName),
// String.format("${%s} %s", Constants.WRAPPER_DOT + MybatisxConstants.TB_MAP + Constants.DOT + tableName, tableName),
// tableInfo.getTableName());
// }
}