From 03fac41eb32c2b595e007753d3674af2828a1f7c Mon Sep 17 00:00:00 2001 From: admin <570810310@qq.com> Date: Mon, 1 Feb 2021 15:04:51 +0800 Subject: [PATCH] update --- .../interceptor/MyResultInterceptor.java | 1 - .../interceptor/MybatisParameterHandler.java | 205 ++++++++++++++++++ 2 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/github/mybatisplus/interceptor/MybatisParameterHandler.java diff --git a/src/main/java/com/github/mybatisplus/interceptor/MyResultInterceptor.java b/src/main/java/com/github/mybatisplus/interceptor/MyResultInterceptor.java index b910368..f847f5d 100644 --- a/src/main/java/com/github/mybatisplus/interceptor/MyResultInterceptor.java +++ b/src/main/java/com/github/mybatisplus/interceptor/MyResultInterceptor.java @@ -1,6 +1,5 @@ package com.github.mybatisplus.interceptor; -import com.baomidou.mybatisplus.core.MybatisParameterHandler; import com.baomidou.mybatisplus.core.toolkit.ClassUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.github.mybatisplus.toolkit.Constant; diff --git a/src/main/java/com/github/mybatisplus/interceptor/MybatisParameterHandler.java b/src/main/java/com/github/mybatisplus/interceptor/MybatisParameterHandler.java new file mode 100644 index 0000000..19d1b5c --- /dev/null +++ b/src/main/java/com/github/mybatisplus/interceptor/MybatisParameterHandler.java @@ -0,0 +1,205 @@ +package com.github.mybatisplus.interceptor; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator; +import com.baomidou.mybatisplus.core.metadata.TableInfo; +import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils; +import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import org.apache.ibatis.executor.ErrorContext; +import org.apache.ibatis.executor.parameter.ParameterHandler; +import org.apache.ibatis.mapping.*; +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.type.JdbcType; +import org.apache.ibatis.type.TypeException; +import org.apache.ibatis.type.TypeHandler; +import org.apache.ibatis.type.TypeHandlerRegistry; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * copy {@link com.baomidou.mybatisplus.core.MybatisParameterHandler} + *

