![JAR search and dependency download from the Maven repository](/logo.png)
org.zodiac.mybatisplus.binding.parser.ParserCache Maven / Gradle / Ivy
package org.zodiac.mybatisplus.binding.parser;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.NonNull;
import org.zodiac.commons.util.ArrayUtil;
import org.zodiac.commons.util.BeanUtil;
import org.zodiac.commons.util.Colls;
import org.zodiac.core.data.annotation.ProtectField;
import org.zodiac.core.exception.IllegalUsageException;
import org.zodiac.mybatisplus.binding.annotation.*;
import org.zodiac.mybatisplus.binding.cache.BindingCacheManager;
import org.zodiac.mybatisplus.binding.query.BindQuery;
import org.zodiac.mybatisplus.binding.query.dynamic.AnnoJoiner;
import org.zodiac.sdk.toolkit.util.lang.StrUtil;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
/**
* 对象中的绑定注解 缓存管理类。
*
*/
@SuppressWarnings({"rawtypes"})
public class ParserCache {
private static final Logger log = LoggerFactory.getLogger(ParserCache.class);
/**
* VO类-绑定注解缓存
*/
private static final Map, BindAnnotationGroup> allVoBindAnnotationCacheMap = new ConcurrentHashMap<>();
/**
* dto类-BindQuery注解的缓存
*/
private static final Map> dtoClassBindQueryCacheMap = new ConcurrentHashMap<>();
/**
* 保护字段缓存
*/
private static final Map> PROTECT_FIELD_MAP = new ConcurrentHashMap<>();
/**
* 用于查询注解是否是Bind相关注解
*/
private static final Set> BIND_ANNOTATION_SET = new HashSet<>(Arrays.asList(BindDict.class,
BindField.class, BindFieldList.class, BindEntity.class, BindEntityList.class, BindCount.class));
private ParserCache() {
super();
}
/**
* 获取指定class对应的Bind相关注解。
*
* @param voClass vo类型对象
* @return 绑定注解的归类分组对象
*/
public static BindAnnotationGroup getBindAnnotationGroup(Class> voClass) {
return allVoBindAnnotationCacheMap.computeIfAbsent(voClass, k -> {
/*获取注解并缓存*/
BindAnnotationGroup group = new BindAnnotationGroup();
/*获取当前VO的所有字段*/
List fields = BeanUtil.extractAllFields(voClass);
if (Colls.notEmptyColl(fields)) {
/*遍历属性*/
for (Field field : fields) {
/*获取当前字段所有注解*/
Annotation[] annotations = field.getDeclaredAnnotations();
if (ArrayUtil.emptyArray(annotations)) {
continue;
}
/*字段名称*/
String fieldName = field.getName();
/*字段类型*/
Class> setterObjClazz = field.getType();
/*如果是集合,获取其泛型参数class*/
if (setterObjClazz.equals(java.util.List.class)
|| setterObjClazz.equals(java.util.Collection.class)) {
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType)genericType;
setterObjClazz = (Class>)pt.getActualTypeArguments()[0];
}
}
for (Annotation annotation : annotations) {
/*是bind相关注解则添加*/
if (BIND_ANNOTATION_SET.contains(annotation.annotationType())) {
group.addBindAnnotation(fieldName, setterObjClazz, annotation);
}
}
}
}
/*返回归类后的注解对象*/
return group;
});
}
/**
* 取得“删除”列。
*
* @param table 表名
* @return 列名
*/
public static String getDeletedColumn(String table) {
PropInfo propInfo = BindingCacheManager.getPropInfoByTable(table);
if (propInfo != null) {
return propInfo.getDeletedColumn();
}
log.debug("未能识别到逻辑删除字段, table={}", table);
return null;
}
/**
* 获取entity对应的表名。
*
* @param entityClass 实体类型对象
* @return 表名称
*/
public static String getEntityTableName(Class> entityClass) {
EntityInfoCache entityInfoCache = BindingCacheManager.getEntityInfoByClass(entityClass);
if (entityInfoCache != null) {
return entityInfoCache.getTableName();
} else {
TableName tableNameAnno = AnnotationUtils.findAnnotation(entityClass, TableName.class);
if (tableNameAnno != null && StrUtil.isNotBlank(tableNameAnno.value())) {
return tableNameAnno.value();
} else {
return StrUtil.toSnakeCase(entityClass.getSimpleName());
}
}
}
/**
* 根据类的entity类名获取EntityClass(已废弃) 请调用{@link BindingCacheManager#getEntityClassBySimpleName(String)}}。
*
* @param className 类名
* @return 类型对象
*/
@Deprecated
public static Class> getEntityClassByClassName(String className) {
return BindingCacheManager.getEntityClassBySimpleName(className);
}
/**
* 根据entity类获取mapper实例。
*
* @param entityClass 实体类型
* @return {@link BaseMapper}对象
*/
public static BaseMapper getMapperInstance(Class> entityClass) {
BaseMapper mapper = BindingCacheManager.getMapperByClass(entityClass);
if (mapper == null) {
throw new IllegalUsageException("未找到 " + entityClass.getName() + " 的Mapper定义!");
}
return mapper;
}
/**
* 当前DTO是否有Join绑定。
*
* @param DTO类型
* @param dto dto对象
* @param fieldNameSet 有值属性集合
* @return 是否连接表
*/
public static boolean hasJoinTable(DTO dto, Collection fieldNameSet) {
List annoList = getBindQueryAnnos(dto.getClass());
if (Colls.notEmptyColl(annoList)) {
for (AnnoJoiner anno : annoList) {
if (StrUtil.isNotBlank(anno.getJoin()) && Colls.containsInstance(fieldNameSet, anno.getFieldName())) {
return true;
}
}
}
return false;
}
/**
* 获取dto类中定义的BindQuery注解。
*
* @param dtoClass DTO类型
* @return 注解连接器列表
*/
public static List getBindQueryAnnos(Class> dtoClass) {
String dtoClassName = dtoClass.getName();
if (dtoClassBindQueryCacheMap.containsKey(dtoClassName)) {
return dtoClassBindQueryCacheMap.get(dtoClassName);
}
/*初始化。*/
List annos = new ArrayList<>();
AtomicInteger index = new AtomicInteger(1);
Map joinOn2Alias = new HashMap<>(8);
/*构建AnnoJoiner。*/
BiConsumer buildAnnoJoiner = (field, query) -> {
AnnoJoiner annoJoiner = new AnnoJoiner(field, query);
/*关联对象,设置别名。*/
if (StrUtil.isNotBlank(annoJoiner.getJoin())) {
String key = annoJoiner.getJoin() + ":" + annoJoiner.getCondition();
String alias = joinOn2Alias.get(key);
if (alias == null) {
alias = "r" + index.getAndIncrement();
annoJoiner.setAlias(alias);
joinOn2Alias.put(key, alias);
} else {
annoJoiner.setAlias(alias);
}
annoJoiner.parse();
}
annos.add(annoJoiner);
};
for (Field field : BeanUtil.extractFields(dtoClass, BindQuery.class)) {
BindQuery query = field.getAnnotation(BindQuery.class);
/*不可能为null。*/
if (query.ignore()) {
continue;
}
buildAnnoJoiner.accept(field, query);
}
for (Field field : BeanUtil.extractFields(dtoClass, BindQuery.List.class)) {
BindQuery.List queryList = field.getAnnotation(BindQuery.List.class);
for (BindQuery bindQuery : queryList.value()) {
buildAnnoJoiner.accept(field, bindQuery);
}
}
dtoClassBindQueryCacheMap.put(dtoClassName, annos);
return annos;
}
/**
* 获取注解joiner。
*
* @param dtoClass DTO类型
* @param fieldNames 字段名列表
* @return 注解连接器列表
*/
public static List getAnnoJoiners(Class> dtoClass, Collection fieldNames) {
List annoList = getBindQueryAnnos(dtoClass);
/*不过滤 返回全部*/
if (fieldNames == null) {
return annoList;
}
/*过滤*/
if (Colls.notEmptyColl(annoList)) {
List matchedAnnoList = new ArrayList<>();
for (AnnoJoiner anno : annoList) {
if (fieldNames.contains(anno.getFieldName())) {
matchedAnnoList.add(anno);
}
}
return matchedAnnoList;
}
return Collections.emptyList();
}
/**
* 获取该类保护字段属性名列表。
*
* @param clazz 类型
* @return 属性名列表
*/
@NonNull
public static List getProtectFieldList(@NonNull Class> clazz) {
return PROTECT_FIELD_MAP.computeIfAbsent(clazz.getName(), k -> {
List protectFieldList = new ArrayList<>(4);
for (Field field : BeanUtil.extractFields(clazz, ProtectField.class)) {
if (!field.getType().isAssignableFrom(String.class)) {
log.error("`@ProtectField` 仅支持 String 类型字段。");
continue;
}
protectFieldList.add(field.getName());
}
return protectFieldList.isEmpty() ? Collections.emptyList() : protectFieldList;
});
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy