From 929e12a0908d50961229baa9591c54627cca51a1 Mon Sep 17 00:00:00 2001
From: b2baccline <23131013+b2baccline@users.noreply.github.com>
Date: Tue, 9 Jun 2020 21:28:40 +0800
Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E6=B7=BB=E5=8A=A0=20mybatis-plus-?=
=?UTF-8?q?mysql=20=E6=89=A9=E5=B1=95,=20=E8=87=AA=E5=AE=9A=E4=B9=89?=
=?UTF-8?q?=E4=BA=86=E4=B8=80=E4=BA=9B=E5=85=A8=E5=B1=80=E6=96=B9=E6=B3=95?=
=?UTF-8?q?=EF=BC=8C=E7=9B=AE=E5=89=8D=E5=8F=AA=E9=80=82=E7=94=A8MySQL,?=
=?UTF-8?q?=E6=8F=90=E4=BE=9B=E4=BA=86=E8=87=AA=E5=AE=9A=E4=B9=89=E6=89=A9?=
=?UTF-8?q?=E5=B1=95=20mybatis-plus=E6=A8=A1=E5=9D=97=E7=9A=84=E7=A4=BA?=
=?UTF-8?q?=E4=BE=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../mybatis-plus-mysql-extend/pom.xml | 26 ++++
.../extend/mybatis/plus/mysql/BaseMapper.java | 57 +++++++
.../extend/mybatis/plus/mysql/Columns.java | 142 ++++++++++++++++++
.../mybatis/plus/mysql/MybatisConfig.java | 30 ++++
.../plus/mysql/methods/BaseInsertBatch.java | 67 +++++++++
.../mysql/methods/InsertIgnoreByBatch.java | 16 ++
.../mysql/methods/InsertOrUpdateByBatch.java | 42 ++++++
.../methods/InsertOrUpdateFieldByBatch.java | 41 +++++
8 files changed, 421 insertions(+)
create mode 100644 ballcat-extends/mybatis-plus-mysql-extend/pom.xml
create mode 100644 ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/BaseMapper.java
create mode 100644 ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/Columns.java
create mode 100644 ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/MybatisConfig.java
create mode 100644 ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/BaseInsertBatch.java
create mode 100644 ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/InsertIgnoreByBatch.java
create mode 100644 ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/InsertOrUpdateByBatch.java
create mode 100644 ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/InsertOrUpdateFieldByBatch.java
diff --git a/ballcat-extends/mybatis-plus-mysql-extend/pom.xml b/ballcat-extends/mybatis-plus-mysql-extend/pom.xml
new file mode 100644
index 00000000..64b057fa
--- /dev/null
+++ b/ballcat-extends/mybatis-plus-mysql-extend/pom.xml
@@ -0,0 +1,26 @@
+
+
+
+ ballcat-extends
+ com.hccake
+ 0.0.2
+
+ 4.0.0
+
+ mybatis-plus-mysql-extend
+
+
+
+ com.hccake
+ mybatis-plus-extend
+ 0.0.2
+
+
+
+ cn.hutool
+ hutool-all
+
+
+
\ No newline at end of file
diff --git a/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/BaseMapper.java b/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/BaseMapper.java
new file mode 100644
index 00000000..dcb91213
--- /dev/null
+++ b/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/BaseMapper.java
@@ -0,0 +1,57 @@
+package com.hccake.extend.mybatis.plus.mysql;
+
+import com.hccake.extend.mybatis.plus.config.StaticConfig;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 所有的 Mapper接口 都需要继承当前接口
+ * 如果想自己定义其他的全局方法, 您的全局 BaseMapper 需要继承当前接口
+ *
+ * @author lingting 2020/5/27 11:39
+ */
+public interface BaseMapper extends com.baomidou.mybatisplus.core.mapper.BaseMapper {
+
+ /**
+ * 批处理 如果重复则忽略
+ *
+ * @param list 值列表
+ * @return int
+ * @author lingting 2020-05-27 11:41:28
+ */
+ int insertIgnoreByBatch(@Param("list") List list);
+
+ /**
+ * 批处理 如果重复则更新
+ *
+ * @param list 值列表
+ * @param ignore 是否忽略全局配置的忽略字段 {@link StaticConfig#UPDATE_IGNORE_FIELDS}
+ * @return int
+ * @author lingting 2020-05-27 11:41:28
+ */
+ int insertOrUpdateByBatch(@Param("list") List list, @Param("ignore") boolean ignore);
+
+ /**
+ * 批处理 如果重复则更新 直接调用本方法会 忽略全局配置的忽略字段 {@link StaticConfig#UPDATE_IGNORE_FIELDS}
+ *
+ * @param list 值列表
+ * @return int
+ * @author lingting 2020-05-27 11:41:28
+ */
+ default int insertOrUpdateByBatch(@Param("list") List list) {
+ return insertOrUpdateByBatch(list, true);
+ }
+
+ /**
+ * 自定义 如果重复 需要更新的 field
+ * 当传入的 columns.ignore 属性为 true时
+ * 会使用您传入的 字段值 去覆盖 不在 columns.list 中 字段 的值
+ *
+ * @param list 值列表
+ * @param columns 字段
+ * @return int
+ * @author lingting 2020-05-27 15:48:20
+ */
+ int insertOrUpdateFieldByBatch(@Param("list") List list, @Param("columns") Columns columns);
+}
\ No newline at end of file
diff --git a/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/Columns.java b/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/Columns.java
new file mode 100644
index 00000000..e98afa34
--- /dev/null
+++ b/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/Columns.java
@@ -0,0 +1,142 @@
+package com.hccake.extend.mybatis.plus.mysql;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda;
+import lombok.Data;
+import lombok.Getter;
+import lombok.experimental.Accessors;
+import org.apache.ibatis.reflection.property.PropertyNamer;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 用于mybatis 自定义的 列
+ *
+ * @author lingting 2020/5/27 15:53
+ */
+@Getter
+public class Columns {
+ public static final String COLUMN_FLAG = "@";
+ /**
+ * 缓存 全类名 方法名 字段名
+ */
+ private static final Map> COLUMN_CACHE_MAP = new ConcurrentHashMap<>();
+ /**
+ * 自定义字段
+ */
+ private final List list = new ArrayList<>();
+ /**
+ * 类的所有字段
+ */
+ private final List back = new ArrayList<>();
+
+ /**
+ * 是否忽略设置的字段
+ */
+ private boolean ignore = false;
+
+ private Columns() {
+ }
+
+ private Columns(SFunction sf) {
+ this(sf, null);
+ }
+
+ private Columns(SFunction sf, String val) {
+ this.add(sf, val);
+ }
+
+ public static Columns create() {
+ return new Columns<>();
+ }
+
+ public static Columns create(SFunction sf) {
+ return new Columns<>(sf);
+ }
+
+ public static Columns create(SFunction sf, String val) {
+ return new Columns<>(sf, val);
+ }
+
+ public Columns add(SFunction sf) {
+ return add(sf, null);
+ }
+
+ /**
+ * @param val 自定义的替换sql {@link Columns#COLUMN_FLAG} 表示字段名
+ * @author lingting 2020-05-27 17:57:35
+ */
+ public Columns add(SFunction sf, String val) {
+ String column = getColumn(sf);
+ if (StrUtil.isEmpty(val)) {
+ val = "VALUES(" + column + ")";
+ }
+
+ list.add(new Column()
+ .setName(column)
+ .setVal(val.replaceAll(COLUMN_FLAG, column))
+ );
+ back.remove(column);
+ return this;
+ }
+
+ /**
+ * 获取方法所代表的表的字段名
+ *
+ * @author lingting 2020-05-27 17:56:40
+ */
+ public String getColumn(SFunction sf) {
+ SerializedLambda lambda = SerializedLambda.resolve(sf);
+
+ if (!COLUMN_CACHE_MAP.containsKey(lambda.getImplClass().getName())) {
+ ConcurrentHashMap map = new ConcurrentHashMap<>(LambdaUtils.getColumnMap(lambda.getImplClass()).size());
+ LambdaUtils.getColumnMap(lambda.getImplClass()).forEach((k, v) -> {
+ map.put(k, v.getColumn());
+ });
+ COLUMN_CACHE_MAP.put(lambda.getImplClass().getName(), map);
+ }
+
+ // 设置全字段名
+ if (back.size() == 0 && COLUMN_CACHE_MAP.get(lambda.getImplClass().getName()).size() != 0) {
+ COLUMN_CACHE_MAP.get(lambda.getImplClass().getName()).forEach((k, v) -> {
+ back.add(v);
+ });
+ }
+
+ return COLUMN_CACHE_MAP.get(lambda.getImplClass().getName())
+ .get(LambdaUtils.formatKey(PropertyNamer.methodToProperty(lambda.getImplMethodName())));
+ }
+
+ /**
+ * 忽略设置的字段
+ *
+ * @author lingting 2020-05-28 11:06:15
+ */
+ public Columns ignore() {
+ this.ignore = true;
+ return this;
+ }
+
+ /**
+ * 设置不忽略设置的字段
+ *
+ * @author lingting 2020-05-28 11:05:59
+ */
+ public Columns set() {
+ this.ignore = false;
+ return this;
+ }
+
+ @Data
+ @Accessors(chain = true)
+ public static class Column {
+ private String name;
+ private String val;
+ }
+}
+
diff --git a/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/MybatisConfig.java b/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/MybatisConfig.java
new file mode 100644
index 00000000..2fe90196
--- /dev/null
+++ b/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/MybatisConfig.java
@@ -0,0 +1,30 @@
+package com.hccake.extend.mybatis.plus.mysql;
+
+import com.baomidou.mybatisplus.core.injector.AbstractMethod;
+import com.hccake.extend.mybatis.plus.config.MybatisConfigurer;
+import com.hccake.extend.mybatis.plus.mysql.methods.InsertIgnoreByBatch;
+import com.hccake.extend.mybatis.plus.mysql.methods.InsertOrUpdateByBatch;
+import com.hccake.extend.mybatis.plus.mysql.methods.InsertOrUpdateFieldByBatch;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author lingting 2020/5/27 11:43
+ */
+@Configuration
+public class MybatisConfig implements MybatisConfigurer {
+
+ @Override
+ public void pushIgnoreFields(Set set) {
+ set.add("createTime");
+ }
+
+ @Override
+ public void pushMethods(List list) {
+ list.add(new InsertIgnoreByBatch());
+ list.add(new InsertOrUpdateByBatch());
+ list.add(new InsertOrUpdateFieldByBatch());
+ }
+}
diff --git a/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/BaseInsertBatch.java b/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/BaseInsertBatch.java
new file mode 100644
index 00000000..289e626f
--- /dev/null
+++ b/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/BaseInsertBatch.java
@@ -0,0 +1,67 @@
+package com.hccake.extend.mybatis.plus.mysql.methods;
+
+import com.baomidou.mybatisplus.core.injector.AbstractMethod;
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
+import org.apache.ibatis.executor.keygen.NoKeyGenerator;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.SqlSource;
+
+/**
+ * 所有插入自定义方法的父类
+ *
+ * @author lingting 2020/5/27 15:14
+ */
+public abstract class BaseInsertBatch extends AbstractMethod {
+
+ @Override
+ public MappedStatement injectMappedStatement(Class> mapperClass, Class> modelClass, TableInfo tableInfo) {
+ SqlSource sqlSource = languageDriver.createSqlSource(configuration,
+ String.format(getSql(), tableInfo.getTableName(),
+ prepareFieldSql(tableInfo),
+ prepareValuesSqlForMysqlBatch(tableInfo)
+ ),
+ modelClass);
+ return this.addInsertMappedStatement(mapperClass, modelClass, getId(), sqlSource, new NoKeyGenerator(), null, null);
+ }
+
+ protected String prepareFieldSql(TableInfo tableInfo) {
+ StringBuilder fieldSql = new StringBuilder();
+ fieldSql.append(tableInfo.getKeyColumn()).append(",");
+ tableInfo.getFieldList().forEach(x -> fieldSql.append(x.getColumn()).append(","));
+ fieldSql.delete(fieldSql.length() - 1, fieldSql.length());
+ fieldSql.insert(0, "(");
+ fieldSql.append(")");
+ return fieldSql.toString();
+ }
+
+ /**
+ * 获取注册的脚本
+ *
+ * @return java.lang.String
+ * @author lingting 2020-06-09 20:38:54
+ */
+ abstract protected String getSql();
+
+ /**
+ * 获取脚本id 即 方法名
+ *
+ * @return java.lang.String
+ * @author lingting 2020-06-09 20:39:30
+ */
+ abstract protected String getId();
+
+
+ protected String prepareValuesSqlForMysqlBatch(TableInfo tableInfo) {
+ return prepareValuesBuildSqlForMysqlBatch(tableInfo).toString();
+ }
+
+ protected StringBuilder prepareValuesBuildSqlForMysqlBatch(TableInfo tableInfo) {
+ final StringBuilder valueSql = new StringBuilder();
+ valueSql.append("");
+ valueSql.append("#{item.").append(tableInfo.getKeyProperty()).append("},");
+ tableInfo.getFieldList().forEach(x -> valueSql.append("#{item.").append(x.getProperty()).append("},"));
+ valueSql.delete(valueSql.length() - 1, valueSql.length());
+ valueSql.append("");
+ return valueSql;
+ }
+}
diff --git a/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/InsertIgnoreByBatch.java b/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/InsertIgnoreByBatch.java
new file mode 100644
index 00000000..2a5c03ae
--- /dev/null
+++ b/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/InsertIgnoreByBatch.java
@@ -0,0 +1,16 @@
+package com.hccake.extend.mybatis.plus.mysql.methods;
+
+/**
+ * @author lingting 2020/5/27 11:47
+ */
+public class InsertIgnoreByBatch extends BaseInsertBatch {
+ @Override
+ protected String getSql() {
+ return "";
+ }
+
+ @Override
+ protected String getId() {
+ return "insertIgnoreByBatch";
+ }
+}
diff --git a/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/InsertOrUpdateByBatch.java b/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/InsertOrUpdateByBatch.java
new file mode 100644
index 00000000..065ce6a1
--- /dev/null
+++ b/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/InsertOrUpdateByBatch.java
@@ -0,0 +1,42 @@
+package com.hccake.extend.mybatis.plus.mysql.methods;
+
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
+import com.hccake.extend.mybatis.plus.config.StaticConfig;
+
+/**
+ * @author lingting 2020/5/27 11:47
+ */
+public class InsertOrUpdateByBatch extends BaseInsertBatch {
+ @Override
+ protected String getSql() {
+ return "";
+ }
+
+ @Override
+ protected String getId() {
+ return "insertOrUpdateByBatch";
+ }
+
+ @Override
+ protected String prepareValuesSqlForMysqlBatch(TableInfo tableInfo) {
+ StringBuilder sql = super.prepareValuesBuildSqlForMysqlBatch(tableInfo);
+ sql.append(" ON DUPLICATE KEY UPDATE ");
+ StringBuilder ignore = new StringBuilder();
+
+ tableInfo.getFieldList().forEach(field -> {
+ // 默认忽略字段
+ if (!StaticConfig.UPDATE_IGNORE_FIELDS.contains(field.getProperty())) {
+ sql.append(field.getColumn()).append("=").append("VALUES(").append(field.getColumn()).append("),");
+ } else {
+ ignore.append(",").append(field.getColumn()).append("=").append("VALUES(").append(field.getColumn()).append(")");
+ }
+ });
+
+ // 删除最后一个多余的逗号
+ sql.delete(sql.length() - 1, sql.length());
+
+ // 配置不忽略全局配置字段时的sql部分
+ sql.append("").append(ignore).append("");
+ return sql.toString();
+ }
+}
diff --git a/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/InsertOrUpdateFieldByBatch.java b/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/InsertOrUpdateFieldByBatch.java
new file mode 100644
index 00000000..3cdc4893
--- /dev/null
+++ b/ballcat-extends/mybatis-plus-mysql-extend/src/main/java/com/hccake/extend/mybatis/plus/mysql/methods/InsertOrUpdateFieldByBatch.java
@@ -0,0 +1,41 @@
+package com.hccake.extend.mybatis.plus.mysql.methods;
+
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
+
+/**
+ * @author lingting 2020/5/27 11:47
+ */
+public class InsertOrUpdateFieldByBatch extends BaseInsertBatch {
+ private static final String SQL = "";
+
+ @Override
+ protected String getSql() {
+ return "";
+ }
+
+ @Override
+ protected String getId() {
+ return "insertOrUpdateFieldByBatch";
+ }
+
+ @Override
+ protected String prepareValuesSqlForMysqlBatch(TableInfo tableInfo) {
+ StringBuilder sql = super.prepareValuesBuildSqlForMysqlBatch(tableInfo);
+ sql.append(" ON DUPLICATE KEY UPDATE ")
+ // 如果模式为 不忽略设置的字段
+ .append("")
+ .append("")
+ .append("${item.name}=${item.val}")
+ .append("")
+ .append("");
+
+ // 如果模式为 忽略设置的字段
+ sql.append("")
+ .append("")
+ .append("${item}=VALUES(${item})")
+ .append("")
+ .append("");
+ return sql.toString();
+ }
+
+}