|
@@ -1,60 +1,28 @@
|
|
|
package com.chelvc.framework.database.context;
|
|
|
|
|
|
-import java.io.InputStream;
|
|
|
-import java.io.Reader;
|
|
|
import java.lang.reflect.Modifier;
|
|
|
-import java.math.BigDecimal;
|
|
|
-import java.math.BigInteger;
|
|
|
import java.sql.Connection;
|
|
|
import java.sql.ResultSet;
|
|
|
import java.sql.SQLException;
|
|
|
import java.sql.Statement;
|
|
|
-import java.time.Instant;
|
|
|
-import java.time.LocalDate;
|
|
|
-import java.time.LocalDateTime;
|
|
|
-import java.time.LocalTime;
|
|
|
-import java.time.Month;
|
|
|
-import java.time.OffsetDateTime;
|
|
|
-import java.time.OffsetTime;
|
|
|
-import java.time.Year;
|
|
|
-import java.time.YearMonth;
|
|
|
-import java.time.ZonedDateTime;
|
|
|
-import java.time.chrono.JapaneseDate;
|
|
|
import java.util.Collection;
|
|
|
-import java.util.Date;
|
|
|
import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
import java.util.function.Function;
|
|
|
import java.util.function.Supplier;
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
-import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
|
|
-import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
|
|
-import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
|
|
|
-import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache;
|
|
|
-import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
|
|
-import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.chelvc.framework.base.context.ApplicationContextHolder;
|
|
|
import com.chelvc.framework.base.util.SpringUtils;
|
|
|
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.model.File;
|
|
|
-import com.chelvc.framework.common.model.Modification;
|
|
|
import com.chelvc.framework.common.model.Pagination;
|
|
|
import com.chelvc.framework.common.model.Paging;
|
|
|
-import com.chelvc.framework.common.model.Period;
|
|
|
-import com.chelvc.framework.common.model.Region;
|
|
|
-import com.chelvc.framework.common.util.AssertUtils;
|
|
|
import com.chelvc.framework.common.util.ObjectUtils;
|
|
|
-import com.chelvc.framework.common.util.StringUtils;
|
|
|
import com.chelvc.framework.database.crypto.DatabaseCipherHandler;
|
|
|
import com.chelvc.framework.database.entity.Entity;
|
|
|
-import com.google.common.collect.Maps;
|
|
|
import lombok.NonNull;
|
|
|
-import org.apache.ibatis.reflection.property.PropertyNamer;
|
|
|
-import org.apache.ibatis.type.TypeHandler;
|
|
|
import org.mybatis.spring.SqlSessionTemplate;
|
|
|
import org.springframework.context.ApplicationContext;
|
|
|
import org.springframework.dao.DuplicateKeyException;
|
|
@@ -66,16 +34,6 @@ import org.springframework.dao.DuplicateKeyException;
|
|
|
* @date 2024/1/30
|
|
|
*/
|
|
|
public final class DatabaseContextHolder {
|
|
|
- /**
|
|
|
- * 表名称/上下文映射表
|
|
|
- */
|
|
|
- private static final Map<String, TableContext> TABLE_CONTEXT_MAPPING = Maps.newConcurrentMap();
|
|
|
-
|
|
|
- /**
|
|
|
- * 类对象/类型处理器实例映射表
|
|
|
- */
|
|
|
- private static final Map<Class<?>, TypeHandler<?>> TYPE_HANDLER_MAPPING = Maps.newConcurrentMap();
|
|
|
-
|
|
|
/**
|
|
|
* 事务处理器
|
|
|
*/
|
|
@@ -264,143 +222,6 @@ public final class DatabaseContextHolder {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 去掉表、字段名称反引号
|
|
|
- *
|
|
|
- * @param name 表、字段名称
|
|
|
- * @return 表、字段名称
|
|
|
- */
|
|
|
- public static String unquote(String name) {
|
|
|
- return isQuoted(name) ? name.substring(1, name.length() - 1) : name;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 判断表、字段名称是否包含反引号
|
|
|
- *
|
|
|
- * @param name 表、字段名称
|
|
|
- * @return true/false
|
|
|
- */
|
|
|
- public static boolean isQuoted(String name) {
|
|
|
- return StringUtils.notEmpty(name) && name.charAt(0) == '`' && name.charAt(name.length() - 1) == '`';
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取表数据模型
|
|
|
- *
|
|
|
- * @param table 表名
|
|
|
- * @return 数据模型对象
|
|
|
- */
|
|
|
- public static Class<?> getTableModel(@NonNull String table) {
|
|
|
- return ObjectUtils.ifNull(getTableContext(table), TableContext::getModel);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取表上下文
|
|
|
- *
|
|
|
- * @param table 表名称
|
|
|
- * @return 表上下文
|
|
|
- */
|
|
|
- public static TableContext getTableContext(@NonNull String table) {
|
|
|
- String unquote = unquote(table);
|
|
|
- TableContext context = TABLE_CONTEXT_MAPPING.get(unquote);
|
|
|
- if (context == null) {
|
|
|
- context = TABLE_CONTEXT_MAPPING.computeIfAbsent(unquote, k -> {
|
|
|
- TableInfo info = TableInfoHelper.getTableInfo(table);
|
|
|
- if (info == null && isQuoted(table)) {
|
|
|
- info = TableInfoHelper.getTableInfo(unquote);
|
|
|
- }
|
|
|
- return ObjectUtils.ifNull(info, TableContext::new);
|
|
|
- });
|
|
|
- }
|
|
|
- return context;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取表字段上下文
|
|
|
- *
|
|
|
- * @param table 表名称
|
|
|
- * @param field 字段名称
|
|
|
- * @return 表字段上下文
|
|
|
- */
|
|
|
- public static TableFieldContext getTableFieldContext(@NonNull String table, @NonNull String field) {
|
|
|
- return ObjectUtils.ifNull(getTableContext(table), context -> context.getFieldContext(field));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取TypeHandler实例
|
|
|
- *
|
|
|
- * @param clazz TypeHandler对象类型
|
|
|
- * @param <T> TypeHandler类型
|
|
|
- * @return TypeHandler实例
|
|
|
- */
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
- public static <T extends TypeHandler<?>> T getTypeHandler(@NonNull Class<T> clazz) {
|
|
|
- T handler = (T) TYPE_HANDLER_MAPPING.get(clazz);
|
|
|
- if (handler == null) {
|
|
|
- handler = (T) TYPE_HANDLER_MAPPING.computeIfAbsent(clazz, k -> ObjectUtils.instance(clazz));
|
|
|
- }
|
|
|
- return handler;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 将Getter方法转换成字段名称
|
|
|
- *
|
|
|
- * @param getter Getter方法
|
|
|
- * @return 字段名称
|
|
|
- */
|
|
|
- public static String getter2column(@NonNull SFunction<?, ?> getter) {
|
|
|
- SerializedLambda lambda = LambdaUtils.resolve(getter);
|
|
|
- String property = PropertyNamer.methodToProperty(lambda.getImplMethodName());
|
|
|
- return property2column(lambda.getInstantiatedType(), property);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 将Getter方法转换成属性名称
|
|
|
- *
|
|
|
- * @param getter Getter方法
|
|
|
- * @return 属性名称
|
|
|
- */
|
|
|
- public static String getter2property(@NonNull SFunction<?, ?> getter) {
|
|
|
- SerializedLambda lambda = LambdaUtils.resolve(getter);
|
|
|
- return PropertyNamer.methodToProperty(lambda.getImplMethodName());
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 将属性名转换成字段名称
|
|
|
- *
|
|
|
- * @param clazz 实体对象
|
|
|
- * @param property 属性名称
|
|
|
- * @return 字段名称
|
|
|
- */
|
|
|
- public static String property2column(@NonNull Class<?> clazz, @NonNull String property) {
|
|
|
- Map<String, ColumnCache> columns = LambdaUtils.getColumnMap(clazz);
|
|
|
- ColumnCache column = ObjectUtils.ifNull(columns, cs -> cs.get(LambdaUtils.formatKey(property)));
|
|
|
- AssertUtils.nonnull(column, () -> "Column not found for property: " + clazz.getName() + "." + property);
|
|
|
- return column.getColumn();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 判断对象类型处理器是否已注册
|
|
|
- *
|
|
|
- * @param type 对象类型
|
|
|
- * @return true/false
|
|
|
- */
|
|
|
- public static boolean isTypeHandlerRegistered(Class<?> type) {
|
|
|
- return type == byte.class || type == Byte.class || type == byte[].class || type == Byte[].class
|
|
|
- || type == char.class || type == Character.class || type == short.class || type == Short.class
|
|
|
- || type == int.class || type == Integer.class || type == long.class || type == Long.class
|
|
|
- || type == float.class || type == Float.class || type == double.class || type == Double.class
|
|
|
- || type == boolean.class || type == Boolean.class || type == String.class || type == Object.class
|
|
|
- || type == BigInteger.class || type == BigDecimal.class || type == Reader.class
|
|
|
- || type == InputStream.class || type == Date.class || type == java.sql.Date.class
|
|
|
- || type == java.sql.Time.class || type == java.sql.Timestamp.class || type == Instant.class
|
|
|
- || type == LocalDate.class || type == LocalTime.class || type == LocalDateTime.class
|
|
|
- || type == OffsetTime.class || type == OffsetDateTime.class || type == ZonedDateTime.class
|
|
|
- || type == Year.class || type == Month.class || type == YearMonth.class || type == JapaneseDate.class
|
|
|
- || (type != null && Enum.class.isAssignableFrom(type)) || type == File.class || type == Period.class
|
|
|
- || type == Region.class || type == Modification.class;
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 根据包名查找数据模型对象
|
|
|
*
|