+ * 兼容3.4以下 + */ +public class MybatisParameterHandler implements ParameterHandler { + + private final TypeHandlerRegistry typeHandlerRegistry; + private final MappedStatement mappedStatement; + private final Object parameterObject; + private final BoundSql boundSql; + private final Configuration configuration; + private final SqlCommandType sqlCommandType; + + public MybatisParameterHandler(MappedStatement mappedStatement, Object parameter, BoundSql boundSql) { + this.typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry(); + this.mappedStatement = mappedStatement; + this.boundSql = boundSql; + this.configuration = mappedStatement.getConfiguration(); + this.sqlCommandType = mappedStatement.getSqlCommandType(); + this.parameterObject = processParameter(parameter); + } + + public Object processParameter(Object parameter) { + /* 只处理插入或更新操作 */ + if (parameter != null + && (SqlCommandType.INSERT == this.sqlCommandType || SqlCommandType.UPDATE == this.sqlCommandType)) { + //检查 parameterObject + if (ReflectionKit.isPrimitiveOrWrapper(parameter.getClass()) + || parameter.getClass() == String.class) { + return parameter; + } + Collection parameters = getParameters(parameter); + if (null != parameters) { + // 感觉这里可以稍微优化一下,理论上都是同一个. + parameters.forEach(this::process); + } else { + process(parameter); + } + } + return parameter; + } + + @Override + public Object getParameterObject() { + return this.parameterObject; + } + + private void process(Object parameter) { + if (parameter != null) { + TableInfo tableInfo = null; + Object entity = parameter; + if (parameter instanceof Map) { + Map map = (Map) parameter; + if (map.containsKey(Constants.ENTITY)) { + Object et = map.get(Constants.ENTITY); + if (et != null) { + entity = et; + tableInfo = TableInfoHelper.getTableInfo(entity.getClass()); + } + } + } else { + tableInfo = TableInfoHelper.getTableInfo(parameter.getClass()); + } + if (tableInfo != null) { + //到这里就应该转换到实体参数对象了,因为填充和ID处理都是争对实体对象处理的,不用传递原参数对象下去. + MetaObject metaObject = this.configuration.newMetaObject(entity); + if (SqlCommandType.INSERT == this.sqlCommandType) { + populateKeys(tableInfo, metaObject, entity); + insertFill(metaObject, tableInfo); + } else { + updateFill(metaObject, tableInfo); + } + } + } + } + + + protected void populateKeys(TableInfo tableInfo, MetaObject metaObject, Object entity) { + final IdType idType = tableInfo.getIdType(); + final String keyProperty = tableInfo.getKeyProperty(); + if (StringUtils.isNotBlank(keyProperty) && null != idType && idType.getKey() >= 3) { + final IdentifierGenerator identifierGenerator = GlobalConfigUtils.getGlobalConfig(this.configuration).getIdentifierGenerator(); + Object idValue = metaObject.getValue(keyProperty); + if (StringUtils.checkValNull(idValue)) { + if (idType.getKey() == IdType.ASSIGN_ID.getKey()) { + if (Number.class.isAssignableFrom(tableInfo.getKeyType())) { + metaObject.setValue(keyProperty, identifierGenerator.nextId(entity)); + } else { + metaObject.setValue(keyProperty, identifierGenerator.nextId(entity).toString()); + } + } else if (idType.getKey() == IdType.ASSIGN_UUID.getKey()) { + metaObject.setValue(keyProperty, identifierGenerator.nextUUID(entity)); + } + } + } + } + + + protected void insertFill(MetaObject metaObject, TableInfo tableInfo) { + GlobalConfigUtils.getMetaObjectHandler(this.configuration).ifPresent(metaObjectHandler -> { + if (metaObjectHandler.openInsertFill() && tableInfo.isWithInsertFill()) { + metaObjectHandler.insertFill(metaObject); + } + }); + } + + protected void updateFill(MetaObject metaObject, TableInfo tableInfo) { + GlobalConfigUtils.getMetaObjectHandler(this.configuration).ifPresent(metaObjectHandler -> { + if (metaObjectHandler.openUpdateFill() && tableInfo.isWithUpdateFill()) { + metaObjectHandler.updateFill(metaObject); + } + }); + } + + /** + * 处理正常批量插入逻辑 + *

+ * org.apache.ibatis.session.defaults.DefaultSqlSession$StrictMap 该类方法 + * wrapCollection 实现 StrictMap 封装逻辑 + *

+ * + * @return 集合参数 + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + protected Collection getParameters(Object parameterObject) { + Collection parameters = null; + if (parameterObject instanceof Collection) { + parameters = (Collection) parameterObject; + } else if (parameterObject instanceof Map) { + Map parameterMap = (Map) parameterObject; + if (parameterMap.containsKey("collection")) { + parameters = (Collection) parameterMap.get("collection"); + } else if (parameterMap.containsKey("list")) { + parameters = (List) parameterMap.get("list"); + } else if (parameterMap.containsKey("array")) { + parameters = Arrays.asList((Object[]) parameterMap.get("array")); + } + } + return parameters; + } + + @Override + @SuppressWarnings("unchecked") + public void setParameters(PreparedStatement ps) { + ErrorContext.instance().activity("setting parameters").object(this.mappedStatement.getParameterMap().getId()); + List parameterMappings = this.boundSql.getParameterMappings(); + if (parameterMappings != null) { + for (int i = 0; i < parameterMappings.size(); i++) { + ParameterMapping parameterMapping = parameterMappings.get(i); + if (parameterMapping.getMode() != ParameterMode.OUT) { + Object value; + String propertyName = parameterMapping.getProperty(); + if (this.boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params + value = this.boundSql.getAdditionalParameter(propertyName); + } else if (this.parameterObject == null) { + value = null; + } else if (this.typeHandlerRegistry.hasTypeHandler(this.parameterObject.getClass())) { + value = parameterObject; + } else { + MetaObject metaObject = this.configuration.newMetaObject(this.parameterObject); + value = metaObject.getValue(propertyName); + } + TypeHandler typeHandler = parameterMapping.getTypeHandler(); + JdbcType jdbcType = parameterMapping.getJdbcType(); + if (value == null && jdbcType == null) { + jdbcType = this.configuration.getJdbcTypeForNull(); + } + try { + typeHandler.setParameter(ps, i + 1, value, jdbcType); + } catch (TypeException | SQLException e) { + throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e); + } + } + } + } + } +}