diff --git a/mongo-plus-annotation/src/main/java/com/anwen/mongo/annotation/collection/CollectionLogic.java b/mongo-plus-annotation/src/main/java/com/anwen/mongo/annotation/collection/CollectionLogic.java new file mode 100644 index 0000000000000000000000000000000000000000..083a399765a35a6b0c6bd0959938efef7b14e422 --- /dev/null +++ b/mongo-plus-annotation/src/main/java/com/anwen/mongo/annotation/collection/CollectionLogic.java @@ -0,0 +1,35 @@ +package com.anwen.mongo.annotation.collection; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 表字段逻辑处理注解(逻辑删除) + * + * @author loser + * @date 2024/4/28 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE}) +public @interface CollectionLogic { + + /** + * 开启全局配置 并忽略该文档(任意补充在某一个字段上,建议跟@ID 相同) + */ + boolean close() default false; + + /** + * 默认逻辑未删除值(该值可无、会自动获取全局配置) + */ + String value() default ""; + + /** + * 默认逻辑删除值(该值可无、会自动获取全局配置) + */ + String delval() default ""; + +} diff --git a/mongo-plus-boot-starter/src/main/java/com/anwen/mongo/config/MongoPlusAutoConfiguration.java b/mongo-plus-boot-starter/src/main/java/com/anwen/mongo/config/MongoPlusAutoConfiguration.java index 44afe6ffe933f03ad918c49d626461df78e961d4..22e9e9b9a286cbcad006ca868d919364599bac2b 100644 --- a/mongo-plus-boot-starter/src/main/java/com/anwen/mongo/config/MongoPlusAutoConfiguration.java +++ b/mongo-plus-boot-starter/src/main/java/com/anwen/mongo/config/MongoPlusAutoConfiguration.java @@ -1,6 +1,7 @@ package com.anwen.mongo.config; import com.anwen.mongo.annotation.collection.CollectionName; +import com.anwen.mongo.cache.global.ExecutorReplacerCache; import com.anwen.mongo.cache.global.HandlerCache; import com.anwen.mongo.cache.global.InterceptorCache; import com.anwen.mongo.cache.global.ListenerCache; @@ -21,6 +22,8 @@ import com.anwen.mongo.manager.MongoPlusClient; import com.anwen.mongo.mapper.BaseMapper; import com.anwen.mongo.property.MongoDBCollectionProperty; import com.anwen.mongo.property.MongoDBLogProperty; +import com.anwen.mongo.property.MongoLogicDelProperty; +import com.anwen.mongo.replacer.Replacer; import com.anwen.mongo.service.IService; import com.anwen.mongo.service.impl.ServiceImpl; import com.anwen.mongo.strategy.convert.ConversionService; @@ -36,11 +39,18 @@ import org.springframework.context.ApplicationContext; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; /** * MongoPlus自动注入配置 + * * @author JiaChaoYang **/ @EnableConfigurationProperties(MongoDBLogProperty.class) @@ -54,33 +64,45 @@ public class MongoPlusAutoConfiguration implements InitializingBean { private final MongoDBCollectionProperty mongodbCollectionProperty; + private final MongoLogicDelProperty mongoLogicDelProperty; + private final CollectionNameConvert collectionNameConvert; private final BaseMapper baseMapper; Log log = LogFactory.getLog(MongoPlusAutoConfiguration.class); - public MongoPlusAutoConfiguration(MongoDBLogProperty mongodbLogProperty, MongoDBCollectionProperty mongodbCollectionProperty, BaseMapper baseMapper, MongoPlusClient mongoPlusClient, ApplicationContext applicationContext, CollectionNameConvert collectionNameConvert) { + public MongoPlusAutoConfiguration(MongoDBLogProperty mongodbLogProperty, MongoDBCollectionProperty mongodbCollectionProperty, MongoLogicDelProperty mongoLogicDelProperty, BaseMapper baseMapper, MongoPlusClient mongoPlusClient, ApplicationContext applicationContext, CollectionNameConvert collectionNameConvert) { this.mongoPlusClient = mongoPlusClient; this.applicationContext = applicationContext; this.mongodbLogProperty = mongodbLogProperty; this.mongodbCollectionProperty = mongodbCollectionProperty; + this.mongoLogicDelProperty = mongoLogicDelProperty; this.collectionNameConvert = collectionNameConvert; setConversion(); setMetaObjectHandler(); setDocumentHandler(); setListener(); setInterceptor(); + setReplacer(); this.baseMapper = baseMapper; } @Override public void afterPropertiesSet() { - applicationContext.getBeansOfType(IService.class) - .values() - .stream() - .filter(s -> s instanceof ServiceImpl) - .forEach(s -> setExecute((ServiceImpl) s, s.getGenericityClass())); + Collection values = applicationContext.getBeansOfType(IService.class).values(); + values.forEach(s -> setExecute((ServiceImpl) s, s.getGenericityClass())); + setLogicFiled(values.stream().map(IService::getGenericityClass).toArray(Class[]::new)); + } + + /** + * 配置逻辑删除 + * + * @param collectionClasses 需要进行逻辑删除的 collection class 集合 + * @author loser + */ + private void setLogicFiled(Class... collectionClasses) { + Configuration.builder().logic(this.mongoLogicDelProperty).setLogicFiled(collectionClasses); } private void setExecute(ServiceImpl serviceImpl, Class clazz) { @@ -109,12 +131,12 @@ public class MongoPlusAutoConfiguration implements InitializingBean { ConnectMongoDB connectMongodb = new ConnectMongoDB(mongoPlusClient.getMongoClient(), db, finalCollectionName); MongoDatabase mongoDatabase = mongoPlusClient.getMongoClient().getDatabase(db); mongoDatabaseList.add(mongoDatabase); - if (Objects.equals(db, finalDataBaseName[0])){ + if (Objects.equals(db, finalDataBaseName[0])) { MongoCollection collection = connectMongodb.open(mongoDatabase); - collectionManager.setCollectionMap(finalCollectionName,collection); + collectionManager.setCollectionMap(finalCollectionName, collection); } - mongoPlusClient.getCollectionManagerMap().put(DataSourceConstant.DEFAULT_DATASOURCE,new HashMap(){{ - put(db,collectionManager); + mongoPlusClient.getCollectionManagerMap().put(DataSourceConstant.DEFAULT_DATASOURCE, new HashMap() {{ + put(db, collectionManager); }}); }); mongoPlusClient.setMongoDatabase(mongoDatabaseList); @@ -126,24 +148,25 @@ public class MongoPlusAutoConfiguration implements InitializingBean { /** * 从Bean中拿到转换器 + * * @author JiaChaoYang * @date 2023/10/19 12:49 - */ + */ @SuppressWarnings("unchecked") - private void setConversion(){ + private void setConversion() { applicationContext.getBeansOfType(ConversionStrategy.class).values().forEach(conversionStrategy -> { try { Type[] genericInterfaces = conversionStrategy.getClass().getGenericInterfaces(); for (Type anInterface : genericInterfaces) { ParameterizedType parameterizedType = (ParameterizedType) anInterface; - if (parameterizedType.getRawType().equals(ConversionStrategy.class)){ + if (parameterizedType.getRawType().equals(ConversionStrategy.class)) { Class clazz = (Class) parameterizedType.getActualTypeArguments()[0]; - ConversionService.appendConversion(clazz,conversionStrategy); + ConversionService.appendConversion(clazz, conversionStrategy); break; } } - }catch (Exception e){ - log.error("Unknown converter type",e); + } catch (Exception e) { + log.error("Unknown converter type", e); throw new MongoPlusConvertException("Unknown converter type"); } }); @@ -151,48 +174,52 @@ public class MongoPlusAutoConfiguration implements InitializingBean { /** * 从Bean中拿到自动填充策略 + * * @author JiaChaoYang * @date 2023/11/21 12:18 - */ - private void setMetaObjectHandler(){ + */ + private void setMetaObjectHandler() { applicationContext.getBeansOfType(MetaObjectHandler.class).values().forEach(metaObjectHandler -> HandlerCache.metaObjectHandler = metaObjectHandler); } /** * 从Bean中拿到Document的处理器 + * * @author JiaChaoYang * @date 2023/11/23 12:58 - */ - private void setDocumentHandler(){ + */ + private void setDocumentHandler() { applicationContext.getBeansOfType(DocumentHandler.class).values().forEach(documentHandler -> HandlerCache.documentHandler = documentHandler); } /** * 从Bean中拿到监听器 + * * @author JiaChaoYang * @date 2023/11/22 18:39 - */ - private void setListener(){ - List listeners = new ArrayList<>(); - if (mongodbLogProperty.getLog()){ + */ + private void setListener() { + List listeners = ListenerCache.listeners; + if (mongodbLogProperty.getLog()) { listeners.add(new LogListener()); } - if (mongodbCollectionProperty.getBlockAttackInner()){ + if (mongodbCollectionProperty.getBlockAttackInner()) { listeners.add(new BlockAttackInnerListener()); } Collection listenerCollection = applicationContext.getBeansOfType(Listener.class).values(); - if (CollUtil.isNotEmpty(listenerCollection)){ + if (CollUtil.isNotEmpty(listenerCollection)) { listeners.addAll(listenerCollection); } - ListenerCache.listeners = listeners.stream().sorted(Comparator.comparingInt(Listener::getOrder)).collect(Collectors.toList()); + ListenerCache.sorted(); } /** * 从Bean中拿到拦截器 + * * @author JiaChaoYang * @date 2024/3/17 0:30 - */ - private void setInterceptor(){ + */ + private void setInterceptor() { Collection interceptorCollection = applicationContext.getBeansOfType(Interceptor.class).values(); if (CollUtil.isNotEmpty(interceptorCollection)) { interceptorCollection = interceptorCollection.stream().sorted(Comparator.comparing(Interceptor::order)).collect(Collectors.toList()); @@ -200,4 +227,17 @@ public class MongoPlusAutoConfiguration implements InitializingBean { InterceptorCache.interceptors = new ArrayList<>(interceptorCollection); } + /** + * 从bean 容器中获取替换器 + * + * @author loser + */ + private void setReplacer() { + Collection replacers = applicationContext.getBeansOfType(Replacer.class).values(); + if (CollUtil.isNotEmpty(replacers)) { + replacers = replacers.stream().sorted(Comparator.comparing(Replacer::order)).collect(Collectors.toList()); + } + ExecutorReplacerCache.replacers = new ArrayList<>(replacers); + } + } diff --git a/mongo-plus-boot-starter/src/main/java/com/anwen/mongo/property/MongoLogicDelProperty.java b/mongo-plus-boot-starter/src/main/java/com/anwen/mongo/property/MongoLogicDelProperty.java new file mode 100644 index 0000000000000000000000000000000000000000..bc061a93e0458d876f50a221190715da4927f3f6 --- /dev/null +++ b/mongo-plus-boot-starter/src/main/java/com/anwen/mongo/property/MongoLogicDelProperty.java @@ -0,0 +1,15 @@ +package com.anwen.mongo.property; + +import com.anwen.mongo.model.LogicProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * 逻辑删除配置 + * + * @author loser + * @date 2024/4/28 + */ +@ConfigurationProperties(prefix = "mongo-plus.configuration.logic") +public class MongoLogicDelProperty extends LogicProperty { + +} diff --git a/mongo-plus-boot-starter/src/main/resources/META-INF/spring.factories b/mongo-plus-boot-starter/src/main/resources/META-INF/spring.factories index 2d5f7d3fb1d2f11788c84a20cbe0a9bca36a8343..fd8a5e4e91e5a910b90d46fd3c910b91a10b0737 100644 --- a/mongo-plus-boot-starter/src/main/resources/META-INF/spring.factories +++ b/mongo-plus-boot-starter/src/main/resources/META-INF/spring.factories @@ -5,4 +5,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.anwen.mongo.property.MongoSpringProperty,\ com.anwen.mongo.property.MongoDBFieldProperty,\ com.anwen.mongo.transactional.MongoTransactionManagerAutoConfiguration,\ - com.anwen.mongo.config.MongoPropertyConfiguration + com.anwen.mongo.config.MongoPropertyConfiguration,\ + com.anwen.mongo.property.MongoLogicDelProperty diff --git a/mongo-plus-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/mongo-plus-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index cd843ccf9d387a48794b37560072ea352aa5b391..86368e241f133513975673e3fd1334c6dae001d3 100644 --- a/mongo-plus-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/mongo-plus-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -4,4 +4,5 @@ com.anwen.mongo.config.OverrideMongoConfiguration com.anwen.mongo.property.MongoSpringProperty com.anwen.mongo.property.MongoDBFieldProperty com.anwen.mongo.transactional.MongoTransactionManagerAutoConfiguration -com.anwen.mongo.config.MongoPropertyConfiguration \ No newline at end of file +com.anwen.mongo.config.MongoPropertyConfiguration +com.anwen.mongo.property.MongoLogicDelProperty \ No newline at end of file diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/cache/global/CollectionLogicDeleteCache.java b/mongo-plus-core/src/main/java/com/anwen/mongo/cache/global/CollectionLogicDeleteCache.java new file mode 100644 index 0000000000000000000000000000000000000000..ff6727db9e70b64bd0b5219ff17eff7c717d2a5b --- /dev/null +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/cache/global/CollectionLogicDeleteCache.java @@ -0,0 +1,49 @@ +package com.anwen.mongo.cache.global; + +import com.anwen.mongo.model.LogicDeleteResult; +import com.anwen.mongo.model.LogicProperty; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 全局逻辑删除基础信息缓存 + * + * @author loser + * @date 2024/4/29 + */ +public class CollectionLogicDeleteCache { + + /** + * 是否开启逻辑删除功能 + */ + public static Boolean open = false; + + /** + * 逻辑删除配置 + */ + public static LogicProperty logicProperty = new LogicProperty(); + + /** + * 目标文档对应的逻辑删除字段 + */ + public static final Map, LogicDeleteResult> logicDeleteResultHashMap = new HashMap<>(); + + /** + * 存储 mongo 连接对象关联的 实体 {"mongo连接fullName":"mongo集合实体class"} + */ + public static final Map> fullNameMap = new ConcurrentHashMap<>(); + + /** + * mongo 连接对象关联的 实体(处理直接通过 BaseMapper 操作的 class) + * + * @param fullName mongo 连接 fullName + * @param clazz 实体 + */ + public static void mapperClassByCollection(String fullName, Class clazz) { + if (!fullNameMap.containsKey(fullName)) { + fullNameMap.put(fullName, clazz); + } + } +} diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/cache/global/ExecutorReplacerCache.java b/mongo-plus-core/src/main/java/com/anwen/mongo/cache/global/ExecutorReplacerCache.java new file mode 100644 index 0000000000000000000000000000000000000000..4d52f8d1f0500b19a42ff2d5c4ee3461f3efdcd3 --- /dev/null +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/cache/global/ExecutorReplacerCache.java @@ -0,0 +1,24 @@ +package com.anwen.mongo.cache.global; + +import com.anwen.mongo.replacer.Replacer; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +/** + * executor 替换器 + * + * @author loser + * @date 2024/4/30 + */ +public class ExecutorReplacerCache { + + public static List replacers = new ArrayList<>(); + + public static void sorted() { + replacers = replacers.stream().sorted(Comparator.comparing(Replacer::order)).collect(Collectors.toList()); + } + +} diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/cache/global/InterceptorCache.java b/mongo-plus-core/src/main/java/com/anwen/mongo/cache/global/InterceptorCache.java index 7f1a6058fde6d62eab49eb9a5a47b2478e2255ef..4ac3c9f2fa8e0a541b9b63bfcc3792316417e909 100644 --- a/mongo-plus-core/src/main/java/com/anwen/mongo/cache/global/InterceptorCache.java +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/cache/global/InterceptorCache.java @@ -3,7 +3,9 @@ package com.anwen.mongo.cache.global; import com.anwen.mongo.interceptor.Interceptor; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import java.util.stream.Collectors; /** * 拦截器 @@ -14,4 +16,8 @@ public class InterceptorCache { public static List interceptors = new ArrayList<>(); + public static void sorted() { + interceptors = interceptors.stream().sorted(Comparator.comparing(Interceptor::order)).collect(Collectors.toList()); + } + } diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/cache/global/ListenerCache.java b/mongo-plus-core/src/main/java/com/anwen/mongo/cache/global/ListenerCache.java index f8cb392945026a472a3ad2aa98e799e7593d3127..c2ab959ede4050abf9346b31eba8209e0d5cc399 100644 --- a/mongo-plus-core/src/main/java/com/anwen/mongo/cache/global/ListenerCache.java +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/cache/global/ListenerCache.java @@ -3,7 +3,9 @@ package com.anwen.mongo.cache.global; import com.anwen.mongo.listener.Listener; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import java.util.stream.Collectors; /** * @author JiaChaoYang @@ -15,4 +17,8 @@ public class ListenerCache { public static List listeners = new ArrayList<>(); + public static void sorted() { + listeners = listeners.stream().sorted(Comparator.comparing(Listener::getOrder)).collect(Collectors.toList()); + } + } diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/config/Configuration.java b/mongo-plus-core/src/main/java/com/anwen/mongo/config/Configuration.java index 73649eabbc3a8d6645031000aefd4af78dbe7c1e..ed8c048e78195ac2ebb23bc61e119a576a567eab 100644 --- a/mongo-plus-core/src/main/java/com/anwen/mongo/config/Configuration.java +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/config/Configuration.java @@ -1,5 +1,9 @@ package com.anwen.mongo.config; +import com.anwen.mongo.annotation.collection.CollectionField; +import com.anwen.mongo.annotation.collection.CollectionLogic; +import com.anwen.mongo.cache.global.CollectionLogicDeleteCache; +import com.anwen.mongo.cache.global.ExecutorReplacerCache; import com.anwen.mongo.cache.global.HandlerCache; import com.anwen.mongo.cache.global.InterceptorCache; import com.anwen.mongo.cache.global.ListenerCache; @@ -7,6 +11,7 @@ import com.anwen.mongo.cache.global.MongoPlusClientCache; import com.anwen.mongo.conn.CollectionManager; import com.anwen.mongo.constant.DataSourceConstant; import com.anwen.mongo.convert.CollectionNameConvert; +import com.anwen.mongo.domain.InitMongoLogicException; import com.anwen.mongo.domain.InitMongoPlusException; import com.anwen.mongo.enums.CollectionNameConvertEnum; import com.anwen.mongo.factory.MongoClientFactory; @@ -17,6 +22,10 @@ import com.anwen.mongo.listener.BaseListener; import com.anwen.mongo.listener.Listener; import com.anwen.mongo.listener.business.BlockAttackInnerListener; import com.anwen.mongo.listener.business.LogListener; +import com.anwen.mongo.logic.AnnotationHandler; +import com.anwen.mongo.logic.interceptor.CollectionLogiceInterceptor; +import com.anwen.mongo.logic.interceptor.LogicAutoFillInterceptor; +import com.anwen.mongo.logic.replacer.LogicRemoveReplacer; import com.anwen.mongo.manager.MongoPlusClient; import com.anwen.mongo.mapper.BaseMapper; import com.anwen.mongo.mapper.DefaultBaseMapperImpl; @@ -24,6 +33,10 @@ import com.anwen.mongo.mapper.MongoPlusMapMapper; import com.anwen.mongo.mapping.MappingMongoConverter; import com.anwen.mongo.mapping.MongoConverter; import com.anwen.mongo.model.BaseProperty; +import com.anwen.mongo.model.ClassAnnotationFiled; +import com.anwen.mongo.model.LogicDeleteResult; +import com.anwen.mongo.model.LogicProperty; +import com.anwen.mongo.replacer.Replacer; import com.anwen.mongo.strategy.convert.ConversionService; import com.anwen.mongo.strategy.convert.ConversionStrategy; import com.anwen.mongo.toolkit.MongoCollectionUtils; @@ -35,10 +48,17 @@ import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoDatabase; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -51,50 +71,63 @@ public class Configuration { /** * MongoDB连接URL + * * @author JiaChaoYang * @date 2024/3/19 18:25 - */ + */ private String url; /** * 属性配置文件,url和baseProperty存在一个即可 + * * @author JiaChaoYang * @date 2024/3/19 18:25 - */ + */ private BaseProperty baseProperty = new BaseProperty(); + /** + * 逻辑删除配置 + * + * @author loser + */ + private LogicProperty logicProperty = new LogicProperty(); + /** * 集合名称获取策略 + * * @author JiaChaoYang * @date 2024/3/19 18:25 - */ + */ private CollectionNameConvert collectionNameConvert = MongoCollectionUtils.build(CollectionNameConvertEnum.ALL_CHAR_LOWERCASE); /** * 获取一个空的Configuration + * * @author JiaChaoYang * @date 2024/3/19 18:26 - */ - public static Configuration builder(){ + */ + public static Configuration builder() { return new Configuration(); } /** * 设置url + * * @author JiaChaoYang * @date 2024/3/19 18:26 - */ - public Configuration connection(String url){ + */ + public Configuration connection(String url) { this.url = url; return this; } /** * 设置属性配置文件 + * * @author JiaChaoYang * @date 2024/3/19 18:26 - */ - public Configuration connection(BaseProperty baseProperty){ + */ + public Configuration connection(BaseProperty baseProperty) { this.baseProperty = baseProperty; UrlJoint urlJoint = new UrlJoint(baseProperty); return connection(urlJoint.jointMongoUrl()); @@ -102,43 +135,46 @@ public class Configuration { /** * 配置数据库 + * * @param database 数据库 多个库使用逗号隔开 * @return com.anwen.mongo.config.Configuration * @author JiaChaoYang * @date 2024/3/19 19:08 - */ - public Configuration database(String database){ + */ + public Configuration database(String database) { this.baseProperty.setDatabase(database); return this; } /** * 设置集合名称获取策略 + * * @author JiaChaoYang * @date 2024/3/19 18:27 - */ - public Configuration collectionNameConvert(CollectionNameConvertEnum collectionNameConvertEnum){ + */ + public Configuration collectionNameConvert(CollectionNameConvertEnum collectionNameConvertEnum) { this.collectionNameConvert = MongoCollectionUtils.build(collectionNameConvertEnum); return this; } /** * 设置转换器 + * * @param clazzConversions 转换器类 * @return com.anwen.mongo.config.Configuration * @author JiaChaoYang * @date 2024/3/19 18:29 - */ + */ @SafeVarargs - public final Configuration convert(Class>... clazzConversions){ + public final Configuration convert(Class>... clazzConversions) { for (Class> clazzConversion : clazzConversions) { Type[] genericInterfaces = clazzConversion.getGenericInterfaces(); for (Type anInterface : genericInterfaces) { ParameterizedType parameterizedType = (ParameterizedType) anInterface; - if (parameterizedType.getRawType().equals(ConversionStrategy.class)){ + if (parameterizedType.getRawType().equals(ConversionStrategy.class)) { Class clazz = (Class) parameterizedType.getActualTypeArguments()[0]; try { - ConversionService.appendConversion(clazz,clazzConversion.getDeclaredConstructor().newInstance()); + ConversionService.appendConversion(clazz, clazzConversion.getDeclaredConstructor().newInstance()); } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { throw new RuntimeException(e); @@ -152,57 +188,62 @@ public class Configuration { /** * 设置自动填充 + * * @param metaObjectHandler 元数据填充 * @return com.anwen.mongo.config.Configuration * @author JiaChaoYang * @date 2024/3/19 18:29 - */ - public Configuration metaObjectHandler(MetaObjectHandler metaObjectHandler){ + */ + public Configuration metaObjectHandler(MetaObjectHandler metaObjectHandler) { HandlerCache.metaObjectHandler = metaObjectHandler; return this; } /** * 设置Document处理器 + * * @param documentHandler document处理器 * @return com.anwen.mongo.config.Configuration * @author JiaChaoYang * @date 2024/3/19 18:30 - */ - public Configuration documentHandler(DocumentHandler documentHandler){ + */ + public Configuration documentHandler(DocumentHandler documentHandler) { HandlerCache.documentHandler = documentHandler; return this; } /** * 开启日志打印 + * * @author JiaChaoYang * @date 2024/3/19 18:31 - */ - public Configuration log(){ + */ + public Configuration log() { ListenerCache.listeners.add(new LogListener()); return this; } /** * 开启防攻击 + * * @author JiaChaoYang * @date 2024/3/19 18:31 - */ - public Configuration blockAttackInner(){ + */ + public Configuration blockAttackInner() { ListenerCache.listeners.add(new BlockAttackInnerListener()); return this; } /** * 设置监听器 + * * @param listeners 监听器 * @return com.anwen.mongo.config.Configuration * @author JiaChaoYang * @date 2024/3/19 18:38 - */ + */ @SafeVarargs - public final Configuration listener(Class... listeners){ + public final Configuration listener(Class... listeners) { for (Class listener : listeners) { try { ListenerCache.listeners.add(listener.getDeclaredConstructor().newInstance()); @@ -216,13 +257,14 @@ public class Configuration { /** * 设置拦截器 + * * @param interceptors 拦截器 * @return com.anwen.mongo.config.Configuration * @author JiaChaoYang * @date 2024/3/19 18:38 - */ + */ @SafeVarargs - public final Configuration interceptor(Class... interceptors){ + public final Configuration interceptor(Class... interceptors) { for (Class interceptor : interceptors) { try { InterceptorCache.interceptors.add(interceptor.getDeclaredConstructor().newInstance()); @@ -231,42 +273,64 @@ public class Configuration { throw new RuntimeException(e); } } - InterceptorCache.interceptors = InterceptorCache.interceptors.stream().sorted(Comparator.comparing(Interceptor::order)).collect(Collectors.toList()); + InterceptorCache.sorted(); + return this; + } + + /** + * 设置 替换器 + * + * @param replacers 替换器 + * @return 配置对象 + * @author loser + */ + @SafeVarargs + public final Configuration replacer(Class... replacers) { + for (Class replacer : replacers) { + try { + ExecutorReplacerCache.replacers.add(replacer.getDeclaredConstructor().newInstance()); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | + NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + ExecutorReplacerCache.sorted(); return this; } /** * 获取MongoPlusClient + * * @author JiaChaoYang * @date 2024/3/19 18:38 - */ - public MongoPlusClient getMongoPlusClient(){ - if (StringUtils.isBlank(url)){ + */ + public MongoPlusClient getMongoPlusClient() { + if (StringUtils.isBlank(url)) { throw new InitMongoPlusException("Connection URL not configured"); } - if (StringUtils.isBlank(baseProperty.getDatabase())){ + if (StringUtils.isBlank(baseProperty.getDatabase())) { throw new InitMongoPlusException("Connection database not configured"); } return initMongoPlusClient(); } - public MongoPlusClient initMongoPlusClient(){ + public MongoPlusClient initMongoPlusClient() { return initMongoPlusClient(MongoClients.create(MongoClientSettings.builder() - .applyConnectionString(new ConnectionString(this.url)).commandListenerList(Collections.singletonList(new BaseListener())).build()),collectionNameConvert,baseProperty); + .applyConnectionString(new ConnectionString(this.url)).commandListenerList(Collections.singletonList(new BaseListener())).build()), collectionNameConvert, baseProperty); } - public MongoPlusClient initMongoPlusClient(CollectionNameConvert collectionNameConvert){ + public MongoPlusClient initMongoPlusClient(CollectionNameConvert collectionNameConvert) { return initMongoPlusClient(MongoClients.create(MongoClientSettings.builder() - .applyConnectionString(new ConnectionString(this.url)).commandListenerList(Collections.singletonList(new BaseListener())).build()),collectionNameConvert,baseProperty); + .applyConnectionString(new ConnectionString(this.url)).commandListenerList(Collections.singletonList(new BaseListener())).build()), collectionNameConvert, baseProperty); } - public MongoPlusClient initMongoPlusClient(CollectionNameConvert collectionNameConvert,BaseProperty baseProperty){ + public MongoPlusClient initMongoPlusClient(CollectionNameConvert collectionNameConvert, BaseProperty baseProperty) { return initMongoPlusClient(MongoClients.create(MongoClientSettings.builder() - .applyConnectionString(new ConnectionString(this.url)).commandListenerList(Collections.singletonList(new BaseListener())).build()),collectionNameConvert,baseProperty); + .applyConnectionString(new ConnectionString(this.url)).commandListenerList(Collections.singletonList(new BaseListener())).build()), collectionNameConvert, baseProperty); } - public MongoPlusClient initMongoPlusClient(MongoClient mongoClient,CollectionNameConvert collectionNameConvert,BaseProperty baseProperty){ - if (StringUtils.isBlank(baseProperty.getDatabase())){ + public MongoPlusClient initMongoPlusClient(MongoClient mongoClient, CollectionNameConvert collectionNameConvert, BaseProperty baseProperty) { + if (StringUtils.isBlank(baseProperty.getDatabase())) { throw new InitMongoPlusException("Connection database not configured"); } MongoClientFactory.getInstance(mongoClient); @@ -274,14 +338,14 @@ public class Configuration { mongoPlusClient.setBaseProperty(baseProperty); mongoPlusClient.setCollectionNameConvert(collectionNameConvert); List mongoDatabaseList = new ArrayList<>(); - mongoPlusClient.setCollectionManagerMap(new ConcurrentHashMap>(){{ - put(DataSourceConstant.DEFAULT_DATASOURCE,new LinkedHashMap(){{ + mongoPlusClient.setCollectionManagerMap(new ConcurrentHashMap>() {{ + put(DataSourceConstant.DEFAULT_DATASOURCE, new LinkedHashMap() {{ String database = mongoPlusClient.getBaseProperty().getDatabase(); Arrays.stream(database.split(",")).collect(Collectors.toList()).forEach(db -> { CollectionManager collectionManager = new CollectionManager(mongoPlusClient.getMongoClient(), collectionNameConvert, db); MongoDatabase mongoDatabase = mongoPlusClient.getMongoClient().getDatabase(db); mongoDatabaseList.add(mongoDatabase); - put(db,collectionManager); + put(db, collectionManager); }); }}); }}); @@ -292,32 +356,127 @@ public class Configuration { /** * 设置数据源 + * * @author JiaChaoYang * @date 2024/4/5 1:48 - */ - public void setOtherDataSource(Map mongoClientMap){ + */ + public void setOtherDataSource(Map mongoClientMap) { MongoClientFactory.getInstance(mongoClientMap); } /** * 获取BaseMapper + * * @author JiaChaoYang * @date 2024/3/19 18:39 - */ - public BaseMapper getBaseMapper(){ - return new DefaultBaseMapperImpl(getMongoPlusClient(),new MappingMongoConverter(getMongoPlusClient())); + */ + public BaseMapper getBaseMapper() { + return new DefaultBaseMapperImpl(getMongoPlusClient(), new MappingMongoConverter(getMongoPlusClient())); + } + + public BaseMapper getBaseMapper(MongoConverter mongoConverter) { + return new DefaultBaseMapperImpl(getMongoPlusClient(), mongoConverter); } - public BaseMapper getBaseMapper(MongoConverter mongoConverter){ - return new DefaultBaseMapperImpl(getMongoPlusClient(),mongoConverter); + public MongoPlusMapMapper getMongoPlusMapMapper() { + return new MongoPlusMapMapper(getMongoPlusClient(), new MappingMongoConverter(getMongoPlusClient())); + } + + public MongoPlusMapMapper getMongoPlusMapMapper(MongoConverter mongoConverter) { + return new MongoPlusMapMapper(getMongoPlusClient(), mongoConverter); + } + + /** + * 配置逻辑删除 + * + * @param logicProperty 逻辑删除配置 + * @return 全局配置对象 + * @author loser + */ + public Configuration logic(LogicProperty logicProperty) { + + if (Objects.isNull(logicProperty)) { + throw new InitMongoLogicException("Config logic logicProperty not null"); + } + this.logicProperty = logicProperty; + CollectionLogicDeleteCache.open = logicProperty.getOpen(); + CollectionLogicDeleteCache.logicProperty = logicProperty; + if (logicProperty.getOpen()) { + InterceptorCache.interceptors.add(new CollectionLogiceInterceptor()); + if (logicProperty.getAutoFill()) { + InterceptorCache.interceptors.add(new LogicAutoFillInterceptor()); + } + InterceptorCache.sorted(); + ExecutorReplacerCache.replacers.add(new LogicRemoveReplacer()); + ExecutorReplacerCache.sorted(); + } + return this; + } - public MongoPlusMapMapper getMongoPlusMapMapper(){ - return new MongoPlusMapMapper(getMongoPlusClient(),new MappingMongoConverter(getMongoPlusClient())); + /** + * 注册逻辑删除 class + * + * @param collectionClasses 需要注册的 class 集合 + * @return 全局配置对象 + * @author loser + */ + public Configuration setLogicFiled(Class... collectionClasses) { + return setLogicFiled(logicProperty, collectionClasses); } - public MongoPlusMapMapper getMongoPlusMapMapper(MongoConverter mongoConverter){ - return new MongoPlusMapMapper(getMongoPlusClient(),mongoConverter); + /** + * 注册逻辑删除 class + * + * @param collectionClasses 需要注册的 class 集合 + * @return 全局配置对象 + * @author loser + */ + public Configuration setLogicFiled(LogicProperty logicProperty, Class... collectionClasses) { + + if (Objects.isNull(collectionClasses) || Objects.isNull(logicProperty) || !logicProperty.getOpen()) { + return this; + } + Map, LogicDeleteResult> logicDeleteResultHashMap = CollectionLogicDeleteCache.logicDeleteResultHashMap; + + for (Class clazz : collectionClasses) { + if (logicDeleteResultHashMap.containsKey(clazz)) { + continue; + } + ClassAnnotationFiled targetInfo = AnnotationHandler.getAnnotationOnFiled(clazz, CollectionLogic.class); + // 优先使用每个对象自定义规则 + if (Objects.nonNull(targetInfo)) { + CollectionLogic annotation = targetInfo.getTargetAnnotation(); + if (annotation.close()) { + continue; + } + LogicDeleteResult result = new LogicDeleteResult(); + Field field = targetInfo.getField(); + CollectionField collectionField = field.getAnnotation(CollectionField.class); + String column = Objects.nonNull(collectionField) && StringUtils.isNotEmpty(collectionField.value()) ? collectionField.value() : field.getName(); + result.setColumn(column); + result.setLogicDeleteValue(StringUtils.isNotBlank(annotation.delval()) ? annotation.delval() : logicProperty.getLogicDeleteValue()); + result.setLogicNotDeleteValue(StringUtils.isNotBlank(annotation.value()) ? annotation.value() : logicProperty.getLogicNotDeleteValue()); + logicDeleteResultHashMap.put(clazz, result); + continue; + } + + // 其次使用全局配置规则 + if (StringUtils.isNotEmpty(logicProperty.getLogicDeleteField()) + && StringUtils.isNotEmpty(logicProperty.getLogicDeleteValue()) + && StringUtils.isNotEmpty(logicProperty.getLogicNotDeleteValue())) { + LogicDeleteResult result = new LogicDeleteResult(); + result.setColumn(logicProperty.getLogicDeleteField()); + result.setLogicDeleteValue(logicProperty.getLogicDeleteValue()); + result.setLogicNotDeleteValue(logicProperty.getLogicNotDeleteValue()); + logicDeleteResultHashMap.put(clazz, result); + continue; + } + logicDeleteResultHashMap.put(clazz, null); + + } + return this; + } } diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/conn/CollectionManager.java b/mongo-plus-core/src/main/java/com/anwen/mongo/conn/CollectionManager.java index 3d5b3292d8d4dbbeca306ce7ff56735dc7ce873a..3c242daf46083bcd93c0c531a4382394121d1d94 100644 --- a/mongo-plus-core/src/main/java/com/anwen/mongo/conn/CollectionManager.java +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/conn/CollectionManager.java @@ -1,5 +1,6 @@ package com.anwen.mongo.conn; +import com.anwen.mongo.cache.global.CollectionLogicDeleteCache; import com.anwen.mongo.convert.CollectionNameConvert; import com.anwen.mongo.factory.MongoClientFactory; import com.anwen.mongo.toolkit.ClassTypeUtil; @@ -22,6 +23,7 @@ public class CollectionManager { /** * 缓存mongoCollection + * * @author JiaChaoYang * @date 2023/12/28 10:58 */ @@ -38,24 +40,27 @@ public class CollectionManager { /** * 设置一个连接 + * * @author JiaChaoYang * @date 2023/12/28 11:20 - */ - public void setCollectionMap(String key,MongoCollection value){ - collectionMap.put(key,value); + */ + public void setCollectionMap(String key, MongoCollection value) { + collectionMap.put(key, value); } private MongoCollection getCollection(T entity) { return getCollection(ClassTypeUtil.getClass(entity)).withCodecRegistry(RegisterCodecUtil.registerCodec(entity)); } - private MongoCollection getCollection(String collectionName,Map map){ + private MongoCollection getCollection(String collectionName, Map map) { return getCollection(collectionName).withCodecRegistry(RegisterCodecUtil.registerCodec(map)); } public MongoCollection getCollection(Class clazz) { String collectionName = this.collectionNameConvert.convert(clazz); - return getCollection(collectionName); + MongoCollection collection = getCollection(collectionName); + CollectionLogicDeleteCache.mapperClassByCollection(collection.getNamespace().getFullName(), clazz); + return collection; } public MongoCollection getCollection(String collectionName) { @@ -64,7 +69,7 @@ public class CollectionManager { if (!this.collectionMap.containsKey(collectionName)) { mongoCollection = new ConnectMongoDB(MongoClientFactory.getInstance().getMongoClient(), database, collectionName).open(); this.collectionMap.put(collectionName, mongoCollection); - }else { + } else { mongoCollection = this.collectionMap.get(collectionName); } return mongoCollection.withCodecRegistry(RegisterCodecUtil.getCodecCacheAndDefault()); diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/domain/InitMongoLogicException.java b/mongo-plus-core/src/main/java/com/anwen/mongo/domain/InitMongoLogicException.java new file mode 100644 index 0000000000000000000000000000000000000000..25c8e39bfb50a15aae6b136036e90c4a41361936 --- /dev/null +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/domain/InitMongoLogicException.java @@ -0,0 +1,16 @@ +package com.anwen.mongo.domain; + +/** + * 初始化MongoPlus逻辑删除异常 + * + * @author loser + * @date 2024/4/30 + */ +public class InitMongoLogicException extends MongoPlusException { + + public InitMongoLogicException(String message) { + super(message); + this.message = message; + } + +} diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/interceptor/Interceptor.java b/mongo-plus-core/src/main/java/com/anwen/mongo/interceptor/Interceptor.java index 0a8b5f8e8bec436c52cb70a44b7c199c681ef0af..d76730d9d935ed5e51582bffd2a130acec82d0e3 100644 --- a/mongo-plus-core/src/main/java/com/anwen/mongo/interceptor/Interceptor.java +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/interceptor/Interceptor.java @@ -4,6 +4,7 @@ import com.anwen.mongo.model.AggregateBasicDBObject; import com.anwen.mongo.model.MutablePair; import com.anwen.mongo.model.QueryParam; import com.mongodb.BasicDBObject; +import com.mongodb.client.MongoCollection; import com.mongodb.client.model.CountOptions; import com.mongodb.client.model.WriteModel; import org.bson.Document; @@ -99,4 +100,76 @@ public interface Interceptor { return writeModelList; } + /** + * 添加拦截方法 + * + * @param documentList 经过添加方法的值 + * @return java.util.List + * @author JiaChaoYang + * @date 2024/3/17 0:37 + */ + default List executeSave(List documentList, MongoCollection collection) { + return documentList; + } + + /** + * 删除拦截方法 + * + * @author JiaChaoYang + * @date 2024/3/19 19:18 + */ + default Bson executeRemove(Bson filter, MongoCollection collection) { + return filter; + } + + /** + * 修改拦截方法 + * + * @author JiaChaoYang + * @date 2024/3/19 19:18 + */ + default MutablePair executeUpdate(Bson queryBasic, Bson updateBasic, MongoCollection collection) { + return new MutablePair<>(queryBasic, updateBasic); + } + + /** + * 查询拦截方法 + * + * @author JiaChaoYang + * @date 2024/3/19 19:18 + */ + default QueryParam executeQuery(Bson queryBasic, BasicDBObject projectionList, BasicDBObject sortCond, MongoCollection collection) { + return new QueryParam(queryBasic, projectionList, sortCond); + } + + /** + * 管道拦截方法 + * + * @author JiaChaoYang + * @date 2024/3/19 19:18 + */ + default List executeAggregate(List aggregateConditionList, MongoCollection collection) { + return aggregateConditionList; + } + + /** + * 统计拦截方法 + * + * @author JiaChaoYang + * @date 2024/3/19 19:18 + */ + default MutablePair executeCount(BasicDBObject queryBasic, CountOptions countOptions, MongoCollection collection) { + return new MutablePair<>(queryBasic, countOptions); + } + + /** + * 批量操作拦截方法 + * + * @author JiaChaoYang + * @date 2024/3/19 19:19 + */ + default List> executeBulkWrite(List> writeModelList, MongoCollection collection) { + return writeModelList; + } + } diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/logic/AnnotationHandler.java b/mongo-plus-core/src/main/java/com/anwen/mongo/logic/AnnotationHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..db7366956e1a6ff0cb98294bc3beae0e6ffbdba3 --- /dev/null +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/logic/AnnotationHandler.java @@ -0,0 +1,52 @@ +package com.anwen.mongo.logic; + + +import com.anwen.mongo.model.ClassAnnotationFiled; +import com.anwen.mongo.toolkit.AnnotationUtil; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.util.Objects; + +/** + * 注解处理类 + * + * @author loser + * @date 2024/4/29 + */ +public interface AnnotationHandler { + + /** + * 从类的所有字段上获取注解 + * + * @param beanClass 类的class + * @param annotationClass 要获取的注解class + * @return 逻辑删除的字段信息 + */ + static ClassAnnotationFiled getAnnotationOnFiled(Class beanClass, Class annotationClass) { + for (Field field : beanClass.getDeclaredFields()) { + T annotation = getAnnotation(field, annotationClass); + if (Objects.nonNull(annotation)) { + return new ClassAnnotationFiled<>(beanClass, field, annotation); + } + } + Class superclass = beanClass.getSuperclass(); + if (!Objects.equals(superclass, Object.class)) { + return getAnnotationOnFiled(superclass, annotationClass); + } + return null; + } + + /** + * 从字段上获取注解 + * + * @param field 字段 + * @param annotationClass 要获取的注解class + * @param 具体注解 + * @return 注解 + */ + static T getAnnotation(Field field, Class annotationClass) { + return AnnotationUtil.findFirstAnnotation(annotationClass, field); + } + +} diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/logic/LogicDeleteHandler.java b/mongo-plus-core/src/main/java/com/anwen/mongo/logic/LogicDeleteHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..5b01ee247ccc9062a4df6238030296c8fe1923fd --- /dev/null +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/logic/LogicDeleteHandler.java @@ -0,0 +1,144 @@ +package com.anwen.mongo.logic; + +import com.anwen.mongo.cache.global.CollectionLogicDeleteCache; +import com.anwen.mongo.conditions.BuildCondition; +import com.anwen.mongo.conditions.interfaces.condition.CompareCondition; +import com.anwen.mongo.conditions.query.QueryChainWrapper; +import com.anwen.mongo.conditions.query.QueryWrapper; +import com.anwen.mongo.config.Configuration; +import com.anwen.mongo.model.LogicDeleteResult; +import com.anwen.mongo.toolkit.ChainWrappers; +import com.mongodb.BasicDBObject; +import com.mongodb.client.MongoCollection; +import org.bson.BsonDocument; +import org.bson.BsonString; +import org.bson.Document; +import org.bson.conversions.Bson; + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * 逻辑删除处理类 + * + * @author loser + * @date 2024/4/29 + */ +public interface LogicDeleteHandler { + + /** + * 是否关闭逻辑删除功能 + */ + static boolean close() { + return !CollectionLogicDeleteCache.open; + } + + /** + * 获取 mongo 实体对象和逻辑删除字段的映射关系 + */ + static Map, LogicDeleteResult> mapper() { + return CollectionLogicDeleteCache.logicDeleteResultHashMap; + } + + /** + * bson 对象添加逻辑未删除条件 + * + * @param query 查询条件 + * @param clazz 目标文档 + * @param 文档类型 + * @return 添加逻辑未删除的条件对象 + */ + @SuppressWarnings("all") + static Bson doBsonLogicDel(Bson query, Class clazz) { + + if (close()) { + return query; + } + LogicDeleteResult result = mapper().get(clazz); + if (Objects.isNull(result)) { + return query; + } + if (Objects.isNull(query)) { + QueryChainWrapper wrapper = new QueryWrapper(); + wrapper.eq(result.getColumn(), result.getLogicNotDeleteValue()); + return BuildCondition.buildQueryCondition(wrapper.getCompareList()); + } + if (query instanceof BasicDBObject) { + BasicDBObject bdb = (BasicDBObject) query; + bdb.put(result.getColumn(), new BsonString(result.getLogicNotDeleteValue())); + return bdb; + } + BsonDocument bsonDocument = query.toBsonDocument(); + bsonDocument.append(result.getColumn(), new BsonString(result.getLogicNotDeleteValue())); + return bsonDocument; + + } + + + /** + * 给 wrapper 对象添加逻辑未删除对象 + * + * @param clazz 目标文档 + * @param 文档类型 + * @return 添加逻辑未删除的条件集合 + */ + @SuppressWarnings("all") + static List doWrapperLogicDel(Class clazz) { + return doWrapperLogicDel(null, clazz); + } + + /** + * 给 wrapper 对象添加逻辑未删除对象 + * + * @param queryChainWrapper wrapper 条件包裹对象 + * @param clazz 目标文档 + * @param 文档类型 + * @return 添加逻辑未删除的条件集合 + */ + @SuppressWarnings("unchecked") + static List doWrapperLogicDel(QueryChainWrapper queryChainWrapper, Class clazz) { + + if (close()) { + if (Objects.isNull(queryChainWrapper)) { + return null; + } + return queryChainWrapper.getCompareList(); + } + LogicDeleteResult result = CollectionLogicDeleteCache.logicDeleteResultHashMap.get(clazz); + if (Objects.isNull(result)) { + if (Objects.isNull(queryChainWrapper)) { + return null; + } + return queryChainWrapper.getCompareList(); + } + if (Objects.isNull(queryChainWrapper)) { + queryChainWrapper = ChainWrappers.lambdaQueryChain(null, clazz); + } + queryChainWrapper.eq(result.getColumn(), result.getLogicNotDeleteValue()); + return queryChainWrapper.getCompareList(); + + } + + /** + * 获取连接对象 关联的 mongo 实体 + * + * @param collection 连接对象 + * @return 关联实体 + */ + static Class getBeanClass(MongoCollection collection) { + + if (Objects.isNull(collection)) { + return null; + } + Class clazz = CollectionLogicDeleteCache.fullNameMap.get(collection.getNamespace().getFullName()); + if (Objects.nonNull(clazz)) { + if (!CollectionLogicDeleteCache.logicDeleteResultHashMap.containsKey(clazz)) { + Configuration.builder().setLogicFiled(CollectionLogicDeleteCache.logicProperty, clazz); + } + } + return clazz; + + } + +} diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/logic/interceptor/CollectionLogiceInterceptor.java b/mongo-plus-core/src/main/java/com/anwen/mongo/logic/interceptor/CollectionLogiceInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..c18b21b671d17a8926d42ed9582e71015b153084 --- /dev/null +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/logic/interceptor/CollectionLogiceInterceptor.java @@ -0,0 +1,93 @@ +package com.anwen.mongo.logic.interceptor; + +import com.anwen.mongo.interceptor.Interceptor; +import com.anwen.mongo.logic.LogicDeleteHandler; +import com.anwen.mongo.model.MutablePair; +import com.anwen.mongo.model.QueryParam; +import com.mongodb.BasicDBObject; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.model.CountOptions; +import com.mongodb.client.model.UpdateManyModel; +import com.mongodb.client.model.WriteModel; +import org.bson.Document; +import org.bson.conversions.Bson; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * 逻辑删除拦截器 + * + * @author loser + * @date 2024/4/30 + */ +public class CollectionLogiceInterceptor implements Interceptor { + + @Override + public Bson executeRemove(Bson filter, MongoCollection collection) { + + Class clazz = LogicDeleteHandler.getBeanClass(collection); + if (LogicDeleteHandler.close() || Objects.isNull(clazz)) { + return filter; + } + return LogicDeleteHandler.doBsonLogicDel(filter, clazz); + + } + + @Override + public MutablePair executeUpdate(Bson queryBasic, Bson updateBasic, MongoCollection collection) { + + Class clazz = LogicDeleteHandler.getBeanClass(collection); + if (LogicDeleteHandler.close() || Objects.isNull(clazz)) { + return new MutablePair<>(queryBasic, updateBasic); + } + Bson query = LogicDeleteHandler.doBsonLogicDel(queryBasic, clazz); + return new MutablePair<>(query, updateBasic); + + } + + @Override + public QueryParam executeQuery(Bson queryBasic, BasicDBObject projectionList, BasicDBObject sortCond, MongoCollection collection) { + + Class clazz = LogicDeleteHandler.getBeanClass(collection); + if (LogicDeleteHandler.close() || Objects.isNull(clazz)) { + return new QueryParam(queryBasic, projectionList, sortCond); + } + Bson query = LogicDeleteHandler.doBsonLogicDel(queryBasic, clazz); + return new QueryParam(query, projectionList, sortCond); + + } + + @Override + public MutablePair executeCount(BasicDBObject queryBasic, CountOptions countOptions, MongoCollection collection) { + + Class clazz = LogicDeleteHandler.getBeanClass(collection); + if (LogicDeleteHandler.close() || Objects.isNull(clazz)) { + return new MutablePair<>(queryBasic, countOptions); + } + BasicDBObject query = (BasicDBObject) LogicDeleteHandler.doBsonLogicDel(queryBasic, clazz); + return new MutablePair<>(query, countOptions); + + } + + @Override + @SuppressWarnings("all") + public List> executeBulkWrite(List> writeModelList, MongoCollection collection) { + + Class clazz = LogicDeleteHandler.getBeanClass(collection); + if (LogicDeleteHandler.close() || Objects.isNull(clazz)) { + return writeModelList; + } + return writeModelList.stream().map(item -> { + if (item instanceof UpdateManyModel) { + UpdateManyModel umm = (UpdateManyModel) item; + Bson filter = LogicDeleteHandler.doBsonLogicDel(umm.getFilter(), clazz); + return new UpdateManyModel(filter, umm.getUpdate()); + } + return item; + }).collect(Collectors.toList()); + + } + +} diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/logic/interceptor/LogicAutoFillInterceptor.java b/mongo-plus-core/src/main/java/com/anwen/mongo/logic/interceptor/LogicAutoFillInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..1aa4ce3234fcc1a7d98e67bfe55ca2eefcd1d14c --- /dev/null +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/logic/interceptor/LogicAutoFillInterceptor.java @@ -0,0 +1,40 @@ +package com.anwen.mongo.logic.interceptor; + +import com.anwen.mongo.interceptor.Interceptor; +import com.anwen.mongo.logic.LogicDeleteHandler; +import com.anwen.mongo.model.LogicDeleteResult; +import com.mongodb.client.MongoCollection; +import org.bson.Document; + +import java.util.List; +import java.util.Objects; + +/** + * 逻辑删除默认字段拦截器(初始化逻辑未删除字段、建议方案:使用数据库默认字段 > 其次是手动设置 > 配置框架提供拦截器 > 自定义拦截器)) + * + * @author loser + * @date 2024/4/30 + */ +public class LogicAutoFillInterceptor implements Interceptor { + + @Override + public List executeSave(List documentList, MongoCollection collection) { + + Class clazz = LogicDeleteHandler.getBeanClass(collection); + if (Objects.isNull(clazz)) { + return documentList; + } + LogicDeleteResult result = LogicDeleteHandler.mapper().get(clazz); + if (Objects.nonNull(result)) { + for (Document document : documentList) { + if (!document.containsKey(result.getColumn())) { + document.put(result.getColumn(), result.getLogicNotDeleteValue()); + } + } + } + return documentList; + + } + + +} diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/logic/replacer/LogicRemoveReplacer.java b/mongo-plus-core/src/main/java/com/anwen/mongo/logic/replacer/LogicRemoveReplacer.java new file mode 100644 index 0000000000000000000000000000000000000000..e6c99000ff4ee9b697e0930599b60e4158b07c37 --- /dev/null +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/logic/replacer/LogicRemoveReplacer.java @@ -0,0 +1,63 @@ +package com.anwen.mongo.logic.replacer; + +import com.anwen.mongo.cache.global.CollectionLogicDeleteCache; +import com.anwen.mongo.enums.ExecuteMethodEnum; +import com.anwen.mongo.enums.SpecialConditionEnum; +import com.anwen.mongo.logic.LogicDeleteHandler; +import com.anwen.mongo.model.LogicDeleteResult; +import com.anwen.mongo.replacer.Replacer; +import com.anwen.mongo.support.BoolFunction; +import com.mongodb.BasicDBObject; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import org.bson.Document; +import org.bson.conversions.Bson; + +import java.lang.reflect.Method; +import java.util.Objects; + +/** + * 逻辑删除替换器 + * + * @author loser + * @date 2024/4/30 + */ +public class LogicRemoveReplacer implements Replacer { + + @Override + public Object invoke(Object proxy, Object target, Method method, Object[] args) throws Throwable { + + Class clazz = LogicDeleteHandler.getBeanClass((MongoCollection) args[1]); + if (Objects.isNull(clazz)) { + return method.invoke(target, args); + } + LogicDeleteResult result = LogicDeleteHandler.mapper().get(clazz); + if (Objects.isNull(result)) { + return method.invoke(target, args); + } + Method updateMethod = target.getClass().getMethod(ExecuteMethodEnum.UPDATE.getMethod(), Bson.class, Bson.class, MongoCollection.class); + Document updateBasic = new Document(result.getColumn(), result.getLogicDeleteValue()); + BasicDBObject update = new BasicDBObject(SpecialConditionEnum.SET.getCondition(), updateBasic); + Object[] updateArgs = new Object[]{args[0], update, args[1]}; + UpdateResult res = (UpdateResult) updateMethod.invoke(target, updateArgs); + return new DeleteResult() { + @Override + public boolean wasAcknowledged() { + return res.wasAcknowledged(); + } + + @Override + public long getDeletedCount() { + return res.getModifiedCount(); + } + }; + + } + + @Override + public BoolFunction supplier() { + return (proxy, target, method, args) -> CollectionLogicDeleteCache.open && method.getName().equals(ExecuteMethodEnum.REMOVE.getMethod()); + } + +} diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/model/ClassAnnotationFiled.java b/mongo-plus-core/src/main/java/com/anwen/mongo/model/ClassAnnotationFiled.java new file mode 100644 index 0000000000000000000000000000000000000000..234b1e0a290776ebff31ee1ad8ab2e99bf4d8800 --- /dev/null +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/model/ClassAnnotationFiled.java @@ -0,0 +1,49 @@ +package com.anwen.mongo.model; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; + +/** + * 目标类首个指定注解结果包裹对象 + * + * @author loser + * @date 2024/4/28 + */ +public class ClassAnnotationFiled { + + private Class target; + + private Field field; + + private T targetAnnotation; + + public ClassAnnotationFiled(Class target, Field field, T tableLogic) { + this.target = target; + this.field = field; + this.targetAnnotation = tableLogic; + } + + public Class getTarget() { + return target; + } + + public void setTarget(Class target) { + this.target = target; + } + + public Field getField() { + return field; + } + + public void setField(Field field) { + this.field = field; + } + + public T getTargetAnnotation() { + return targetAnnotation; + } + + public void setTargetAnnotation(T targetAnnotation) { + this.targetAnnotation = targetAnnotation; + } +} diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/model/LogicDeleteResult.java b/mongo-plus-core/src/main/java/com/anwen/mongo/model/LogicDeleteResult.java new file mode 100644 index 0000000000000000000000000000000000000000..d9990cc20bee9de5718214aedfa31c5d97e8dfee --- /dev/null +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/model/LogicDeleteResult.java @@ -0,0 +1,49 @@ +package com.anwen.mongo.model; + +/** + * 逻辑删除信息 + * + * @author loser + * @date 2024/4/29 + */ +public class LogicDeleteResult { + + /** + * 逻辑删除指定的列 + */ + private String column; + + /** + * 逻辑删除全局值(默认 1、表示已删除) + */ + private String logicDeleteValue = "1"; + + /** + * 逻辑未删除全局值(默认 0、表示未删除) + */ + private String logicNotDeleteValue = "0"; + + public String getColumn() { + return column; + } + + public void setColumn(String column) { + this.column = column; + } + + public String getLogicDeleteValue() { + return logicDeleteValue; + } + + public void setLogicDeleteValue(String logicDeleteValue) { + this.logicDeleteValue = logicDeleteValue; + } + + public String getLogicNotDeleteValue() { + return logicNotDeleteValue; + } + + public void setLogicNotDeleteValue(String logicNotDeleteValue) { + this.logicNotDeleteValue = logicNotDeleteValue; + } +} diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/model/LogicProperty.java b/mongo-plus-core/src/main/java/com/anwen/mongo/model/LogicProperty.java new file mode 100644 index 0000000000000000000000000000000000000000..f1d63ad15ce1f0d57461aa78527d3b9ab3ed9763 --- /dev/null +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/model/LogicProperty.java @@ -0,0 +1,75 @@ +package com.anwen.mongo.model; + +/** + * @author JiaChaoYang + * @project mongo-plus + * @description + * @date 2023-02-23 10:42 + **/ +public class LogicProperty { + + /** + * 是否开启逻辑删除功能 + */ + private Boolean open = false; + + /** + * 是否开启基于拦截器的逻辑删除字段填充(建议方案:使用数据库默认字段 > 其次是手动设置 > 框架自带拦截器 > 自定义拦截器) + */ + private Boolean autoFill = false; + + /** + * 逻辑删除全局属性名 + */ + private String logicDeleteField; + + /** + * 逻辑删除全局值(默认 1、表示已删除) + */ + private String logicDeleteValue = "1"; + + /** + * 逻辑未删除全局值(默认 0、表示未删除) + */ + private String logicNotDeleteValue = "0"; + + public void setAutoFill(Boolean autoFill) { + this.autoFill = autoFill; + } + + public Boolean getAutoFill() { + return autoFill; + } + + public Boolean getOpen() { + return open; + } + + public void setOpen(Boolean open) { + this.open = open; + } + + public String getLogicDeleteField() { + return logicDeleteField; + } + + public void setLogicDeleteField(String logicDeleteField) { + this.logicDeleteField = logicDeleteField; + } + + public String getLogicDeleteValue() { + return logicDeleteValue; + } + + public void setLogicDeleteValue(String logicDeleteValue) { + this.logicDeleteValue = logicDeleteValue; + } + + public String getLogicNotDeleteValue() { + return logicNotDeleteValue; + } + + public void setLogicNotDeleteValue(String logicNotDeleteValue) { + this.logicNotDeleteValue = logicNotDeleteValue; + } +} diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/proxy/ExecutorProxy.java b/mongo-plus-core/src/main/java/com/anwen/mongo/proxy/ExecutorProxy.java index 65135a762c3d615b6c471fcba2853d738c550311..03b22c6610970eab124f2aa6b7805ff55bf348c2 100644 --- a/mongo-plus-core/src/main/java/com/anwen/mongo/proxy/ExecutorProxy.java +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/proxy/ExecutorProxy.java @@ -1,8 +1,10 @@ package com.anwen.mongo.proxy; import com.anwen.mongo.cache.global.ExecutorProxyCache; +import com.anwen.mongo.cache.global.ExecutorReplacerCache; import com.anwen.mongo.cache.global.InterceptorCache; import com.anwen.mongo.execute.Execute; +import com.anwen.mongo.replacer.Replacer; import com.anwen.mongo.strategy.executor.MethodExecutorStrategy; import java.lang.reflect.InvocationHandler; @@ -26,12 +28,22 @@ public class ExecutorProxy implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - String name = method.getName(); - MethodExecutorStrategy executor = ExecutorProxyCache.EXECUTOR_MAP.get(name); + + // 参数替换拦截器 + MethodExecutorStrategy executor = ExecutorProxyCache.EXECUTOR_MAP.get(method.getName()); if (Objects.nonNull(executor)) { InterceptorCache.interceptors.forEach(interceptor -> executor.invoke(interceptor, args)); } + + // 方法替换执行器 执行首个命中执行器 + for (Replacer replacer : ExecutorReplacerCache.replacers) { + if (replacer.supplier().get(proxy, target, method, args)) { + return replacer.invoke(proxy, target, method, args); + } + } + return method.invoke(target, args); + } } diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/replacer/Replacer.java b/mongo-plus-core/src/main/java/com/anwen/mongo/replacer/Replacer.java new file mode 100644 index 0000000000000000000000000000000000000000..2b8ec5a29123218dd8ed0e066862508f7933cfae --- /dev/null +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/replacer/Replacer.java @@ -0,0 +1,23 @@ +package com.anwen.mongo.replacer; + +import com.anwen.mongo.support.BoolFunction; + +import java.lang.reflect.Method; + +/** + * 替换器接 + * + * @author loser + * @date 2024/4/30 + */ +public interface Replacer { + + default int order() { + return Integer.MIN_VALUE; + } + + Object invoke(Object proxy, Object target, Method method, Object[] args) throws Throwable; + + BoolFunction supplier(); + +} \ No newline at end of file diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/MethodExecutorStrategy.java b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/MethodExecutorStrategy.java index 001549ca76146544b23a151b74ca6d6917959105..3eefa437f0c8e86f1d07285ea7226238b6074d29 100644 --- a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/MethodExecutorStrategy.java +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/MethodExecutorStrategy.java @@ -4,7 +4,7 @@ import com.anwen.mongo.enums.ExecuteMethodEnum; import com.anwen.mongo.interceptor.Interceptor; /** - * 解耦逻辑 + * 方法执行策略(解耦逻辑) * * @author loser * @date 2024/4/28 diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/AggregateExecutorStrategy.java b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/AggregateExecutorStrategy.java index a6c6e68240b229bbb9cc794bd6c56fbfc453deba..4d354e7122cfef25ab7aabfe8e8f1e90b73b38a6 100644 --- a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/AggregateExecutorStrategy.java +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/AggregateExecutorStrategy.java @@ -4,9 +4,17 @@ import com.anwen.mongo.enums.ExecuteMethodEnum; import com.anwen.mongo.interceptor.Interceptor; import com.anwen.mongo.model.AggregateBasicDBObject; import com.anwen.mongo.strategy.executor.MethodExecutorStrategy; +import com.mongodb.client.MongoCollection; +import org.bson.Document; import java.util.List; +/** + * AGGREGATE 策略执行器 + * + * @author loser + * @date 2024/4/30 + */ public class AggregateExecutorStrategy implements MethodExecutorStrategy { @Override @@ -17,6 +25,7 @@ public class AggregateExecutorStrategy implements MethodExecutorStrategy { @Override public void invoke(Interceptor interceptor, Object[] args) { args[0] = interceptor.executeAggregate((List) args[0]); + args[0] = interceptor.executeAggregate((List) args[0], (MongoCollection) args[1]); } } diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/BulkWriteExecutorStrategy.java b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/BulkWriteExecutorStrategy.java index e6d552103aacb0ef0528277ff118b42371ed9ec3..1b56f3f0f8d750fbc4288d2517b9d8ae372d7a79 100644 --- a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/BulkWriteExecutorStrategy.java +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/BulkWriteExecutorStrategy.java @@ -3,11 +3,18 @@ package com.anwen.mongo.strategy.executor.impl; import com.anwen.mongo.enums.ExecuteMethodEnum; import com.anwen.mongo.interceptor.Interceptor; import com.anwen.mongo.strategy.executor.MethodExecutorStrategy; +import com.mongodb.client.MongoCollection; import com.mongodb.client.model.WriteModel; import org.bson.Document; import java.util.List; +/** + * BULK_WRITE 策略执行器 + * + * @author loser + * @date 2024/4/30 + */ public class BulkWriteExecutorStrategy implements MethodExecutorStrategy { @Override @@ -18,6 +25,7 @@ public class BulkWriteExecutorStrategy implements MethodExecutorStrategy { @Override public void invoke(Interceptor interceptor, Object[] args) { args[0] = interceptor.executeBulkWrite((List>) args[0]); + args[0] = interceptor.executeBulkWrite((List>) args[0], (MongoCollection) args[1]); } } diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/CountExecutorStrategy.java b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/CountExecutorStrategy.java index 50deabd349d1f6ffd4f80fff104de8b04e9de2e4..2df64649b9fe753d1773e98923e3cae503b492ca 100644 --- a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/CountExecutorStrategy.java +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/CountExecutorStrategy.java @@ -5,8 +5,16 @@ import com.anwen.mongo.interceptor.Interceptor; import com.anwen.mongo.model.MutablePair; import com.anwen.mongo.strategy.executor.MethodExecutorStrategy; import com.mongodb.BasicDBObject; +import com.mongodb.client.MongoCollection; import com.mongodb.client.model.CountOptions; +import org.bson.Document; +/** + * COUNT 策略执行器 + * + * @author loser + * @date 2024/4/30 + */ public class CountExecutorStrategy implements MethodExecutorStrategy { @Override @@ -19,6 +27,9 @@ public class CountExecutorStrategy implements MethodExecutorStrategy { MutablePair basicDBObjectCountOptionsMutablePair = interceptor.executeCount((BasicDBObject) args[0], (CountOptions) args[1]); args[0] = basicDBObjectCountOptionsMutablePair.getLeft(); args[1] = basicDBObjectCountOptionsMutablePair.getRight(); + basicDBObjectCountOptionsMutablePair = interceptor.executeCount((BasicDBObject) args[0], (CountOptions) args[1], (MongoCollection) args[2]); + args[0] = basicDBObjectCountOptionsMutablePair.getLeft(); + args[1] = basicDBObjectCountOptionsMutablePair.getRight(); } } diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/QueryExecutorStrategy.java b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/QueryExecutorStrategy.java index 4325f869396a8abf6e51b57be19424c2650c1456..cef0e159c16ba56cfdec3ad6c0b0cb7f14871d61 100644 --- a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/QueryExecutorStrategy.java +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/QueryExecutorStrategy.java @@ -5,8 +5,16 @@ import com.anwen.mongo.interceptor.Interceptor; import com.anwen.mongo.model.QueryParam; import com.anwen.mongo.strategy.executor.MethodExecutorStrategy; import com.mongodb.BasicDBObject; +import com.mongodb.client.MongoCollection; +import org.bson.Document; import org.bson.conversions.Bson; +/** + * QUERY 策略执行器 + * + * @author loser + * @date 2024/4/30 + */ public class QueryExecutorStrategy implements MethodExecutorStrategy { @Override @@ -20,6 +28,10 @@ public class QueryExecutorStrategy implements MethodExecutorStrategy { args[0] = queryParam.getQuery(); args[1] = queryParam.getProjection(); args[2] = queryParam.getSort(); + queryParam = interceptor.executeQuery((Bson) args[0], (BasicDBObject) args[1], (BasicDBObject) args[2], (MongoCollection) args[3]); + args[0] = queryParam.getQuery(); + args[1] = queryParam.getProjection(); + args[2] = queryParam.getSort(); } } diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/RemoveExecutorStrategy.java b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/RemoveExecutorStrategy.java index 8c33ee1b4f561290b45a5f704301d567e345878f..d2e9781e86e955b090e58c91b9952fefa0a36378 100644 --- a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/RemoveExecutorStrategy.java +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/RemoveExecutorStrategy.java @@ -3,8 +3,17 @@ package com.anwen.mongo.strategy.executor.impl; import com.anwen.mongo.enums.ExecuteMethodEnum; import com.anwen.mongo.interceptor.Interceptor; import com.anwen.mongo.strategy.executor.MethodExecutorStrategy; +import com.mongodb.client.MongoCollection; +import org.bson.Document; import org.bson.conversions.Bson; + +/** + * REMOVE 策略执行器 + * + * @author loser + * @date 2024/4/30 + */ public class RemoveExecutorStrategy implements MethodExecutorStrategy { @Override @@ -15,6 +24,7 @@ public class RemoveExecutorStrategy implements MethodExecutorStrategy { @Override public void invoke(Interceptor interceptor, Object[] args) { args[0] = interceptor.executeRemove((Bson) args[0]); + args[0] = interceptor.executeRemove((Bson) args[0], (MongoCollection) args[1]); } } diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/SaveExecutorStrategy.java b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/SaveExecutorStrategy.java index da838c862c9ef0d2d561b4b0a4e75f03843d2b0f..2f731ebd4c65e56921e743ed2a3cb5a3b74f8d23 100644 --- a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/SaveExecutorStrategy.java +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/SaveExecutorStrategy.java @@ -3,10 +3,17 @@ package com.anwen.mongo.strategy.executor.impl; import com.anwen.mongo.enums.ExecuteMethodEnum; import com.anwen.mongo.interceptor.Interceptor; import com.anwen.mongo.strategy.executor.MethodExecutorStrategy; +import com.mongodb.client.MongoCollection; import org.bson.Document; import java.util.List; +/** + * SAVE 策略执行器 + * + * @author loser + * @date 2024/4/30 + */ public class SaveExecutorStrategy implements MethodExecutorStrategy { @Override @@ -17,6 +24,7 @@ public class SaveExecutorStrategy implements MethodExecutorStrategy { @Override public void invoke(Interceptor interceptor, Object[] args) { args[0] = interceptor.executeSave((List) args[0]); + args[0] = interceptor.executeSave((List) args[0], (MongoCollection) args[1]); } } diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/UpdateExecutorStrategy.java b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/UpdateExecutorStrategy.java index 1166437f77e8726a59905602e7b82f9ccf63cfa0..e5c1b329e622da31bdd3a54886db8ad06553abfb 100644 --- a/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/UpdateExecutorStrategy.java +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/strategy/executor/impl/UpdateExecutorStrategy.java @@ -4,8 +4,16 @@ import com.anwen.mongo.enums.ExecuteMethodEnum; import com.anwen.mongo.interceptor.Interceptor; import com.anwen.mongo.model.MutablePair; import com.anwen.mongo.strategy.executor.MethodExecutorStrategy; +import com.mongodb.client.MongoCollection; +import org.bson.Document; import org.bson.conversions.Bson; +/** + * UPDATE 策略执行器 + * + * @author loser + * @date 2024/4/30 + */ public class UpdateExecutorStrategy implements MethodExecutorStrategy { @Override @@ -18,6 +26,9 @@ public class UpdateExecutorStrategy implements MethodExecutorStrategy { MutablePair bsonBsonMutablePair = interceptor.executeUpdate((Bson) args[0], (Bson) args[1]); args[0] = bsonBsonMutablePair.getLeft(); args[1] = bsonBsonMutablePair.getRight(); + bsonBsonMutablePair = interceptor.executeUpdate((Bson) args[0], (Bson) args[1], (MongoCollection) args[2]); + args[0] = bsonBsonMutablePair.getLeft(); + args[1] = bsonBsonMutablePair.getRight(); } } diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/support/BoolFunction.java b/mongo-plus-core/src/main/java/com/anwen/mongo/support/BoolFunction.java new file mode 100644 index 0000000000000000000000000000000000000000..8a13da4ea37a800fdb0b84849b945811398b8bb0 --- /dev/null +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/support/BoolFunction.java @@ -0,0 +1,17 @@ +package com.anwen.mongo.support; + + +import java.lang.reflect.Method; + +/** + * boolean function + * + * @author loser + * @date 2024/4/30 + */ +@FunctionalInterface +public interface BoolFunction { + + boolean get(Object proxy, Object target, Method method, Object[] args); + +} diff --git a/mongo-plus-core/src/main/java/com/anwen/mongo/toolkit/AnnotationUtil.java b/mongo-plus-core/src/main/java/com/anwen/mongo/toolkit/AnnotationUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..7c1419b1ff253c391b71f6ccb7470f96e1cfcb67 --- /dev/null +++ b/mongo-plus-core/src/main/java/com/anwen/mongo/toolkit/AnnotationUtil.java @@ -0,0 +1,70 @@ +package com.anwen.mongo.toolkit; + +import com.anwen.mongo.annotation.ID; +import com.anwen.mongo.enums.IdTypeEnum; +import com.anwen.mongo.model.BaseModelID; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * @author JiaChaoYang + * 注解操作 + * @since 2023-02-13 13:59 + **/ +public class AnnotationUtil { + + public static Map getFieldAnnotation(Object object) { + Field[] fields = object.getClass().getDeclaredFields(); + Map resultMap = new HashMap<>(); + Class superclass = object.getClass().getSuperclass(); + IdTypeEnum idTypeEnum = null; + String fieldName = "id"; + Class fieldType = String.class; + for (Field field : fields) { + if (field.isAnnotationPresent(ID.class)) { + idTypeEnum = field.getAnnotation(ID.class).type(); + fieldName = field.getName(); + fieldType = field.getType(); + } + } + if (superclass == BaseModelID.class) { + try { + idTypeEnum = superclass.getField("id").getAnnotation(ID.class).type(); + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } + } + if (idTypeEnum != null) { + resultMap.put("fieldName", fieldName); + resultMap.put("fieldType", fieldType); + resultMap.put("generateType", idTypeEnum); + } + return resultMap; + } + + public static T findFirstAnnotation(Class annotationClazz, Field field) { + return getAnnotation(annotationClazz, new HashSet<>(), field.getDeclaredAnnotations()); + } + + @SuppressWarnings("unchecked") + private static T getAnnotation(Class annotationClazz, Set> annotationSet, Annotation... annotations) { + for (Annotation annotation : annotations) { + if (annotationSet.add(annotation.annotationType())) { + if (annotationClazz.isAssignableFrom(annotation.annotationType())) { + return (T) annotation; + } + annotation = getAnnotation(annotationClazz, annotationSet, annotation.annotationType().getDeclaredAnnotations()); + if (annotation != null) { + return (T) annotation; + } + } + } + return null; + } + +} diff --git a/mongo-plus-solon-plugin/src/main/java/com/anwen/mongo/config/MongoPlusAutoConfiguration.java b/mongo-plus-solon-plugin/src/main/java/com/anwen/mongo/config/MongoPlusAutoConfiguration.java index cf985e8cb3737342839afb42c833237db126754d..c791e8feb328ba2ce9fe0919d714b9ba20430db6 100644 --- a/mongo-plus-solon-plugin/src/main/java/com/anwen/mongo/config/MongoPlusAutoConfiguration.java +++ b/mongo-plus-solon-plugin/src/main/java/com/anwen/mongo/config/MongoPlusAutoConfiguration.java @@ -169,7 +169,7 @@ public class MongoPlusAutoConfiguration { * @date 2023/11/22 18:39 */ private void setListener(AppContext context){ - List listeners = new ArrayList<>(); + List listeners = ListenerCache.listeners; if (mongoDBLogProperty.getLog()){ listeners.add(new LogListener()); } @@ -180,7 +180,8 @@ public class MongoPlusAutoConfiguration { if (CollUtil.isNotEmpty(listenerCollection)){ listeners.addAll(listenerCollection); } - ListenerCache.listeners = listeners.stream().sorted(Comparator.comparingInt(Listener::getOrder)).collect(Collectors.toList()); + ListenerCache.sorted(); + } /**