import org.apache.ibatis.builder.StaticSqlSource;
import org.apache.ibatis.executor.statement.PreparedStatementHandler;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.scripting.defaults.RawSqlSource;
import org.apache.ibatis.scripting.xmltags.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.util.List;
import java.util.Objects;
@Intercepts(
{
@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
}
)
@Component
@SuppressWarnings("unused")
public class SqlInterceptor implements Interceptor {
static final Logger log = LoggerFactory.getLogger(JpaAndMybatisAop.class);
@SuppressWarnings("all")
public <T> T getFiledObject(Object clazz, String filed) {
if (Objects.isNull(clazz) || Objects.isNull(filed)) {
return null;
} else {
T result = null;
try {
Field declaredField = clazz.getClass().getDeclaredField(filed);
declaredField.setAccessible(true);
result = (T) declaredField.get(clazz);
} catch (Exception e) {
log.error(e.getMessage());
}
return result;
}
}
public String getContentListSql(List<?> contents) {
if (contents == null || contents.isEmpty()) {
return "";
}
StringBuffer sql = new StringBuffer();
contents.forEach(content -> {
if (content instanceof StaticTextSqlNode) {
StaticTextSqlNode sqlNode = (StaticTextSqlNode) content;
String text = getFiledObject(sqlNode, "text");
if (text != null) {
sql.append(text).append(" ");
}
} else if (content instanceof ChooseSqlNode) {
MixedSqlNode defaultSqlNode = getFiledObject(content, "defaultSqlNode");
if (defaultSqlNode != null) {
String chooseContent = getContentListSql(getFiledObject(defaultSqlNode, "contents"));
if (!ObjectUtils.isEmpty(chooseContent)) {
sql.append(chooseContent).append(" ");
}
}
} else if (content instanceof IfSqlNode) {
MixedSqlNode ifSqlNodeContent = getFiledObject(content, "contents");
if (ifSqlNodeContent != null) {
String ifSqlNodeContentText = getContentListSql(getFiledObject(ifSqlNodeContent, "contents"));
if (!ObjectUtils.isEmpty(ifSqlNodeContentText)) {
sql.append(ifSqlNodeContentText).append(" ");
}
}
}
});
return sql.toString();
}
public String getSqlSourceSql(SqlSource sqlSource) {
if (Objects.isNull(sqlSource)) {
return "";
} else {
String result = "";
try {
if (sqlSource instanceof RawSqlSource) {
result = getSqlSourceSql(getFiledObject(sqlSource, "sqlSource"));
} else if (sqlSource instanceof StaticSqlSource) {
StaticSqlSource staticSqlSource = (StaticSqlSource) sqlSource;
result = getFiledObject(staticSqlSource, "sql");
} else if (sqlSource instanceof DynamicSqlSource) {
MixedSqlNode rootSqlNode = getFiledObject(sqlSource, "rootSqlNode");
if (rootSqlNode != null) {
result = getContentListSql(getFiledObject(rootSqlNode, "contents"));
}
} else {
throw new RuntimeException("没有算上此类型" + sqlSource.getClass().getName());
}
} catch (Exception e) {
log.error(e.getMessage());
}
return result;
}
}
@Override
public synchronized Object intercept(Invocation invocation) throws Throwable {
log.debug("begin.SqlInterceptor.intercept");
if (invocation.getTarget() instanceof RoutingStatementHandler) {
RoutingStatementHandler target = (RoutingStatementHandler) invocation.getTarget();
Field delegate = target.getClass().getDeclaredField("delegate");
delegate.setAccessible(true);
PreparedStatementHandler prepared = (PreparedStatementHandler) delegate.get(target);
Field mappedStatement = prepared.getClass().getSuperclass().getDeclaredField("mappedStatement");
mappedStatement.setAccessible(true);
MappedStatement mapped = (MappedStatement) mappedStatement.get(prepared);
Field sqlfField = target.getBoundSql().getClass().getDeclaredField("sql");
sqlfField.setAccessible(true);
}
Object o = invocation.proceed();
log.debug("end.SqlInterceptor.intercept");
return o;
}
}
05-18
6384
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交