diff --git a/common/mall-spring-boot-starter-mybatis/src/main/java/cn/iocoder/mall/mybatis/core/MybatisPlusAutoConfiguration.java b/common/mall-spring-boot-starter-mybatis/src/main/java/cn/iocoder/mall/mybatis/core/MybatisPlusAutoConfiguration.java new file mode 100644 index 000000000..789d2fac9 --- /dev/null +++ b/common/mall-spring-boot-starter-mybatis/src/main/java/cn/iocoder/mall/mybatis/core/MybatisPlusAutoConfiguration.java @@ -0,0 +1,23 @@ +package cn.iocoder.mall.mybatis.core; + +import cn.iocoder.mall.mybatis.core.injector.CustomSqlInject; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import com.baomidou.mybatisplus.core.injector.ISqlInjector; + +/** + * @author Hccake 2020/8/3 + * @version 1.0 + */ +public class MybatisPlusAutoConfiguration { + + /** + * 自定义方法扩展注入器 + * @return ISqlInjector CustomSqlInject + */ + @Bean + @ConditionalOnMissingBean(ISqlInjector.class) + public ISqlInjector sqlInjector(){ + return new CustomSqlInject(); + } +} diff --git a/common/mall-spring-boot-starter-mybatis/src/main/java/cn/iocoder/mall/mybatis/core/enums/CustomSqlMethodEnum.java b/common/mall-spring-boot-starter-mybatis/src/main/java/cn/iocoder/mall/mybatis/core/enums/CustomSqlMethodEnum.java new file mode 100644 index 000000000..20079365f --- /dev/null +++ b/common/mall-spring-boot-starter-mybatis/src/main/java/cn/iocoder/mall/mybatis/core/enums/CustomSqlMethodEnum.java @@ -0,0 +1,40 @@ +package cn.iocoder.mall.mybatis.core.enums; + +/** + * @author Hccake 2020/8/3 + * @version 1.0 + */ +public enum CustomSqlMethodEnum { + /** + * 批量插入 + */ + INSERT_BATCH("insertByBatch", + "批量插入数据", + ""); + + private final String method; + private final String desc; + private final String sql; + + CustomSqlMethodEnum(String method, String desc, String sql) { + this.method = method; + this.desc = desc; + this.sql = sql; + } + + public String getMethod() { + return method; + } + + public String getDesc() { + return desc; + } + + public String getSql() { + return sql; + } + +} diff --git a/common/mall-spring-boot-starter-mybatis/src/main/java/cn/iocoder/mall/mybatis/core/injector/CustomSqlInject.java b/common/mall-spring-boot-starter-mybatis/src/main/java/cn/iocoder/mall/mybatis/core/injector/CustomSqlInject.java new file mode 100644 index 000000000..9cf042af5 --- /dev/null +++ b/common/mall-spring-boot-starter-mybatis/src/main/java/cn/iocoder/mall/mybatis/core/injector/CustomSqlInject.java @@ -0,0 +1,23 @@ +package cn.iocoder.mall.mybatis.core.injector; + +import cn.iocoder.mall.mybatis.core.injector.method.InsertByBatch; +import com.baomidou.mybatisplus.core.injector.AbstractMethod; +import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; + +import java.util.List; + +/** + * 自定义 Sql 注入器,继承 MybatisPlus 提供的默认注入器 + * @author Hccake 2020/8/3 + * @version 1.0 + */ +public class CustomSqlInject extends DefaultSqlInjector { + + @Override + public List getMethodList(Class mapperClass) { + List methodList = super.getMethodList(mapperClass); + methodList.add(new InsertByBatch()); + return methodList; + } + +} diff --git a/common/mall-spring-boot-starter-mybatis/src/main/java/cn/iocoder/mall/mybatis/core/injector/method/InsertByBatch.java b/common/mall-spring-boot-starter-mybatis/src/main/java/cn/iocoder/mall/mybatis/core/injector/method/InsertByBatch.java new file mode 100644 index 000000000..1fb4a78c2 --- /dev/null +++ b/common/mall-spring-boot-starter-mybatis/src/main/java/cn/iocoder/mall/mybatis/core/injector/method/InsertByBatch.java @@ -0,0 +1,82 @@ +package cn.iocoder.mall.mybatis.core.injector.method; + +import cn.iocoder.mall.mybatis.core.enums.CustomSqlMethodEnum; +import com.baomidou.mybatisplus.annotation.IdType; +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.metadata.TableInfoHelper; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils; +import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator; +import org.apache.ibatis.executor.keygen.KeyGenerator; +import org.apache.ibatis.executor.keygen.NoKeyGenerator; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.SqlSource; + +import java.util.List; + +/** + * 批量插入 + * @author Hccake 2020/8/3 + * @version 1.0 + */ +@SuppressWarnings("all") +public class InsertByBatch extends AbstractMethod { + + private final static String ITEM = "item"; + + @Override + public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { + KeyGenerator keyGenerator = new NoKeyGenerator(); + + CustomSqlMethodEnum sqlMethod = CustomSqlMethodEnum.INSERT_BATCH; + + // ==== 拼接 sql 模板 ============== + StringBuilder columnScriptBuilder = new StringBuilder(LEFT_BRACKET); + StringBuilder valuesScriptBuilder = new StringBuilder(LEFT_BRACKET); + // 主键拼接 + if (tableInfo.havePK()) { + columnScriptBuilder.append(tableInfo.getKeyColumn()).append(COMMA); + valuesScriptBuilder.append(SqlScriptUtils.safeParam(ITEM + DOT + tableInfo.getKeyProperty())).append(COMMA); + } + // 普通字段拼接 + // PS:如有需要可在此实现插入字段过滤 + List fieldList = tableInfo.getFieldList(); + for (TableFieldInfo fieldInfo : fieldList) { + columnScriptBuilder.append(fieldInfo.getColumn()).append(COMMA); + valuesScriptBuilder.append(SqlScriptUtils.safeParam(ITEM + DOT + fieldInfo.getProperty())).append(COMMA); + } + // 替换多余的逗号为括号 + columnScriptBuilder.setCharAt(columnScriptBuilder.length() - 1, ')'); + valuesScriptBuilder.setCharAt(valuesScriptBuilder.length() - 1, ')'); + // sql 模板占位符替换 + String columnScript = columnScriptBuilder.toString(); + String valuesScript = valuesScriptBuilder.toString(); + String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), columnScript, valuesScript); + + + // === mybatis 主键逻辑处理:主键生成策略,以及主键回填======= + String keyColumn = null; + String keyProperty = null; + // 表包含主键处理逻辑,如果不包含主键当普通字段处理 + if (StringUtils.isNotBlank(tableInfo.getKeyProperty())) { + if (tableInfo.getIdType() == IdType.AUTO) { + /** 自增主键 */ + keyGenerator = new Jdbc3KeyGenerator(); + keyProperty = tableInfo.getKeyProperty(); + keyColumn = tableInfo.getKeyColumn(); + } else { + if (null != tableInfo.getKeySequence()) { + keyGenerator = TableInfoHelper.genKeyGenerator(sqlMethod.getMethod(), tableInfo, builderAssistant); + keyProperty = tableInfo.getKeyProperty(); + keyColumn = tableInfo.getKeyColumn(); + } + } + } + + // 模板写入 + SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); + return this.addInsertMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource, keyGenerator, keyProperty, keyColumn); + } +} diff --git a/common/mall-spring-boot-starter-mybatis/src/main/java/cn/iocoder/mall/mybatis/core/mapper/CommonMapper.java b/common/mall-spring-boot-starter-mybatis/src/main/java/cn/iocoder/mall/mybatis/core/mapper/CommonMapper.java new file mode 100644 index 000000000..5eaaddcbf --- /dev/null +++ b/common/mall-spring-boot-starter-mybatis/src/main/java/cn/iocoder/mall/mybatis/core/mapper/CommonMapper.java @@ -0,0 +1,21 @@ +package cn.iocoder.mall.mybatis.core.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.Collection; + +/** + * Mapper 层基类 + * @author Hccake 2020/8/3 + * @version 1.0 + */ +public interface CommonMapper extends BaseMapper { + + /** + * 批量插入 + * @param collection 批量插入数据 + * @return ignore + */ + int insertByBatch(@Param("collection") Collection collection); +} diff --git a/common/mall-spring-boot-starter-mybatis/src/main/resources/META-INF/spring.factories b/common/mall-spring-boot-starter-mybatis/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..3bbfcd11f --- /dev/null +++ b/common/mall-spring-boot-starter-mybatis/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + cn.iocoder.mall.mybatis.core.MybatisPlusAutoConfiguration \ No newline at end of file