woody 1 éve
szülő
commit
a9fab28f1e

+ 17 - 2
framework-base/src/main/java/com/chelvc/framework/base/context/SessionContextHolder.java

@@ -131,7 +131,7 @@ public class SessionContextHolder implements ServletRequestListener {
     /**
      * 获取会话信息
      *
-     * @param required 会话是否必须
+     * @param required 是否必须
      * @return 会话信息
      */
     public static Session getSession(boolean required) {
@@ -184,7 +184,22 @@ public class SessionContextHolder implements ServletRequestListener {
      * @return 用户ID
      */
     public static Long getId() {
-        return ObjectUtils.ifNull(getSession(), Session::getId);
+        return getId(true);
+    }
+
+    /**
+     * 获取当前用户ID
+     *
+     * @param required 是否必须
+     * @return 用户ID
+     */
+    public static Long getId(boolean required) {
+        Session session = getSession(required);
+        Long id = ObjectUtils.ifNull(session, Session::getId);
+        if (required) {
+            return AssertUtils.nonnull(id, () -> "Session id must not be null");
+        }
+        return id;
     }
 
     /**

+ 8 - 1
framework-database/src/main/java/com/chelvc/framework/database/config/DatabaseConfigurer.java

@@ -5,6 +5,7 @@ import java.util.Comparator;
 import java.util.function.Supplier;
 
 import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
+import com.baomidou.mybatisplus.core.injector.ISqlInjector;
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
@@ -13,8 +14,9 @@ import com.chelvc.framework.common.function.Executor;
 import com.chelvc.framework.common.function.Handler;
 import com.chelvc.framework.common.function.Provider;
 import com.chelvc.framework.common.util.ObjectUtils;
-import com.chelvc.framework.database.entity.Transactor;
+import com.chelvc.framework.database.context.Transactor;
 import com.chelvc.framework.database.interceptor.DeletedExcludeHandler;
+import com.chelvc.framework.database.mapper.CustomerSqlInjector;
 import com.chelvc.framework.redis.context.RedisContextHolder;
 import lombok.NonNull;
 import lombok.RequiredArgsConstructor;
@@ -66,6 +68,11 @@ public class DatabaseConfigurer {
         };
     }
 
+    @Bean
+    public ISqlInjector sqlInjector() {
+        return new CustomerSqlInjector();
+    }
+
     @Bean
     @ConditionalOnClass(RedisContextHolder.class)
     public IdentifierGenerator identifierGenerator() {

+ 1 - 4
framework-database/src/main/java/com/chelvc/framework/database/context/DatabaseContextHolder.java

@@ -46,9 +46,6 @@ import com.chelvc.framework.database.config.DatabaseProperties;
 import com.chelvc.framework.database.entity.Creatable;
 import com.chelvc.framework.database.entity.Deletable;
 import com.chelvc.framework.database.entity.Entity;
-import com.chelvc.framework.database.entity.GetterContext;
-import com.chelvc.framework.database.entity.Transactor;
-import com.chelvc.framework.database.entity.UniqueContext;
 import com.chelvc.framework.database.entity.Updatable;
 import com.google.common.collect.Maps;
 import lombok.NonNull;
@@ -580,7 +577,7 @@ public final class DatabaseContextHolder {
      */
     public static void initializeEntityDefaultValues(@NonNull Entity<?> entity) {
         // 设置新增属性默认值
-        Long operator = SessionContextHolder.getId();
+        Long operator = SessionContextHolder.getId(false);
         if (operator != null && entity instanceof Creatable) {
             Creatable<?> creatable = (Creatable<?>) entity;
             if (creatable.getCreator() == null) {

+ 1 - 2
framework-database/src/main/java/com/chelvc/framework/database/entity/GetterContext.java → framework-database/src/main/java/com/chelvc/framework/database/context/GetterContext.java

@@ -1,4 +1,4 @@
-package com.chelvc.framework.database.entity;
+package com.chelvc.framework.database.context;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
@@ -10,7 +10,6 @@ import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache;
 import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
 import com.chelvc.framework.common.util.AssertUtils;
 import com.chelvc.framework.common.util.ObjectUtils;
-import com.chelvc.framework.database.context.DatabaseContextHolder;
 import lombok.Getter;
 import lombok.NonNull;
 

+ 1 - 1
framework-database/src/main/java/com/chelvc/framework/database/entity/Transactor.java → framework-database/src/main/java/com/chelvc/framework/database/context/Transactor.java

@@ -1,4 +1,4 @@
-package com.chelvc.framework.database.entity;
+package com.chelvc.framework.database.context;
 
 import java.util.function.Supplier;
 

+ 1 - 1
framework-database/src/main/java/com/chelvc/framework/database/entity/UniqueContext.java → framework-database/src/main/java/com/chelvc/framework/database/context/UniqueContext.java

@@ -1,4 +1,4 @@
-package com.chelvc.framework.database.entity;
+package com.chelvc.framework.database.context;
 
 import java.lang.reflect.Field;
 import java.util.List;

+ 4 - 2
framework-database/src/main/java/com/chelvc/framework/database/interceptor/DynamicDatasourceInterceptor.java

@@ -151,8 +151,9 @@ public class DynamicDatasourceInterceptor implements BeanDefinitionRegistryPostP
          * @throws Throwable 方法调用异常
          */
         @Around("@within(org.springframework.stereotype.Service) " +
+                "|| @within(org.apache.ibatis.annotations.Mapper) " +
                 "|| this(com.baomidou.mybatisplus.core.mapper.BaseMapper) " +
-                "|| @within(org.apache.ibatis.annotations.Mapper)")
+                "|| this(com.chelvc.framework.database.mapper.BasicMapper)")
         public Object routing(ProceedingJoinPoint point) throws Throwable {
             return super.routing(point);
         }
@@ -176,9 +177,10 @@ public class DynamicDatasourceInterceptor implements BeanDefinitionRegistryPostP
          * @throws Throwable 方法调用异常
          */
         @Around("@within(org.springframework.stereotype.Service) " +
+                "|| @within(org.apache.ibatis.annotations.Mapper) " +
                 "|| @within(org.apache.dubbo.config.annotation.DubboService) " +
                 "|| this(com.baomidou.mybatisplus.core.mapper.BaseMapper) " +
-                "|| @within(org.apache.ibatis.annotations.Mapper)")
+                "|| this(com.chelvc.framework.database.mapper.BasicMapper)")
         public Object routing(ProceedingJoinPoint point) throws Throwable {
             return super.routing(point);
         }

+ 1 - 1
framework-database/src/main/java/com/chelvc/framework/database/interceptor/PropertyUpdateInterceptor.java

@@ -10,8 +10,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.chelvc.framework.common.exception.ParameterInvalidException;
 import com.chelvc.framework.common.util.ObjectUtils;
 import com.chelvc.framework.database.context.DatabaseContextHolder;
+import com.chelvc.framework.database.context.UniqueContext;
 import com.chelvc.framework.database.entity.Entity;
-import com.chelvc.framework.database.entity.UniqueContext;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.ibatis.cache.CacheKey;
 import org.apache.ibatis.executor.Executor;

+ 19 - 0
framework-database/src/main/java/com/chelvc/framework/database/mapper/BasicMapper.java

@@ -0,0 +1,19 @@
+package com.chelvc.framework.database.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * 数据模型操作接口
+ *
+ * @author Woody
+ * @date 2024/2/27
+ */
+public interface BasicMapper<T> extends BaseMapper<T> {
+    /**
+     * 创建或忽略实体
+     *
+     * @param entity 实体对象实例
+     * @return true/false
+     */
+    boolean insertIgnore(T entity);
+}

+ 21 - 0
framework-database/src/main/java/com/chelvc/framework/database/mapper/CustomerSqlInjector.java

@@ -0,0 +1,21 @@
+package com.chelvc.framework.database.mapper;
+
+import java.util.List;
+
+import com.baomidou.mybatisplus.core.injector.AbstractMethod;
+import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
+
+/**
+ * 自定义SQL注入器实现
+ *
+ * @author Woody
+ * @date 2024/2/27
+ */
+public class CustomerSqlInjector extends DefaultSqlInjector {
+    @Override
+    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
+        List<AbstractMethod> methods = super.getMethodList(mapperClass);
+        methods.add(new InsertIgnoreMethod());
+        return methods;
+    }
+}

+ 58 - 0
framework-database/src/main/java/com/chelvc/framework/database/mapper/InsertIgnoreMethod.java

@@ -0,0 +1,58 @@
+package com.chelvc.framework.database.mapper;
+
+import java.util.List;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.core.enums.SqlMethod;
+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.chelvc.framework.common.util.StringUtils;
+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;
+
+/**
+ * 插入或忽略方法实现
+ *
+ * @author Woody
+ * @date 2024/2/27
+ */
+public class InsertIgnoreMethod extends AbstractMethod {
+    @Override
+    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
+        String keyColumn = null;
+        String keyProperty = null;
+        KeyGenerator keyGenerator;
+        if (StringUtils.isEmpty(tableInfo.getKeyProperty())) {
+            keyGenerator = new NoKeyGenerator();
+        } else if (tableInfo.getIdType() == IdType.AUTO) {
+            keyColumn = tableInfo.getKeyColumn();
+            keyProperty = tableInfo.getKeyProperty();
+            keyGenerator = new Jdbc3KeyGenerator();
+        } else if (tableInfo.getKeySequence() != null) {
+            keyColumn = tableInfo.getKeyColumn();
+            keyProperty = tableInfo.getKeyProperty();
+            String method = this.getMethod(SqlMethod.INSERT_ONE);
+            keyGenerator = TableInfoHelper.genKeyGenerator(method, tableInfo, this.builderAssistant);
+        } else {
+            keyGenerator = new NoKeyGenerator();
+        }
+        List<TableFieldInfo> fields = tableInfo.getFieldList();
+        String columns = tableInfo.getKeyInsertSqlColumn(false) +
+                this.filterTableFieldInfo(fields, null, TableFieldInfo::getInsertSqlColumn, EMPTY);
+        columns = columns.substring(0, columns.length() - 1);
+        String properties = tableInfo.getKeyInsertSqlProperty(null, false) +
+                this.filterTableFieldInfo(fields, null, i -> i.getInsertSqlProperty(null), EMPTY);
+        properties = properties.substring(0, properties.length() - 1);
+        String script = String.format("<script>\nINSERT IGNORE INTO %s (%s) VALUES (%s)\n</script>",
+                tableInfo.getTableName(), columns, properties);
+        SqlSource source = this.languageDriver.createSqlSource(this.configuration, script, modelClass);
+        return this.addInsertMappedStatement(
+                mapperClass, modelClass, "insertIgnore", source, keyGenerator, keyProperty, keyColumn
+        );
+    }
+}