|
@@ -1,5 +1,7 @@
|
|
|
package com.chelvc.framework.database.interceptor;
|
|
|
|
|
|
+import java.sql.Connection;
|
|
|
+import java.time.LocalDateTime;
|
|
|
import java.util.Collection;
|
|
|
import java.util.Collections;
|
|
|
import java.util.Date;
|
|
@@ -9,9 +11,13 @@ import java.util.Objects;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
|
|
import com.chelvc.framework.base.context.SessionContextHolder;
|
|
|
import com.chelvc.framework.common.exception.ParameterInvalidException;
|
|
|
+import com.chelvc.framework.common.util.DateUtils;
|
|
|
import com.chelvc.framework.common.util.ObjectUtils;
|
|
|
+import com.chelvc.framework.common.util.StringUtils;
|
|
|
import com.chelvc.framework.database.context.DatabaseContextHolder;
|
|
|
import com.chelvc.framework.database.context.UniqueContext;
|
|
|
import com.chelvc.framework.database.entity.Creatable;
|
|
@@ -19,9 +25,25 @@ import com.chelvc.framework.database.entity.Deletable;
|
|
|
import com.chelvc.framework.database.entity.Entity;
|
|
|
import com.chelvc.framework.database.entity.Updatable;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import net.sf.jsqlparser.JSQLParserException;
|
|
|
+import net.sf.jsqlparser.expression.Alias;
|
|
|
+import net.sf.jsqlparser.expression.Expression;
|
|
|
+import net.sf.jsqlparser.expression.LongValue;
|
|
|
+import net.sf.jsqlparser.expression.StringValue;
|
|
|
+import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
|
|
|
+import net.sf.jsqlparser.expression.operators.relational.ItemsList;
|
|
|
+import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList;
|
|
|
+import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
|
|
+import net.sf.jsqlparser.schema.Column;
|
|
|
+import net.sf.jsqlparser.schema.Table;
|
|
|
+import net.sf.jsqlparser.statement.Statement;
|
|
|
+import net.sf.jsqlparser.statement.Statements;
|
|
|
+import net.sf.jsqlparser.statement.insert.Insert;
|
|
|
+import net.sf.jsqlparser.statement.update.Update;
|
|
|
import org.apache.ibatis.binding.MapperMethod;
|
|
|
import org.apache.ibatis.cache.CacheKey;
|
|
|
import org.apache.ibatis.executor.Executor;
|
|
|
+import org.apache.ibatis.executor.statement.StatementHandler;
|
|
|
import org.apache.ibatis.mapping.BoundSql;
|
|
|
import org.apache.ibatis.mapping.MappedStatement;
|
|
|
import org.apache.ibatis.mapping.SqlCommandType;
|
|
@@ -30,6 +52,7 @@ import org.apache.ibatis.plugin.Intercepts;
|
|
|
import org.apache.ibatis.plugin.Invocation;
|
|
|
import org.apache.ibatis.plugin.Plugin;
|
|
|
import org.apache.ibatis.plugin.Signature;
|
|
|
+import org.apache.ibatis.reflection.SystemMetaObject;
|
|
|
import org.apache.ibatis.session.ResultHandler;
|
|
|
import org.apache.ibatis.session.RowBounds;
|
|
|
import org.springframework.stereotype.Component;
|
|
@@ -44,6 +67,7 @@ import org.springframework.stereotype.Component;
|
|
|
@Component
|
|
|
@Intercepts({
|
|
|
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
|
|
|
+ @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}),
|
|
|
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class,
|
|
|
RowBounds.class, ResultHandler.class}),
|
|
|
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class,
|
|
@@ -51,66 +75,258 @@ import org.springframework.stereotype.Component;
|
|
|
})
|
|
|
public class PropertyUpdateInterceptor implements Interceptor {
|
|
|
/**
|
|
|
- * 初始化实体默认属性值
|
|
|
+ * 构建操作人字段值表达式
|
|
|
*
|
|
|
- * @param entity 数据实体
|
|
|
+ * @return 表达式实例
|
|
|
*/
|
|
|
- private void initializeDefaultValue(Entity<?> entity) {
|
|
|
- Date now = new Date();
|
|
|
+ private Expression operator() {
|
|
|
Long operator = SessionContextHolder.getId();
|
|
|
- if (entity instanceof Creatable) {
|
|
|
- Creatable<?> creatable = (Creatable<?>) entity;
|
|
|
- if (creatable.getCreator() == null) {
|
|
|
- creatable.setCreator(operator);
|
|
|
+ return operator == null ? Expressions.NULL_VALUE : new LongValue(operator);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建操作时间字段值表达式
|
|
|
+ *
|
|
|
+ * @return 表达式实例
|
|
|
+ */
|
|
|
+ private Expression datetime() {
|
|
|
+ return new StringValue(DateUtils.DEFAULT_DATETIME_MILLIS_FORMATTER.format(LocalDateTime.now()));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断是否包含指定列
|
|
|
+ *
|
|
|
+ * @param columns 列对象实例列表
|
|
|
+ * @param column 列对象实例
|
|
|
+ * @return true/false
|
|
|
+ */
|
|
|
+ private boolean isContains(List<Column> columns, Column column) {
|
|
|
+ if (ObjectUtils.notEmpty(columns)) {
|
|
|
+ for (Column c : columns) {
|
|
|
+ if (Objects.equals(c.getColumnName(), column.getColumnName())) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断是否包含指定列
|
|
|
+ *
|
|
|
+ * @param table 表对象实例
|
|
|
+ * @param columns 列对象实例列表
|
|
|
+ * @param column 列对象实例
|
|
|
+ * @return true/false
|
|
|
+ */
|
|
|
+ private boolean isContains(Table table, List<Column> columns, Column column) {
|
|
|
+ if (ObjectUtils.notEmpty(columns)) {
|
|
|
+ for (Column c : columns) {
|
|
|
+ String alias = ObjectUtils.ifNull(table.getAlias(), Alias::getName, table::getName);
|
|
|
+ if (Objects.equals(alias, ObjectUtils.ifNull(c.getTable(), Table::getName))
|
|
|
+ && Objects.equals(c.getColumnName(), column.getColumnName())) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 初始化创建信息默认值
|
|
|
+ *
|
|
|
+ * @param creatable 创建信息
|
|
|
+ */
|
|
|
+ private void initializeCreatableValue(Creatable<?> creatable) {
|
|
|
+ creatable.setCreator(SessionContextHolder.getId());
|
|
|
+ creatable.setCreateTime(new Date());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 初始化创建信息
|
|
|
+ *
|
|
|
+ * @param type 对象类型
|
|
|
+ * @param insert 数据插入对象实例
|
|
|
+ * @return true/false
|
|
|
+ */
|
|
|
+ private boolean initializeCreatableValue(Class<?> type, Insert insert) {
|
|
|
+ if (!Creatable.class.isAssignableFrom(type)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置创建人字段值
|
|
|
+ boolean containCreator = this.isContains(insert.getColumns(), Expressions.CREATOR_COLUMN);
|
|
|
+ if (!containCreator) {
|
|
|
+ insert.addColumns(Expressions.CREATOR_COLUMN);
|
|
|
+ Expression operator = this.operator();
|
|
|
+ ItemsList items = insert.getItemsList();
|
|
|
+ if (items instanceof MultiExpressionList) {
|
|
|
+ ((MultiExpressionList) items).getExpressionLists().forEach(el -> el.getExpressions().add(operator));
|
|
|
+ } else {
|
|
|
+ ((ExpressionList) items).getExpressions().add(operator);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置创建时间字段值
|
|
|
+ boolean containCreateTime = this.isContains(insert.getColumns(), Expressions.CREATE_TIME_COLUMN);
|
|
|
+ if (!containCreateTime) {
|
|
|
+ insert.addColumns(Expressions.CREATE_TIME_COLUMN);
|
|
|
+ Expression datetime = this.datetime();
|
|
|
+ ItemsList items = insert.getItemsList();
|
|
|
+ if (items instanceof MultiExpressionList) {
|
|
|
+ ((MultiExpressionList) items).getExpressionLists().forEach(el -> el.getExpressions().add(datetime));
|
|
|
+ } else {
|
|
|
+ ((ExpressionList) items).getExpressions().add(datetime);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return !(containCreator && containCreateTime);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 初始化修改信息默认值
|
|
|
+ *
|
|
|
+ * @param updatable 修改信息
|
|
|
+ */
|
|
|
+ private void initializeUpdatableValue(Updatable<?> updatable) {
|
|
|
+ updatable.setUpdater(SessionContextHolder.getId());
|
|
|
+ updatable.setUpdateTime(new Date());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 初始化修改信息
|
|
|
+ *
|
|
|
+ * @param type 对象类型
|
|
|
+ * @param insert 数据插入对象实例
|
|
|
+ * @return true/false
|
|
|
+ */
|
|
|
+ private boolean initializeUpdatableValue(Class<?> type, Insert insert) {
|
|
|
+ if (!Updatable.class.isAssignableFrom(type)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置更新人字段值
|
|
|
+ boolean containUpdater = this.isContains(insert.getColumns(), Expressions.UPDATER_COLUMN);
|
|
|
+ if (!containUpdater) {
|
|
|
+ insert.addColumns(Expressions.UPDATER_COLUMN);
|
|
|
+ Expression operator = this.operator();
|
|
|
+ ItemsList items = insert.getItemsList();
|
|
|
+ if (items instanceof MultiExpressionList) {
|
|
|
+ ((MultiExpressionList) items).getExpressionLists().forEach(el -> el.getExpressions().add(operator));
|
|
|
+ } else {
|
|
|
+ ((ExpressionList) items).getExpressions().add(operator);
|
|
|
}
|
|
|
- if (creatable.getCreateTime() == null) {
|
|
|
- creatable.setCreateTime(now);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置更新时间字段值
|
|
|
+ boolean containUpdateTime = this.isContains(insert.getColumns(), Expressions.UPDATE_TIME_COLUMN);
|
|
|
+ if (!containUpdateTime) {
|
|
|
+ insert.addColumns(Expressions.UPDATE_TIME_COLUMN);
|
|
|
+ Expression datetime = this.datetime();
|
|
|
+ ItemsList items = insert.getItemsList();
|
|
|
+ if (items instanceof MultiExpressionList) {
|
|
|
+ ((MultiExpressionList) items).getExpressionLists().forEach(el -> el.getExpressions().add(datetime));
|
|
|
+ } else {
|
|
|
+ ((ExpressionList) items).getExpressions().add(datetime);
|
|
|
}
|
|
|
}
|
|
|
- if (entity instanceof Updatable) {
|
|
|
- Updatable<?> updatable = (Updatable<?>) entity;
|
|
|
- updatable.setUpdater(operator);
|
|
|
- updatable.setUpdateTime(now);
|
|
|
+ return !(containUpdater && containUpdateTime);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 初始化修改信息
|
|
|
+ *
|
|
|
+ * @param type 对象类型
|
|
|
+ * @param update 数据修改对象实例
|
|
|
+ * @return true/false
|
|
|
+ */
|
|
|
+ private boolean initializeUpdatableValue(Class<?> type, Update update) {
|
|
|
+ if (!Updatable.class.isAssignableFrom(type)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置更新人字段值
|
|
|
+ Table table = update.getTable();
|
|
|
+ boolean containUpdater = this.isContains(table, update.getColumns(), Expressions.UPDATER_COLUMN);
|
|
|
+ if (!containUpdater) {
|
|
|
+ if (StringUtils.isEmpty(table.getAlias())) {
|
|
|
+ update.addColumns(Expressions.UPDATER_COLUMN);
|
|
|
+ } else {
|
|
|
+ update.addColumns(new Column(table, Expressions.UPDATER_COLUMN.getColumnName()));
|
|
|
+ }
|
|
|
+ update.addExpressions(this.operator());
|
|
|
}
|
|
|
- if (entity instanceof Deletable) {
|
|
|
- Deletable<?> deletable = (Deletable<?>) entity;
|
|
|
- if (deletable.getDeleted() == null) {
|
|
|
- deletable.setDeleted(false);
|
|
|
+
|
|
|
+ // 设置更新时间字段值
|
|
|
+ boolean containUpdateTime = this.isContains(table, update.getColumns(), Expressions.UPDATE_TIME_COLUMN);
|
|
|
+ if (!containUpdateTime) {
|
|
|
+ if (StringUtils.isEmpty(table.getAlias())) {
|
|
|
+ update.addColumns(Expressions.UPDATE_TIME_COLUMN);
|
|
|
+ } else {
|
|
|
+ update.addColumns(new Column(table, Expressions.UPDATE_TIME_COLUMN.getColumnName()));
|
|
|
}
|
|
|
+ update.addExpressions(this.datetime());
|
|
|
+ }
|
|
|
+ return !(containUpdater && containUpdateTime);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 初始化删除信息默认值
|
|
|
+ *
|
|
|
+ * @param deletable 删除信息
|
|
|
+ */
|
|
|
+ private void initializeDeletableValue(Deletable<?> deletable) {
|
|
|
+ deletable.setDeleted(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 初始化删除信息
|
|
|
+ *
|
|
|
+ * @param type 对象类型
|
|
|
+ * @param insert 数据插入对象实例
|
|
|
+ * @return true/false
|
|
|
+ */
|
|
|
+ private boolean initializeDeletableValue(Class<?> type, Insert insert) {
|
|
|
+ if (Deletable.class.isAssignableFrom(type)
|
|
|
+ && !this.isContains(insert.getColumns(), Expressions.UPDATER_COLUMN)) {
|
|
|
+ insert.addColumns(Expressions.DELETED_COLUMN);
|
|
|
+ insert.addSetExpressionList(Expressions.ZERO_VALUE);
|
|
|
+ return true;
|
|
|
}
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 数据查询
|
|
|
+ * 数据查询拦截
|
|
|
*
|
|
|
* @param invocation 方法调用信息
|
|
|
* @return 查询结果
|
|
|
* @throws Throwable 操作异常
|
|
|
*/
|
|
|
private Object select(Invocation invocation) throws Throwable {
|
|
|
- // 加密数据解码
|
|
|
+ // 铭感数据解密
|
|
|
Object result = invocation.proceed();
|
|
|
- if (ObjectUtils.notBlank(result) && DatabaseContextHolder.isCodecEnabled()) {
|
|
|
- try {
|
|
|
- DatabaseContextHolder.decoder(cipher -> ObjectUtils.stream(result).forEach(
|
|
|
- entity -> DatabaseContextHolder.decode(cipher, entity)
|
|
|
- ));
|
|
|
- } catch (Exception e) {
|
|
|
- log.warn("Confidential value decode failed: {}", e.getMessage());
|
|
|
+ try {
|
|
|
+ if (result instanceof Collection) {
|
|
|
+ DatabaseContextHolder.decode((Collection<?>) result);
|
|
|
+ } else if (result != null) {
|
|
|
+ DatabaseContextHolder.decode(result);
|
|
|
}
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("Confidential value decode failed: {}", e.getMessage());
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 数据更新
|
|
|
+ * 数据更新拦截
|
|
|
*
|
|
|
* @param invocation 方法调用信息
|
|
|
+ * @param operation 更新操作类型
|
|
|
* @return 更新结果
|
|
|
* @throws Throwable 操作异常
|
|
|
*/
|
|
|
- private Object modify(Invocation invocation) throws Throwable {
|
|
|
- // 获取更新目标对象实例
|
|
|
+ private Object modify(Invocation invocation, SqlCommandType operation) throws Throwable {
|
|
|
+ // 获取更新参数
|
|
|
Object object = invocation.getArgs()[1];
|
|
|
if (object instanceof MapperMethod.ParamMap) {
|
|
|
// 如果是批量更新则为ParamMap
|
|
@@ -124,15 +340,65 @@ public class PropertyUpdateInterceptor implements Interceptor {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 数据更新
|
|
|
+ // 实体数据更新
|
|
|
if (object instanceof Collection) {
|
|
|
- ((Collection<?>) object).forEach(entity -> {
|
|
|
+ for (Object entity : (Collection<?>) object) {
|
|
|
if (entity instanceof Entity) {
|
|
|
- this.modify((Entity<?>) entity);
|
|
|
+ this.modify((Entity<?>) entity, operation);
|
|
|
}
|
|
|
- });
|
|
|
+ }
|
|
|
} else if (object instanceof Entity) {
|
|
|
- this.modify((Entity<?>) object);
|
|
|
+ this.modify((Entity<?>) object, operation);
|
|
|
+ }
|
|
|
+ return invocation.proceed();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * SQL预处理拦截
|
|
|
+ *
|
|
|
+ * @param invocation 方法调用信息
|
|
|
+ * @return 执行结果
|
|
|
+ * @throws Throwable 操作异常
|
|
|
+ */
|
|
|
+ private Object prepare(Invocation invocation) throws Throwable {
|
|
|
+ Statements statements;
|
|
|
+ BoundSql bound = ((StatementHandler) invocation.getTarget()).getBoundSql();
|
|
|
+ try {
|
|
|
+ statements = CCJSqlParserUtil.parseStatements(bound.getSql());
|
|
|
+ } catch (JSQLParserException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建带默认值SQL语句
|
|
|
+ StringBuilder sql = null;
|
|
|
+ for (Statement statement : statements.getStatements()) {
|
|
|
+ boolean changed = false;
|
|
|
+ if (statement instanceof Insert) {
|
|
|
+ Insert insert = (Insert) statement;
|
|
|
+ TableInfo table = DatabaseContextHolder.getTable(insert.getTable().getName());
|
|
|
+ Class<?> type = ObjectUtils.ifNull(table, TableInfo::getEntityType);
|
|
|
+ changed = type != null && (this.initializeCreatableValue(type, insert)
|
|
|
+ || this.initializeUpdatableValue(type, insert) || this.initializeDeletableValue(type, insert));
|
|
|
+ } else if (statement instanceof Update) {
|
|
|
+ Update update = (Update) statement;
|
|
|
+ TableInfo table = DatabaseContextHolder.getTable(update.getTable().getName());
|
|
|
+ Class<?> type = ObjectUtils.ifNull(table, TableInfo::getEntityType);
|
|
|
+ changed = type != null && this.initializeUpdatableValue(type, update);
|
|
|
+ }
|
|
|
+ if (changed) {
|
|
|
+ if (sql == null) {
|
|
|
+ sql = new StringBuilder();
|
|
|
+ }
|
|
|
+ if (sql.length() > 0) {
|
|
|
+ sql.append(StringPool.SEMICOLON);
|
|
|
+ }
|
|
|
+ sql.append(statement.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 重置SQL语句
|
|
|
+ if (sql != null) {
|
|
|
+ SystemMetaObject.forObject(bound).setValue("sql", sql.toString());
|
|
|
}
|
|
|
return invocation.proceed();
|
|
|
}
|
|
@@ -140,17 +406,30 @@ public class PropertyUpdateInterceptor implements Interceptor {
|
|
|
/**
|
|
|
* 实体信息更新
|
|
|
*
|
|
|
- * @param entity 实体对象实例
|
|
|
- * @param <T> 实体类型
|
|
|
+ * @param entity 实体对象实例
|
|
|
+ * @param operation 更新操作类型
|
|
|
+ * @param <T> 实体类型
|
|
|
*/
|
|
|
@SuppressWarnings("unchecked")
|
|
|
- private <T extends Entity<?>> void modify(T entity) {
|
|
|
- // 初始化实体默认属性值
|
|
|
- this.initializeDefaultValue(entity);
|
|
|
+ private <T extends Entity<?>> void modify(T entity, SqlCommandType operation) {
|
|
|
+ // 初始化字段默认值
|
|
|
+ if (operation == SqlCommandType.INSERT) {
|
|
|
+ if (entity instanceof Creatable) {
|
|
|
+ this.initializeCreatableValue((Creatable<?>) entity);
|
|
|
+ }
|
|
|
+ if (entity instanceof Updatable) {
|
|
|
+ this.initializeUpdatableValue((Updatable<?>) entity);
|
|
|
+ }
|
|
|
+ if (entity instanceof Deletable) {
|
|
|
+ this.initializeDeletableValue((Deletable<?>) entity);
|
|
|
+ }
|
|
|
+ } else if (operation == SqlCommandType.UPDATE && entity instanceof Updatable) {
|
|
|
+ this.initializeUpdatableValue((Updatable<?>) entity);
|
|
|
+ }
|
|
|
|
|
|
// 设置加密属性值
|
|
|
Class<T> clazz = (Class<T>) entity.getClass();
|
|
|
- boolean encoding = DatabaseContextHolder.isCodecEnabled() && DatabaseContextHolder.isConfidential(clazz);
|
|
|
+ boolean encoding = DatabaseContextHolder.isConfidential(clazz);
|
|
|
T original = encoding ? ObjectUtils.copying(entity, clazz) : entity;
|
|
|
if (encoding) {
|
|
|
DatabaseContextHolder.encode(entity);
|
|
@@ -193,20 +472,21 @@ public class PropertyUpdateInterceptor implements Interceptor {
|
|
|
|
|
|
@Override
|
|
|
public Object intercept(Invocation invocation) throws Throwable {
|
|
|
- if (!(invocation.getTarget() instanceof Executor)) {
|
|
|
- return invocation.proceed();
|
|
|
- }
|
|
|
- SqlCommandType operation = ((MappedStatement) invocation.getArgs()[0]).getSqlCommandType();
|
|
|
- if (operation == SqlCommandType.SELECT) {
|
|
|
- return this.select(invocation);
|
|
|
- } else if (operation == SqlCommandType.INSERT || operation == SqlCommandType.UPDATE) {
|
|
|
- return this.modify(invocation);
|
|
|
+ if (invocation.getTarget() instanceof Executor) {
|
|
|
+ SqlCommandType operation = ((MappedStatement) invocation.getArgs()[0]).getSqlCommandType();
|
|
|
+ if (operation == SqlCommandType.SELECT) {
|
|
|
+ return this.select(invocation);
|
|
|
+ } else if (operation == SqlCommandType.INSERT || operation == SqlCommandType.UPDATE) {
|
|
|
+ return this.modify(invocation, operation);
|
|
|
+ }
|
|
|
+ } else if (invocation.getTarget() instanceof StatementHandler) {
|
|
|
+ return this.prepare(invocation);
|
|
|
}
|
|
|
return invocation.proceed();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public Object plugin(Object target) {
|
|
|
- return target instanceof Executor ? Plugin.wrap(target, this) : target;
|
|
|
+ return target instanceof Executor || target instanceof StatementHandler ? Plugin.wrap(target, this) : target;
|
|
|
}
|
|
|
}
|