diff --git a/.gitignore b/.gitignore index e090081..4da4016 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ **/*.iml **/.idea/** +.flattened-pom.xml + # User-specific stuff .idea/**/workspace.xml .idea/**/tasks.xml diff --git a/flyfish-approval/pom.xml b/flyfish-approval/pom.xml index f806e10..842298e 100644 --- a/flyfish-approval/pom.xml +++ b/flyfish-approval/pom.xml @@ -5,7 +5,7 @@ flyfish-framework com.flyfish.framework - 0.0.2-SNAPSHOT + ${revision} 4.0.0 @@ -17,14 +17,20 @@ + + org.springframework.data + spring-data-relational + true + org.springframework.data spring-data-mongodb + true com.flyfish.framework flyfish-web - ${project.version} + ${revision} diff --git a/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/ApprovalDomainQo.java b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/ApprovalDomainQo.java index 6695087..9f8b121 100644 --- a/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/ApprovalDomainQo.java +++ b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/ApprovalDomainQo.java @@ -4,8 +4,8 @@ import com.flyfish.framework.annotations.EnumValue; import com.flyfish.framework.annotations.Order; import com.flyfish.framework.annotations.Property; import com.flyfish.framework.approval.enums.ApproveStatus; -import com.flyfish.framework.builder.CriteriaBuilder; import com.flyfish.framework.domain.authorized.AuthorizedQo; +import com.flyfish.framework.query.QueryDefinition; import lombok.Getter; import lombok.Setter; @@ -24,7 +24,7 @@ public class ApprovalDomainQo extends AuthorizedQo private String status; @Override - public CriteriaBuilder criteriaBuilder() { - return super.criteriaBuilder().with("status", "approveStatus"); + public QueryDefinition queryBuilder() { + return super.queryBuilder().mutate().and(T::getApproveStatus).eq(status); } } diff --git a/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecord.java b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecord.java index e099c08..0e671db 100644 --- a/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecord.java +++ b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecord.java @@ -5,6 +5,9 @@ import com.flyfish.framework.domain.base.AuditDomain; import lombok.Getter; import lombok.Setter; import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; /** * 审批记录 @@ -12,11 +15,13 @@ import org.springframework.data.mongodb.core.mapping.Document; * @author wangyu */ @Document(collection = "approve-records") +@Table("approve_records") @Getter @Setter public class ApproveRecord extends AuditDomain { // 是否已审批 + @Column private Boolean approved; // 模块 diff --git a/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecordQo.java b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecordQo.java index c253845..aeb4204 100644 --- a/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecordQo.java +++ b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecordQo.java @@ -1,7 +1,7 @@ package com.flyfish.framework.approval.domain.record; -import com.flyfish.framework.builder.CriteriaBuilder; import com.flyfish.framework.domain.base.NameLikeQo; +import com.flyfish.framework.query.QueryDefinition; import lombok.Getter; import lombok.Setter; @@ -27,7 +27,12 @@ public class ApproveRecordQo extends NameLikeQo { private String approver; @Override - public CriteriaBuilder criteriaBuilder() { - return super.criteriaBuilder().with("module", "dataId", "approved", "approver"); + public QueryDefinition queryBuilder() { + return super.queryBuilder() + .mutate() + .and(ApproveRecord::getModule).eq(module) + .and(ApproveRecord::getDataId).eq(dataId) + .and(ApproveRecord::getApproved).eq(approved) + .and(ApproveRecord::getApprover).eq(approver); } } diff --git a/flyfish-backup/pom.xml b/flyfish-backup/pom.xml index 3d74dca..7db9b45 100644 --- a/flyfish-backup/pom.xml +++ b/flyfish-backup/pom.xml @@ -5,7 +5,7 @@ flyfish-framework com.flyfish.framework - 0.0.2-SNAPSHOT + ${revision} 4.0.0 @@ -17,10 +17,20 @@ + + org.springframework.data + spring-data-relational + true + + + org.springframework.data + spring-data-mongodb + true + com.flyfish.framework flyfish-web - ${project.version} + ${revision} diff --git a/flyfish-backup/src/main/java/com/flyfish/framework/backup/domain/Backup.java b/flyfish-backup/src/main/java/com/flyfish/framework/backup/domain/Backup.java index 23a649e..1d3aea7 100644 --- a/flyfish-backup/src/main/java/com/flyfish/framework/backup/domain/Backup.java +++ b/flyfish-backup/src/main/java/com/flyfish/framework/backup/domain/Backup.java @@ -6,6 +6,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.relational.core.mapping.Table; /** * 系统备份 @@ -15,6 +16,7 @@ import org.springframework.data.mongodb.core.mapping.Document; @Getter @Setter @Document(collection = "backups") +@Table("backups") public class Backup extends AuditDomain { // 文件路径 diff --git a/flyfish-backup/src/main/java/com/flyfish/framework/backup/domain/Version.java b/flyfish-backup/src/main/java/com/flyfish/framework/backup/domain/Version.java index ff5f71a..3d31c5f 100644 --- a/flyfish-backup/src/main/java/com/flyfish/framework/backup/domain/Version.java +++ b/flyfish-backup/src/main/java/com/flyfish/framework/backup/domain/Version.java @@ -7,6 +7,7 @@ import java.util.Date; /** * 版本号实体 + * * @author wangyu */ @Data diff --git a/flyfish-backup/src/main/java/com/flyfish/framework/backup/scheduler/BackupScheduler.java b/flyfish-backup/src/main/java/com/flyfish/framework/backup/scheduler/BackupScheduler.java index 26f2690..e67ba12 100644 --- a/flyfish-backup/src/main/java/com/flyfish/framework/backup/scheduler/BackupScheduler.java +++ b/flyfish-backup/src/main/java/com/flyfish/framework/backup/scheduler/BackupScheduler.java @@ -3,6 +3,8 @@ package com.flyfish.framework.backup.scheduler; import com.alibaba.fastjson.JSON; import com.flyfish.framework.backup.domain.Backup; import com.flyfish.framework.domain.base.DomainService; +import com.flyfish.framework.query.Query; +import com.flyfish.framework.repository.ReactiveEntityOperations; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -12,8 +14,8 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.core.io.buffer.DefaultDataBufferFactory; -import org.springframework.data.mongodb.core.ReactiveMongoOperations; -import org.springframework.data.mongodb.repository.query.MongoEntityInformation; +import org.springframework.data.repository.core.EntityInformation; +import org.springframework.data.util.CastUtils; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.unit.DataSize; @@ -22,7 +24,6 @@ import reactor.core.publisher.Mono; import java.io.IOException; import java.nio.channels.AsynchronousFileChannel; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -45,9 +46,9 @@ public class BackupScheduler { // data buffer 工厂 private final DataBufferFactory factory = new DefaultDataBufferFactory(); // 用于注入所有集合名称 - private List> collections; + private List> collections; // 异步的mongo操作,可以快速备份 - private ReactiveMongoOperations operations; + private ReactiveEntityOperations operations; // 备份路径 private String backupPath = "/opt/flyfish/backup"; @@ -57,8 +58,8 @@ public class BackupScheduler { } @Autowired - public void setOperations(ReactiveMongoOperations reactiveMongoOperations) { - this.operations = reactiveMongoOperations; + public void setOperations(ReactiveEntityOperations reactiveEntityOperations) { + this.operations = reactiveEntityOperations; } @Autowired @@ -92,8 +93,8 @@ public class BackupScheduler { operations.save(backup) .thenMany(Flux.fromIterable(this.collections)) .flatMap(info -> operations - .findAll(info.getJavaType(), info.getCollectionName()).collectList() - .map(list -> new BackupIndex.BackupContent(info.getCollectionName(), JSON.toJSONBytes(list))) + .findAll(Query.empty(), CastUtils.cast(info)).collectList() + .map(list -> new BackupIndex.BackupContent(info.getJavaType().getSimpleName(), JSON.toJSONBytes(list))) ) .flatMap(content -> writeContents(content, parent)) .collectList() diff --git a/flyfish-common/pom.xml b/flyfish-common/pom.xml index 0d26753..c51fcae 100644 --- a/flyfish-common/pom.xml +++ b/flyfish-common/pom.xml @@ -5,7 +5,7 @@ flyfish-framework com.flyfish.framework - 0.0.2-SNAPSHOT + ${revision} 4.0.0 diff --git a/flyfish-common/src/main/java/com/flyfish/framework/utils/LRUCache.java b/flyfish-common/src/main/java/com/flyfish/framework/utils/LRUCache.java new file mode 100644 index 0000000..1b1bdaa --- /dev/null +++ b/flyfish-common/src/main/java/com/flyfish/framework/utils/LRUCache.java @@ -0,0 +1,36 @@ +package com.flyfish.framework.utils; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * LRU (least recently used)最近最久未使用缓存
+ * 根据使用时间来判定对象是否被持续缓存
+ * 当对象被访问时放入缓存,当缓存满了,最久未被使用的对象将被移除。
+ * 此缓存基于LinkedHashMap,因此当被缓存的对象每被访问一次,这个对象的key就到链表头部。
+ * 这个算法简单并且非常快,他比FIFO有一个显著优势是经常使用的对象不太可能被移除缓存。
+ * 缺点是当缓存满时,不能被很快的访问。 + * + * @param 键类型 + * @param 值类型 + * @author wangyu + */ +public class LRUCache extends LinkedHashMap { + + private static final long serialVersionUID = 1L; + private final int maxSize; + + public LRUCache(int maxSize) { + this(maxSize, 16, 0.75f, false); + } + + public LRUCache(int maxSize, int initialCapacity, float loadFactor, boolean accessOrder) { + super(initialCapacity, loadFactor, accessOrder); + this.maxSize = maxSize; + } + + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return this.size() > this.maxSize; + } +} diff --git a/flyfish-common/src/main/java/com/flyfish/framework/utils/Supportable.java b/flyfish-common/src/main/java/com/flyfish/framework/utils/Supportable.java new file mode 100644 index 0000000..e84292e --- /dev/null +++ b/flyfish-common/src/main/java/com/flyfish/framework/utils/Supportable.java @@ -0,0 +1,12 @@ +package com.flyfish.framework.utils; + +public interface Supportable { + + /** + * 判断是否支持实体 + * + * @param entity 实体信息 + * @return 结果 + */ + boolean supports(T entity); +} diff --git a/flyfish-data/README.md b/flyfish-data/README.md new file mode 100644 index 0000000..6f5f8be --- /dev/null +++ b/flyfish-data/README.md @@ -0,0 +1,16 @@ +# 核心数据框架 + +本模块是flyfish framework的最核心能力 +其提供无感知的多种数据源支持,并完整适配了mongodb和rdbms的查询表现, +用户只需要用一套api即可完成数据的查询或修改,无需为了底层实现而大费周章重新开发。 + +## 核心架构 +1. 基于Spring SPI模式,声明式注入查询实现工厂,动态替换查询构建逻辑 +2. 按需引入,不浪费任何依赖,节省空间。使用maven的按需引入模式,让打包后的结果不必因为重量级的框架而变得冗余 +3. 指哪打哪,稳定快速。集成最新版本的spring mongo引擎和spring data r2dbc +4. 核心框架广泛使用,保证"0bug"。 + +## 无限扩展 +1. 根据实际业务需求,采用mongo、jpa、r2dbc的方式,动态选择实现,而业务和底层存储实现无关,完全解耦 +2. 健壮的架构,能够支撑99%的业务 +3. 完善的关联机制,多表关联做到全自动化 diff --git a/flyfish-data/flyfish-data-common/pom.xml b/flyfish-data/flyfish-data-common/pom.xml new file mode 100644 index 0000000..41f4700 --- /dev/null +++ b/flyfish-data/flyfish-data-common/pom.xml @@ -0,0 +1,47 @@ + + + + flyfish-data + com.flyfish.framework + ${revision} + + 4.0.0 + + flyfish-data-common + + + 8 + 8 + + + + + com.flyfish.framework + flyfish-common + + + + org.springframework.boot + spring-boot-autoconfigure + + + + com.flyfish.framework + flyfish-data-domain + ${revision} + compile + + + + org.springframework.security + spring-security-core + + + + com.github.ulisesbocchio + jasypt-spring-boot-starter + + + diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/EnableEnumEndpoint.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/annotations/EnableEnumEndpoint.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/EnableEnumEndpoint.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/annotations/EnableEnumEndpoint.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/EnablePropertyEncrypt.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/annotations/EnablePropertyEncrypt.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/EnablePropertyEncrypt.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/annotations/EnablePropertyEncrypt.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/auditor/AuthorizeAuditor.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/AuthorizeAuditor.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/auditor/AuthorizeAuditor.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/AuthorizeAuditor.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/auditor/BeanAuditor.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/BeanAuditor.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/auditor/BeanAuditor.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/BeanAuditor.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/auditor/BeanPoster.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/BeanPoster.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/auditor/BeanPoster.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/BeanPoster.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/auditor/CommonBeanAuditor.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/CommonBeanAuditor.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/auditor/CommonBeanAuditor.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/CommonBeanAuditor.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/auditor/OperationAuditor.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/OperationAuditor.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/auditor/OperationAuditor.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/OperationAuditor.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/auditor/ReactiveAuthorizeAuditor.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/ReactiveAuthorizeAuditor.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/auditor/ReactiveAuthorizeAuditor.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/ReactiveAuthorizeAuditor.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/auditor/ReactiveBeanAuditor.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/ReactiveBeanAuditor.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/auditor/ReactiveBeanAuditor.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/ReactiveBeanAuditor.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/auditor/ReactiveBeanPoster.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/ReactiveBeanPoster.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/auditor/ReactiveBeanPoster.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/ReactiveBeanPoster.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/auditor/ReactiveCommonBeanAuditor.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/ReactiveCommonBeanAuditor.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/auditor/ReactiveCommonBeanAuditor.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/ReactiveCommonBeanAuditor.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/auditor/ReactiveOperationAuditor.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/ReactiveOperationAuditor.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/auditor/ReactiveOperationAuditor.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/auditor/ReactiveOperationAuditor.java diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/builder/CriteriaBuilderProvider.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/builder/CriteriaBuilderProvider.java new file mode 100644 index 0000000..bc2cba8 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/builder/CriteriaBuilderProvider.java @@ -0,0 +1,10 @@ +package com.flyfish.framework.builder; + +/** + * 查询构建器提供者 + * @author wangyu- + */ +public interface CriteriaBuilderProvider { + + +} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/config/CodeRuleConfig.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/config/CodeRuleConfig.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/config/CodeRuleConfig.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/config/CodeRuleConfig.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/config/DecryptConfig.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/config/DecryptConfig.java similarity index 89% rename from flyfish-data/src/main/java/com/flyfish/framework/config/DecryptConfig.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/config/DecryptConfig.java index b523aef..1b2b43b 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/config/DecryptConfig.java +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/config/DecryptConfig.java @@ -9,6 +9,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; +import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration; import org.springframework.context.annotation.Bean; /** @@ -17,7 +18,7 @@ import org.springframework.context.annotation.Bean; * * @author wangyu */ -@AutoConfigureBefore(MongoDataAutoConfiguration.class) +@AutoConfigureBefore({R2dbcDataAutoConfiguration.class, MongoDataAutoConfiguration.class}) @ConditionalOnProperty("flyfish.jasypt.key") @EnableEncryptableProperties public class DecryptConfig { @@ -34,7 +35,6 @@ public class DecryptConfig { return new AESEncryptablePropertyResolver(password); } - @Bean(name = "encryptablePropertyFilter") public EncryptablePropertyFilter encryptablePropertyFilter() { return (source, name) -> StringUtils.endsWithIgnoreCase(name, PASSWORD_KEY); diff --git a/flyfish-data/src/main/java/com/flyfish/framework/config/EnumConfig.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/config/EnumConfig.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/config/EnumConfig.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/config/EnumConfig.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/config/encrypt/AESEncryptablePropertyResolver.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/config/encrypt/AESEncryptablePropertyResolver.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/config/encrypt/AESEncryptablePropertyResolver.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/config/encrypt/AESEncryptablePropertyResolver.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/context/ReactiveUserContext.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/context/ReactiveUserContext.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/context/ReactiveUserContext.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/context/ReactiveUserContext.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/context/UserContext.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/context/UserContext.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/context/UserContext.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/context/UserContext.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AbstractAuthorizedQo.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/authorized/AbstractAuthorizedQo.java similarity index 67% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AbstractAuthorizedQo.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/authorized/AbstractAuthorizedQo.java index e6d785c..06e93a4 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AbstractAuthorizedQo.java +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/authorized/AbstractAuthorizedQo.java @@ -1,11 +1,11 @@ package com.flyfish.framework.domain.authorized; -import com.flyfish.framework.builder.CriteriaBuilder; import com.flyfish.framework.domain.base.NameLikeQo; import com.flyfish.framework.domain.po.Department; +import com.flyfish.framework.query.LambdaQueryChain; +import com.flyfish.framework.query.Queries; import lombok.Setter; import org.apache.commons.lang3.BooleanUtils; -import org.springframework.data.mongodb.core.query.Criteria; import java.util.Collections; import java.util.Set; @@ -38,20 +38,17 @@ public abstract class AbstractAuthorizedQo extends N * * @return 结果 */ - protected Criteria withPublished() { + protected LambdaQueryChain withPublished() { if (null != published) { if (BooleanUtils.isTrue(published)) { - return Criteria.where("published").is(true); + return Queries.where(T::getPublished).eq(true); } - return Criteria.where("$or").is( - CriteriaBuilder.createCriteriaList( - Criteria.where("published").isNull(), - Criteria.where("published").is(false) - ) + return Queries.within( + Queries.where(T::getPublished).isNull().or(T::getPublished).eq(false) ); } else { // 未指定发布状态,查询已发布内容 - return Criteria.where("published").is(true); + return Queries.where(T::getPublished).eq(true); } } diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedQo.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedQo.java new file mode 100644 index 0000000..6bd0eeb --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedQo.java @@ -0,0 +1,42 @@ +package com.flyfish.framework.domain.authorized; + +import com.flyfish.framework.enums.UserType; +import com.flyfish.framework.query.QueryDefinition; +import com.flyfish.framework.query.Queries; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.BooleanUtils; + +/** + * 带鉴权的查询实体,主要以部门隔绝 + * + * @param + */ +@Getter +@Setter +public class AuthorizedQo extends AbstractAuthorizedQo { + + @Override + public QueryDefinition queryBuilder() { + // 超级管理员拥有查看所有草稿的权限 + if (user.getType() == UserType.SUPER_ADMIN) { + return super.queryBuilder().mutate().and(this.withPublished()); + } + // 查询草稿,只查询自己的 + if (BooleanUtils.isFalse(published)) { + return super.queryBuilder() + .mutate() + .and(this.withPublished()) + .and(Queries.where(T::getCreatorId).eq(user.getId())); + } + // 普通查询,根据权限配置查询 + return super.queryBuilder() + .mutate() + .and(this.withPublished()) + .and(Queries.where(T::getAuthorizeId).in(authorizeIds()) + .or(Queries.where(T::getCreatorId).eq(user.getId()) + .and(T::getAuthorizeId).in(((AuthorizedUserDetails) user).getVisibleDeparts())) + ); + } + +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/authorized/advanced/OwnedAuthorizedQo.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/authorized/advanced/OwnedAuthorizedQo.java new file mode 100644 index 0000000..6896ed3 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/authorized/advanced/OwnedAuthorizedQo.java @@ -0,0 +1,49 @@ +package com.flyfish.framework.domain.authorized.advanced; + +import com.flyfish.framework.domain.authorized.AbstractAuthorizedQo; +import com.flyfish.framework.domain.authorized.AuthorizedUserDetails; +import com.flyfish.framework.enums.UserType; +import com.flyfish.framework.query.QueryDefinition; +import com.flyfish.framework.query.Queries; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.BooleanUtils; + +/** + * 拥有归属权的授权查询 + * + * @param 泛型 + * @author wangyu + * 将会额外查询归属者的内容 + */ +@Getter +@Setter +public class OwnedAuthorizedQo extends AbstractAuthorizedQo { + + @Override + public QueryDefinition queryBuilder() { + // 超级管理员拥有查看所有草稿的权限 + if (user.getType() == UserType.SUPER_ADMIN) { + return super.queryBuilder().mutate().and(this.withPublished()); + } + // 查询草稿,只查询自己的 + if (BooleanUtils.isFalse(published)) { + return super.queryBuilder() + .mutate() + .and(this.withPublished()) + // 此处原意为使用用户id匹配owners列中的id,修改后框架会自动判定并解包,存在耦合性 + .and(Queries + .where(T::getCreatorId).eq(user.getId()) + .or(T::getOwners).hasId(user.getId())); + } + // 普通查询,根据权限配置查询 + return super.queryBuilder() + .mutate() + .and(this.withPublished()) + .and(() -> Queries.where(T::getAuthorizeId).in(authorizeIds()) + .or(Queries.where(T::getCreatorId).eq(user.getId()) + .and(T::getAuthorizeId).in(((AuthorizedUserDetails) user).getVisibleDeparts())) + .or(Queries.where(T::getOwners).hasId(user.getId())) + ); + } +} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/BaseQo.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/base/BaseQo.java similarity index 58% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/base/BaseQo.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/base/BaseQo.java index 7d91b0a..031140c 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/BaseQo.java +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/base/BaseQo.java @@ -1,20 +1,28 @@ package com.flyfish.framework.domain.base; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.flyfish.framework.builder.CriteriaBuilder; +import com.flyfish.framework.query.Queries; +import com.flyfish.framework.query.Query; +import com.flyfish.framework.query.QueryDefinition; +import com.flyfish.framework.utils.CopyUtils; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Example; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; -import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.repository.core.EntityInformation; import java.lang.reflect.ParameterizedType; import java.util.List; +import java.util.Optional; + +import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; /** * 基本的查询实体 * * @author Mr.Wang */ +@Slf4j public class BaseQo implements Qo { protected Pageable pageable; @@ -100,12 +108,20 @@ public class BaseQo implements Qo { * @return 结果 */ @Override - public Criteria getCriteria() { - CriteriaBuilder criteriaBuilder = criteriaBuilder(); - if (null != criteriaBuilder) { - return criteriaBuilder.build(); + public Optional getQuery(EntityInformation entityInformation) { + Query query = Query.empty(); + QueryDefinition definition = queryBuilder(); + if (null != definition) { + // 查询定义存在时,使用查询定义 + query.setDefinition(definition); + } else { + // 不存在查询定义,取得example,若不存在example,则使用probe + query.setExample(defaultIfNull(getExample(), getProbe())); } - return null; + query.setSort(sorts()); + query.setPageable(getPageable()); + query.setFields(getFields()); + return Optional.of(Queries.convert(query, entityInformation)); } /** @@ -115,7 +131,7 @@ public class BaseQo implements Qo { */ @Override public List getFields() { - return null; + return fields; } /** @@ -123,7 +139,7 @@ public class BaseQo implements Qo { * * @return 结果 */ - public CriteriaBuilder criteriaBuilder() { + public QueryDefinition queryBuilder() { return null; } @@ -144,4 +160,29 @@ public class BaseQo implements Qo { public Sort sorts() { return Sort.by(Sort.Order.desc("modifyTime")); } + + /** + * 判断当前查询是否为空 + * + * @return 结果 + */ + @Override + public boolean isEmpty() { + QueryDefinition definition = queryBuilder(); + Example example = getExample(); + return null == example && (null == definition || definition.isEmpty()); + } + + private Example getProbe() { + Class type = pojoType(); + if (null != type && !Object.class.equals(type)) { + try { + T pojo = CopyUtils.copyQueryProps(this, type.newInstance()); + return Example.of(pojo); + } catch (InstantiationException | IllegalAccessException e) { + log.warn("尝试实例化bean失败!", e); + } + } + return null; + } } diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/NameLikeQo.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/base/NameLikeQo.java similarity index 53% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/base/NameLikeQo.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/base/NameLikeQo.java index 732ab7a..916da23 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/NameLikeQo.java +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/base/NameLikeQo.java @@ -1,10 +1,10 @@ package com.flyfish.framework.domain.base; -import com.flyfish.framework.builder.CriteriaBuilder; +import com.flyfish.framework.query.QueryDefinition; +import com.flyfish.framework.query.Queries; import lombok.Getter; import lombok.Setter; import org.springframework.data.domain.Sort; -import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.util.StringUtils; import java.util.Collection; @@ -46,22 +46,24 @@ public class NameLikeQo extends BaseQo { private String distinct; @Override - public CriteriaBuilder criteriaBuilder() { - return CriteriaBuilder.accept(this) - .with("name", CriteriaBuilder.Builders.LIKE) - .with("enable", "code", "creatorId", "modifierId") - .with("ids", "id", CriteriaBuilder.Builders.IN) - .with("excludeId", "id", Criteria::ne) - .with("createTimeRange", "createTime", CriteriaBuilder.Builders.DATE_RANGE) - .with("modifyTimeRange", "modifyTime", CriteriaBuilder.Builders.DATE_RANGE); + public QueryDefinition queryBuilder() { + return Queries.where("name").like(name) + .and("enable").eq(enable) + .and("code").eq(code) + .and("creatorId").eq(creatorId) + .and("modifierId").eq(modifierId) + .and("id").in(ids) + .and("id").ne(excludeId) + .and("createTime").between(createTimeRange) + .and("modifyTime").between(modifyTimeRange); } @Override public Sort sorts() { - if (StringUtils.isEmpty(sort)) { - return super.sorts(); + if (StringUtils.hasText(sort)) { + return Sort.by(Sort.Order.desc(sort)); } - return Sort.by(Sort.Order.desc(sort)); + return super.sorts(); } } diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/package-info.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/package-info.java new file mode 100644 index 0000000..6196f85 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/package-info.java @@ -0,0 +1,4 @@ +package com.flyfish.framework.domain; +/** + * 提供应用级别的实体 + */ diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/tree/TreeQo.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/tree/TreeQo.java new file mode 100644 index 0000000..dcf907d --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/domain/tree/TreeQo.java @@ -0,0 +1,37 @@ +package com.flyfish.framework.domain.tree; + +import com.flyfish.framework.domain.base.NameLikeQo; +import com.flyfish.framework.query.QueryDefinition; +import com.flyfish.framework.query.LambdaQueryChain; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.BooleanUtils; + +import java.util.List; + +/** + * 属性菜单的qo + */ +@Getter +@Setter +public class TreeQo> extends NameLikeQo { + + private Integer depth; + + private String parentId; + + private List parentIds; + + private Boolean recursive; + + @Override + public QueryDefinition queryBuilder() { + LambdaQueryChain chain = super.queryBuilder().mutate().and(T::getDepth).eq(depth); + if (BooleanUtils.isTrue(recursive)) { + chain.and(T::getParentIds).has(parentId).and(T::getParentIds).in(parentId); + } else { + chain.and(T::getParentId).eq(parentId).and(T::getParentId).in(parentIds); + } + return chain; + } +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/LambdaQueryChain.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/LambdaQueryChain.java new file mode 100644 index 0000000..017fc6a --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/LambdaQueryChain.java @@ -0,0 +1,101 @@ +package com.flyfish.framework.query; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.query.Queries.Combinator; +import com.flyfish.framework.query.support.DomainFunction; + +import java.util.List; +import java.util.function.Supplier; + +/** + * lambda查询条件 + * + * @author wangyu + */ +public interface LambdaQueryChain extends QueryChain, DomainFunction> { + + /** + * 以且连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + QueryCondition> and(DomainFunction column); + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @return 结果 + */ + @Override + > LambdaQueryChain and(Supplier> supplier); + + /** + * 条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + @Override + > LambdaQueryChain and(QueryChain chain); + + /** + * 多个嵌套子条件列表 + * + * @param chains 多条链 + * @return 结果 + */ + @Override + default > LambdaQueryChain and(List> chains) { + return QueryChain.super.and(chains); + } + + /** + * 多个嵌套子条件列表 + * + * @param chains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + @Override + > LambdaQueryChain and(List> chains, Combinator combinator); + + /** + * 以或连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + QueryCondition> or(DomainFunction column); + + /** + * 以或连接条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + @Override + > LambdaQueryChain or(QueryChain chain); + + /** + * 以或连接嵌套多个子条件列表 + * + * @param chains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + @Override + > LambdaQueryChain or(List> chains, Combinator combinator); + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @return 结果 + */ + @Override + > LambdaQueryChain or(Supplier> supplier); +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/NamedQueryChain.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/NamedQueryChain.java new file mode 100644 index 0000000..ba09c9d --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/NamedQueryChain.java @@ -0,0 +1,100 @@ +package com.flyfish.framework.query; + +import com.flyfish.framework.query.Queries.Combinator; + +import java.util.List; +import java.util.function.Supplier; + +/** + * 查询链条 + * + * @author wangyu + */ +public interface NamedQueryChain extends QueryChain { + + /** + * 以且连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + QueryCondition and(String column); + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @return 结果 + */ + @Override + > NamedQueryChain and(Supplier> supplier); + + /** + * 条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + @Override + > NamedQueryChain and(QueryChain chain); + + /** + * 多个嵌套子条件列表 + * + * @param chains 多条链 + * @return 结果 + */ + @Override + default > NamedQueryChain and(List> chains) { + return QueryChain.super.and(chains); + } + + /** + * 多个嵌套子条件列表 + * + * @param chains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + @Override + > NamedQueryChain and(List> chains, Combinator combinator); + + /** + * 以或连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + QueryCondition or(String column); + + /** + * 以或连接条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + @Override + > NamedQueryChain or(QueryChain chain); + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @return 结果 + */ + @Override + > NamedQueryChain or(Supplier> supplier); + + /** + * 以或连接嵌套多个子条件列表 + * + * @param chains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + @Override + > NamedQueryChain or(List> chains, Combinator combinator); + +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/Queries.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/Queries.java new file mode 100644 index 0000000..35a087e --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/Queries.java @@ -0,0 +1,93 @@ +package com.flyfish.framework.query; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.query.chain.DefaultLambdaQueryChain; +import com.flyfish.framework.query.chain.DefaultNamedQueryChain; +import com.flyfish.framework.query.support.DomainFunction; +import org.springframework.data.repository.core.EntityInformation; + +/** + * 查询工具类 + * 基于Fluent API风格实现 + * 底层基于适配器兼容各种数据库,包括关系型数据库和 + * 自动判定空值,空值默认情况不会进行查询 + * + * @author wangyu + */ +public final class Queries { + + /** + * 查询转换 + * + * @param query 通用查询 + * @param entityInformation 实体信息 + * @param 具体查询泛型 + * @return 转换结果 + */ + @SuppressWarnings("unchecked") + public static T convert(Query query, EntityInformation entityInformation) { + return QueryFactories.getFactory(entityInformation) + .map(factory -> (T) factory.getConverter().convert(query)) + .orElse(null); + } + + /** + * 创建基于字符串字段名的查询 + * + * @param column 列名 + * @return 结果 + */ + public static QueryCondition where(String column) { + NamedQueryChain chain = new DefaultNamedQueryChain(); + return chain.and(column); + } + + /** + * 创建基于lambda字段引用的查询 + * + * @param getter 列引用 + * @return 结果 + */ + public static QueryCondition> where(DomainFunction getter) { + LambdaQueryChain chain = new DefaultLambdaQueryChain<>(); + return chain.and(getter); + } + + /** + * 以嵌套条件开始 + * + * @param chain 要嵌套的条件 + * @return 结果 + */ + public static NamedQueryChain within(NamedQueryChain chain) { + NamedQueryChain created = new DefaultNamedQueryChain(); + return created.and(chain); + } + + /** + * 以嵌套条件开始 + * + * @param chain 要嵌套的条件 + * @return 结果 + */ + public static LambdaQueryChain within(LambdaQueryChain chain) { + LambdaQueryChain created = new DefaultLambdaQueryChain<>(); + return created.and(chain); + } + + /** + * 传入多个查询列表时的连接方式 + */ + public enum Combinator { + + AND, OR + } + + /** + * 方向,用于描述查询和部分语法 + */ + public enum Direction { + + LEFT, RIGHT, ALL + } +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/Query.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/Query.java new file mode 100644 index 0000000..f8cf4f2 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/Query.java @@ -0,0 +1,71 @@ +package com.flyfish.framework.query; + +import com.flyfish.framework.domain.base.Domain; +import lombok.Data; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; + +import java.util.List; +import java.util.function.Function; + +/** + * 抽象查询实体 + * + * @author wangyu + */ +@Data +public class Query { + + // 查询定义 + private QueryDefinition definition; + // 查询用例 + private Example example; + // 排序 + private Sort sort; + // 分页 + private Pageable pageable; + // 字段列表 + private List fields; + + /** + * 初始化一个查询 + * + * @param definition 查询定义 + * @return 结果 + */ + public static Query query(QueryDefinition definition) { + Query query = new Query(); + query.setDefinition(definition); + return query; + } + + /** + * 创建一个空查询 + * + * @return 结果 + */ + public static Query empty() { + return new Query(); + } + + /** + * 指定选择的字段 + * + * @param columns 字段们 + * @return 当前自身 + */ + public Query select(String... columns) { + return this; + } + + /** + * 指定选择的字段 + * + * @param getters 字段们 + * @return 当前自身 + */ + public Query select(Function... getters) { + return this; + } +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryChain.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryChain.java new file mode 100644 index 0000000..8e4af61 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryChain.java @@ -0,0 +1,106 @@ +package com.flyfish.framework.query; + +import com.flyfish.framework.query.Queries.Combinator; + +import java.util.List; +import java.util.function.Supplier; + +/** + * 查询链 + * 此处为高度抽象,便于上层调用 + * 下层重写方法实现 + * + * @param 本类型泛型 + * @param

参数泛型 + * @author wangyu + */ +public interface QueryChain, P> extends QueryDefinition { + + /** + * 以且连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + QueryCondition and(P column); + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @param 泛型,支持其他类型的链 + * @return 结果 + */ + > C and(Supplier> supplier); + + /** + * 条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + > C and(QueryChain chain); + + /** + * 多个嵌套子条件列表 + * + * @param chains 多条链 + * @return 结果 + */ + default > C and(List> chains) { + return and(chains, Combinator.AND); + } + + /** + * 多个嵌套子条件列表 + * + * @param chains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + > C and(List> chains, Combinator combinator); + + /** + * 以或连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + QueryCondition or(P column); + + /** + * 以或连接条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + > C or(QueryChain chain); + + /** + * 以或连接嵌套多个子条件列表 + * + * @param chains 多条链 + * @return 结果 + */ + default > C or(List> chains) { + return and(chains, Combinator.AND); + } + + /** + * 以或连接嵌套多个子条件列表 + * + * @param chains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + > C or(List> chains, Combinator combinator); + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @param 泛型,支持其他类型的链 + * @return 结果 + */ + > C or(Supplier> supplier); +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryCondition.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryCondition.java new file mode 100644 index 0000000..9cb3c27 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryCondition.java @@ -0,0 +1,152 @@ +package com.flyfish.framework.query; + +import java.util.Collection; +import java.util.List; + +/** + * 查询条件 + * + * @param 条件本类型 + * @author wangyu + */ +public interface QueryCondition> { + + /** + * 相等判定 + * + * @param value 值 + * @return 结果 + */ + C eq(Object value); + + /** + * 判定某列的值中存在指定值,特指json array数据类型且子类型中带有id的场景 + * 用于兼容mongodb查询,mysql查询使用JSON_CONTAINS进行判定。 + * 当且仅当mongodb会拼接.$id,mysql一律匹配id字段 + *

+ * 等价于 .eq(value) + * + * @param value 值 + * @return 结果 + */ + C hasId(Object value); + + /** + * 对于mongodb,自动处理。对于关系型数据库,代表json array中是否包含对应值,值仅支持基本数据类型 + *

+ * 等价于 .eq(value) + * + * @param value 基本数据类型的值 + * @return 结果 + */ + C has(Object value); + + /** + * 不等判定 + * + * @param value 值 + * @return 结果 + */ + C ne(Object value); + + /** + * 值介于两者之间 + * + * @param items 双值列表 + * @return 结果 + */ + C between(List items); + + /** + * 模糊匹配,这里是全模糊 + * + * @param keyword 查询关键字 + * @return 结果 + */ + C like(String keyword); + + /** + * 根据指定的方向进行模糊查询 + * + * @param keyword 关键字 + * @param direction 方向,可以匹配开头和结尾 + * @return 结果 + */ + C like(String keyword, Queries.Direction direction); + + /** + * 判定为空 + * + * @return 结果 + */ + C isNull(); + + /** + * 包含在内 + * + * @param values 集合 + * @return 结果 + */ + C in(Collection values); + + /** + * 包含在内 + * 注意,需要根据字段类型推断。 + * 如果是json数组,需要进行双向匹配 + * + * @param values 值们 + * @return 结果 + */ + C in(Object... values); + + /** + * 不包含在内 + * 注意,需要根据字段类型推断。 + * 如果是json数组,需要进行双向匹配 + * + * @param values 值们 + * @return 结果 + */ + C nin(Object... values); + + /** + * 不包含在内 + * + * @param values 集合 + * @return 结果 + */ + C nin(Collection values); + + /** + * 小于指定的值 + * + * @param value 类型 + * @return 结果 + */ + C lt(Object value); + + /** + * 小于等于指定的值 + * + * @param value 类型 + * @return 结果 + */ + C lte(Object value); + + /** + * 大于指定的值 + * + * @param value 类型 + * @return 结果 + */ + C gt(Object value); + + /** + * 大于等于指定的值 + * + * @param value 类型 + * @return 结果 + */ + C gte(Object value); + +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryDefinition.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryDefinition.java new file mode 100644 index 0000000..fb016e5 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryDefinition.java @@ -0,0 +1,42 @@ +package com.flyfish.framework.query; + +import com.flyfish.framework.query.holder.QueryChainHolder; +import com.flyfish.framework.query.spi.adaptor.CriteriaAdaptor; + +/** + * 可构建的 + * + * @author wangyu + */ +public interface QueryDefinition { + + /** + * 构建结果 + * + * @param adaptor 查询适配器 + * @param 泛型 + * @return 构建结果 + */ + T build(CriteriaAdaptor adaptor); + + /** + * 修改,此修改会直接接着查询条件进行拼接 + * + * @return 修改句柄 + */ + QueryMutation mutate(); + + /** + * 会直接添加嵌套查询到当前查询末尾 + * + * @return 修改句柄 + */ + QueryMutation within(); + + /** + * 判断查询条件是否为空 + * + * @return 结果 + */ + boolean isEmpty(); +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryFactories.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryFactories.java new file mode 100644 index 0000000..595d7e0 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryFactories.java @@ -0,0 +1,33 @@ +package com.flyfish.framework.query; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.query.spi.QueryFactory; +import org.springframework.core.io.support.SpringFactoriesLoader; +import org.springframework.data.repository.core.EntityInformation; + +import java.util.List; +import java.util.Optional; + +/** + * 查询工厂持有者 + * + * @author wangyu + */ +class QueryFactories { + + @SuppressWarnings("rawtypes") + private static final List FACTORIES = + SpringFactoriesLoader.loadFactories(QueryFactory.class, null); + + /** + * 获取目标查询工厂 + * + * @param entityInformation 实体信息 + * @return 结果 + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + public static Optional getFactory(EntityInformation entityInformation) { + return FACTORIES.stream().filter(factory -> factory.supports(entityInformation)) + .findFirst(); + } +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryMutation.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryMutation.java new file mode 100644 index 0000000..2bd65eb --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryMutation.java @@ -0,0 +1,80 @@ +package com.flyfish.framework.query; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.query.support.DomainFunction; + +/** + * 查询修改逻辑 + * + * @author wangyu + */ +public interface QueryMutation { + + /** + * 以lambda的形式修改 + * 注意,如果之前用过lambda的形式,此处应该校验类型 + * + * @param getter 方法引用 + * @param 实体泛型 + * @return 结果 + */ + QueryCondition> and(DomainFunction getter); + + /** + * 以column的形式修改 + * + * @param column 列名 + * @return 结果 + */ + QueryCondition and(String column); + + /** + * 直接以and拼接其他的所有条件 + * + * @param chain 传入的查询 + * @return 结果 + */ + LambdaQueryChain and(LambdaQueryChain chain); + + /** + * 直接以and拼接其他的所有条件 + * + * @param chain 传入的查询 + * @return 结果 + */ + NamedQueryChain and(NamedQueryChain chain); + + /** + * 以lambda的形式修改 + * 注意,如果之前用过lambda的形式,此处应该校验类型 + * + * @param getter 方法引用 + * @param 实体泛型 + * @return 结果 + */ + QueryCondition> or(DomainFunction getter); + + /** + * 以column的形式修改 + * + * @param column 列名 + * @return 结果 + */ + QueryCondition or(String column); + + /** + * 直接以or拼接其他的所有条件 + * + * @param chain 传入的查询 + * @return 结果 + */ + LambdaQueryChain or(LambdaQueryChain chain); + + /** + * 直接以or拼接其他的所有条件 + * + * @param chain 传入的查询 + * @return 结果 + */ + NamedQueryChain or(NamedQueryChain chain); +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/README.md b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/README.md new file mode 100644 index 0000000..3aacfde --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/README.md @@ -0,0 +1,4 @@ +# 查询构建Fluent Api适配器 +同时适配关系型数据库mysql和非关系型数据库mongodb + +未来将会支持更多,采用覆盖的方式进行对象组合 diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultLambdaQueryChain.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultLambdaQueryChain.java new file mode 100644 index 0000000..7dbbe4f --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultLambdaQueryChain.java @@ -0,0 +1,42 @@ +package com.flyfish.framework.query.chain; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.query.LambdaQueryChain; +import com.flyfish.framework.query.QueryCondition; +import com.flyfish.framework.query.support.DomainFunction; + +/** + * 默认按lambda的查询链实现 + * + * @author wangyu + */ +public class DefaultLambdaQueryChain extends DefaultQueryChain, DomainFunction> implements LambdaQueryChain { + + private QueryCondition> createCondition(DomainFunction column) { + return createCondition(column.getName()); + } + + /** + * 以且连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + public QueryCondition> and(DomainFunction column) { + and(); + return createCondition(column); + } + + /** + * 以或连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + public QueryCondition> or(DomainFunction column) { + or(); + return createCondition(column); + } +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultNamedQueryChain.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultNamedQueryChain.java new file mode 100644 index 0000000..6ae97e4 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultNamedQueryChain.java @@ -0,0 +1,37 @@ +package com.flyfish.framework.query.chain; + +import com.flyfish.framework.query.NamedQueryChain; +import com.flyfish.framework.query.QueryCondition; + +/** + * 默认按名称的查询链实现 + * + * @author wangyu + */ +public class DefaultNamedQueryChain extends DefaultQueryChain implements NamedQueryChain { + + /** + * 以且连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + public QueryCondition and(String column) { + and(); + return createCondition(column); + } + + /** + * 以或连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + public QueryCondition or(String column) { + or(); + return createCondition(column); + } + +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultQueryChain.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultQueryChain.java new file mode 100644 index 0000000..602cf15 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultQueryChain.java @@ -0,0 +1,190 @@ +package com.flyfish.framework.query.chain; + +import com.flyfish.framework.query.Queries; +import com.flyfish.framework.query.QueryChain; +import com.flyfish.framework.query.QueryCondition; +import com.flyfish.framework.query.QueryMutation; +import com.flyfish.framework.query.holder.QueryChainHolder; +import com.flyfish.framework.query.spi.adaptor.CriteriaAdaptor; +import lombok.Getter; +import org.springframework.data.util.CastUtils; + +import java.util.List; +import java.util.function.Supplier; + +/** + * 默认的查询定义,交给holder提供构建 + * 在执行时,我们并不知道adaptor是谁,只有最后构建阶段才能明确 + * + * @author wangyu + */ +@Getter +abstract class DefaultQueryChain, P> implements QueryChain { + + protected final DefaultQueryChainHolder holder = new DefaultQueryChainHolder<>(); + + /** + * 以且的关系进行拼接 + * + * @return 结果 + */ + protected QueryChainHolder and() { + return holder.link(adaptor -> adaptor::and); + } + + /** + * 以或的关系进行拼接 + * + * @return 结果 + */ + protected QueryChainHolder or() { + return holder.link(adaptor -> adaptor::or); + } + + /** + * 创建条件,使用默认实现的条件 + * + * @param column 列名 + * @return 结果 + */ + protected QueryCondition createCondition(String column) { + return new DefaultQueryCondition<>(self(), holder, column); + } + + /** + * 返回自身真实类型 + * + * @return 结果 + */ + private C self() { + return CastUtils.cast(this); + } + + /** + * 构建结果 + * + * @param adaptor 查询适配器 + * @return 构建结果 + */ + @Override + @SuppressWarnings("unchecked") + public T build(CriteriaAdaptor adaptor) { + QueryChainHolder casted = (QueryChainHolder) holder; + return casted.get(adaptor); + } + + /** + * 修改,此修改会直接接着查询条件进行拼接 + * + * @return 修改句柄 + */ + @Override + public QueryMutation mutate() { + return new DefaultQueryMutation(this, false); + } + + /** + * 会直接添加嵌套查询到当前查询末尾 + * + * @return 修改句柄 + */ + @Override + public QueryMutation within() { + return new DefaultQueryMutation(this, true); + } + + /** + * 判断查询条件是否为空 + * + * @return 结果 + */ + @Override + public boolean isEmpty() { + return holder.isEmpty(); + } + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @return 结果 + */ + @Override + public > C and(Supplier> supplier) { + and().with(adaptor -> supplier.get().build(adaptor)); + return self(); + } + + /** + * 条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + @Override + public > C and(QueryChain chain) { + and().with(chain::build); + return self(); + } + + /** + * 多个嵌套子条件列表 + * + * @param chains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + @Override + public > C and(List> chains, Queries.Combinator combinator) { + return and(combine(chains, combinator)); + } + + /** + * 以或连接条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + @Override + public > C or(QueryChain chain) { + or().with(chain::build); + return self(); + } + + /** + * 以或连接嵌套多个子条件列表 + * + * @param chains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + @Override + public > C or(List> chains, Queries.Combinator combinator) { + return or(combine(chains, combinator)); + } + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @return 结果 + */ + @Override + public > C or(Supplier> supplier) { + or().with(adaptor -> supplier.get().build(adaptor)); + return self(); + } + + /** + * 结合多个查询链,并根据组合方式进行处理 + * + * @param chains 查询链集合 + * @param combinator 组合方式 + * @return 结果 + */ + private > C combine(List> chains, Queries.Combinator combinator) { + return chains.stream().reduce((left, right) -> combinator == Queries.Combinator.OR ? left.or(right) : left.and(right)) + .map(this::and) + .orElse(self()); + } +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultQueryChainHolder.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultQueryChainHolder.java new file mode 100644 index 0000000..f06f290 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultQueryChainHolder.java @@ -0,0 +1,59 @@ +package com.flyfish.framework.query.chain; + +import com.flyfish.framework.query.holder.QueryChainHolder; +import com.flyfish.framework.query.spi.adaptor.CriteriaAdaptor; + +import java.util.function.BinaryOperator; +import java.util.function.Function; + +/** + * 默认的查询保持器 + * + * @param 泛型,交给适配器处理 + */ +class DefaultQueryChainHolder implements QueryChainHolder { + + /** + * 等待下一步消费 + * 如果不调用with,该状态将一直保持,可被其他link调用替换 + * 在调用with后,自动消费,并完成拼接 + * + * @param operator 操作方法 + * @return 本身 + */ + @Override + public QueryChainHolder link(Function, BinaryOperator> operator) { + return null; + } + + /** + * 拼接条件 + * + * @param criteria 条件 + */ + @Override + public void with(Function, C> criteria) { + + } + + + /** + * 触发动作,得到最终的 + * + * @return 本身 + */ + @Override + public C get(CriteriaAdaptor adaptor) { + return null; + } + + /** + * 判断条件是否为空 + * + * @return 结果 + */ + @Override + public boolean isEmpty() { + return false; + } +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultQueryCondition.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultQueryCondition.java new file mode 100644 index 0000000..aff1424 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultQueryCondition.java @@ -0,0 +1,258 @@ +package com.flyfish.framework.query.chain; + +import com.flyfish.framework.query.Queries; +import com.flyfish.framework.query.QueryChain; +import com.flyfish.framework.query.QueryCondition; +import com.flyfish.framework.query.holder.QueryChainHolder; +import lombok.RequiredArgsConstructor; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.Collection; +import java.util.List; + +/** + * 条件操作实现 + * + * @author wangyu + */ +@RequiredArgsConstructor +class DefaultQueryCondition> implements QueryCondition { + + private final C chain; + private final QueryChainHolder holder; + private final String column; + + /** + * 相等判定 + * + * @param value 值 + * @return 结果 + */ + @Override + public C eq(Object value) { + if (null != value) { + holder.with(adaptor -> adaptor.eq(column, value)); + } + return chain; + } + + /** + * 判定某列的值中存在指定值,特指json array数据类型且子类型中带有id的场景 + * 用于兼容mongodb查询,mysql查询使用JSON_CONTAINS进行判定。 + * 当且仅当mongodb会拼接.$id,mysql一律匹配id字段 + *

+ * 等价于 .eq(value) + * + * @param value 值 + * @return 结果 + */ + @Override + public C hasId(Object value) { + if (null != value) { + holder.with(adaptor -> adaptor.hasId(column, value)); + } + return chain; + } + + /** + * 对于mongodb,自动处理。对于关系型数据库,代表json array中是否包含对应值,值仅支持基本数据类型 + *

+ * 等价于 .eq(value) + * + * @param value 基本数据类型的值 + * @return 结果 + */ + @Override + public C has(Object value) { + if (null != value) { + holder.with(adaptor -> adaptor.has(column, value)); + } + return chain; + } + + /** + * 不等判定 + * + * @param value 值 + * @return 结果 + */ + @Override + public C ne(Object value) { + if (null != value) { + holder.with(adaptor -> adaptor.ne(column, value)); + } + return chain; + } + + /** + * 值介于两者之间 + * + * @param items 双值列表 + * @return 结果 + */ + @Override + public C between(List items) { + if (CollectionUtils.size(items) == 2) { + holder.with(adaptor -> adaptor.between(column, items)); + } + return chain; + } + + /** + * 模糊匹配,这里是全模糊 + * + * @param keyword 查询关键字 + * @return 结果 + */ + @Override + public C like(String keyword) { + if (StringUtils.isNotBlank(keyword)) { + holder.with(adaptor -> adaptor.like(column, keyword, Queries.Direction.ALL)); + } + return chain; + } + + /** + * 根据指定的方向进行模糊查询 + * + * @param keyword 关键字 + * @param direction 方向,可以匹配开头和结尾 + * @return 结果 + */ + @Override + public C like(String keyword, Queries.Direction direction) { + if (StringUtils.isNotBlank(keyword)) { + holder.with(adaptor -> adaptor.like(column, keyword, direction)); + } + return chain; + } + + /** + * 判定为空 + * + * @return 结果 + */ + @Override + public C isNull() { + holder.with(adaptor -> adaptor.isNull(column)); + return chain; + } + + /** + * 包含在内 + * + * @param list 集合 + * @return 结果 + */ + @Override + public C in(Collection list) { + if (CollectionUtils.isNotEmpty(list)) { + holder.with(adaptor -> adaptor.in(column, list)); + } + return chain; + } + + /** + * 包含在内 + * 注意,需要根据字段类型推断。 + * 如果是json数组,需要进行双向匹配 + * + * @param values 值们 + * @return 结果 + */ + @Override + public C in(Object... values) { + if (ArrayUtils.isNotEmpty(values)) { + holder.with(adaptor -> adaptor.in(column, values)); + } + return chain; + } + + /** + * 不包含在内 + * 注意,需要根据字段类型推断。 + * 如果是json数组,需要进行双向匹配 + * + * @param values 值们 + * @return 结果 + */ + @Override + public C nin(Object... values) { + if (ArrayUtils.isNotEmpty(values)) { + holder.with(adaptor -> adaptor.nin(column, values)); + } + return chain; + } + + /** + * 不包含在内 + * + * @param values 集合 + * @return 结果 + */ + @Override + public C nin(Collection values) { + if (CollectionUtils.isNotEmpty(values)) { + holder.with(adaptor -> adaptor.nin(column, values)); + } + return chain; + } + + /** + * 小于指定的值 + * + * @param value 类型 + * @return 结果 + */ + @Override + public C lt(Object value) { + if (null != value) { + holder.with(adaptor -> adaptor.lt(column, value)); + } + return chain; + } + + /** + * 小于等于指定的值 + * + * @param value 类型 + * @return 结果 + */ + @Override + public C lte(Object value) { + if (null != value) { + holder.with(adaptor -> adaptor.lte(column, value)); + } + return chain; + } + + /** + * 大于指定的值 + * + * @param value 类型 + * @return 结果 + */ + @Override + public C gt(Object value) { + if (null != value) { + holder.with(adaptor -> adaptor.gt(column, value)); + } + return chain; + } + + /** + * 大于等于指定的值 + * + * @param value 类型 + * @return 结果 + */ + @Override + public C gte(Object value) { + if (null != value) { + holder.with(adaptor -> adaptor.gte(column, value)); + } + return chain; + } +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultQueryMutation.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultQueryMutation.java new file mode 100644 index 0000000..ebe1916 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/chain/DefaultQueryMutation.java @@ -0,0 +1,120 @@ +package com.flyfish.framework.query.chain; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.query.*; +import com.flyfish.framework.query.support.DomainFunction; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * 默认的查询修改逻辑 + * + * @author wangyu + *

+ * 不修改原条件,而是在此基础上新增 + * 理论上查询不允许直接修改,而是通过该类做一个桥接 + * 也可以修改链的形式 + */ +@RequiredArgsConstructor +public class DefaultQueryMutation implements QueryMutation { + + private final QueryChain previous; + + private final boolean within; + + /** + * 以lambda的形式修改 + * 注意,如果之前用过lambda的形式,此处应该校验类型 + * + * @param getter 方法引用 + * @return 结果 + */ + @Override + public QueryCondition> and(DomainFunction getter) { + LambdaQueryChain newChain = new DefaultLambdaQueryChain<>(); + QueryCondition> condition = newChain.and(getter); + List> chains = Arrays.asList(previous, newChain); + previous.and(chains); + return condition; + } + + /** + * 以column的形式修改 + * + * @param column 列名 + * @return 结果 + */ + @Override + public QueryCondition and(String column) { + return null; + } + + /** + * 直接以and拼接其他的所有条件 + * + * @param chain 传入的查询 + * @return 结果 + */ + @Override + public LambdaQueryChain and(LambdaQueryChain chain) { + return null; + } + + /** + * 直接以and拼接其他的所有条件 + * + * @param chain 传入的查询 + * @return 结果 + */ + @Override + public NamedQueryChain and(NamedQueryChain chain) { + return null; + } + + /** + * 以lambda的形式修改 + * 注意,如果之前用过lambda的形式,此处应该校验类型 + * + * @param getter 方法引用 + * @return 结果 + */ + @Override + public QueryCondition> or(DomainFunction getter) { + return null; + } + + /** + * 以column的形式修改 + * + * @param column 列名 + * @return 结果 + */ + @Override + public QueryCondition or(String column) { + return null; + } + + /** + * 直接以or拼接其他的所有条件 + * + * @param chain 传入的查询 + * @return 结果 + */ + @Override + public LambdaQueryChain or(LambdaQueryChain chain) { + return null; + } + + /** + * 直接以or拼接其他的所有条件 + * + * @param chain 传入的查询 + * @return 结果 + */ + @Override + public NamedQueryChain or(NamedQueryChain chain) { + return null; + } +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/holder/QueryChainHolder.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/holder/QueryChainHolder.java new file mode 100644 index 0000000..71afc87 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/holder/QueryChainHolder.java @@ -0,0 +1,45 @@ +package com.flyfish.framework.query.holder; + +import com.flyfish.framework.query.spi.adaptor.CriteriaAdaptor; + +import java.util.function.BinaryOperator; +import java.util.function.Function; + +/** + * 查询链保持器,将所有拼接工作后置,可以做检查和处理 + * + * @author wangyu + */ +public interface QueryChainHolder { + + /** + * 等待下一步消费 + * 如果不调用with,该状态将一直保持,可被其他link调用替换 + * 在调用with后,自动消费,并完成拼接 + * + * @param operator 操作方法 + * @return 本身 + */ + QueryChainHolder link(Function, BinaryOperator> operator); + + /** + * 拼接条件 + * + * @param criteria 条件 + */ + void with(Function, C> criteria); + + /** + * 触发动作,得到最终的 + * + * @return 本身 + */ + C get(CriteriaAdaptor adaptor); + + /** + * 判断条件是否为空 + * + * @return 结果 + */ + boolean isEmpty(); +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/QueryChainFactory.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/QueryChainFactory.java new file mode 100644 index 0000000..d216822 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/QueryChainFactory.java @@ -0,0 +1,22 @@ +package com.flyfish.framework.query.spi; + +import com.flyfish.framework.query.QueryChain; +import com.flyfish.framework.utils.Supportable; + +/** + * 查询链创建抽象泛型工厂 + * 基于spi提供实现类,最终返回真正实例化的内容 + * 根据引入的jar包自动加载,无需手动处理 + * + * @author wangyu + */ +public interface QueryChainFactory> extends Supportable> { + + /** + * 生产适配器 + * 此接口为高度抽象接口,目的是兼容更多的查询链类型,便于后续扩展 + * + * @return 生产结果 + */ + C produce(); +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/QueryFactory.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/QueryFactory.java new file mode 100644 index 0000000..32fa546 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/QueryFactory.java @@ -0,0 +1,31 @@ +package com.flyfish.framework.query.spi; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.query.spi.adaptor.CriteriaAdaptor; +import com.flyfish.framework.query.spi.converter.QueryConverter; +import com.flyfish.framework.utils.Supportable; +import org.springframework.data.repository.core.EntityInformation; + +/** + * 查询工厂,提供统一的实例 + * + * @param 查询条件对象泛型 + * @param 查询对象泛型 + * @author wangyu + */ +public interface QueryFactory extends Supportable> { + + /** + * 获取查询转换器 + * + * @return 结果 + */ + QueryConverter getConverter(); + + /** + * 获取查询适配器 + * + * @return 结果 + */ + CriteriaAdaptor getAdaptor(); +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/adaptor/CriteriaAdaptor.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/adaptor/CriteriaAdaptor.java new file mode 100644 index 0000000..4326283 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/adaptor/CriteriaAdaptor.java @@ -0,0 +1,180 @@ +package com.flyfish.framework.query.spi.adaptor; + +import com.flyfish.framework.query.Queries; + +import java.util.Collection; +import java.util.List; + +/** + * 查询适配器 + * 直接根据条件操作得到查询条件片段 + * 适配不同的数据库抽取通用操作 + * + * @author wangyu + * 由工厂进行实例化,并输出 + */ +public interface CriteriaAdaptor { + + /** + * 且的关系进行拼接 + * + * @param first 起始条件 + * @param other 其他条件 + * @return 结果 + */ + C and(C first, C other); + + /** + * 或的关系进行拼接 + * + * @param first 起始条件 + * @param other 其他条件 + * @return 结果 + */ + C or(C first, C other); + + /** + * 相等判定 + * + * @param column 列名 + * @param value 值 + * @return 结果 + */ + C eq(String column, Object value); + + /** + * 判定某列的值中存在指定值,特指json array数据类型且子类型中带有id的场景 + * 用于兼容mongodb查询,mysql查询使用JSON_CONTAINS进行判定。 + * 当且仅当mongodb会拼接.$id,mysql一律匹配id字段 + *

+ * 等价于 .eq(value) + * + * @param column 列名 + * @param value 值 + * @return 结果 + */ + C hasId(String column, Object value); + + /** + * 对于mongodb,自动处理。对于关系型数据库,代表json array中是否包含对应值,值仅支持基本数据类型 + *

+ * 等价于 .eq(value) + * + * @param column 列名 + * @param value 基本数据类型的值 + * @return 结果 + */ + C has(String column, Object value); + + /** + * 不等判定 + * + * @param column 列名 + * @param value 值 + * @return 结果 + */ + C ne(String column, Object value); + + /** + * 值介于两者之间 + * + * @param column 列名 + * @param items 双值列表 + * @return 结果 + */ + C between(String column, List items); + + /** + * 根据指定的方向进行模糊查询 + * + * @param column 列名 + * @param keyword 关键字 + * @param direction 方向,可以匹配开头和结尾 + * @return 结果 + */ + C like(String column, String keyword, Queries.Direction direction); + + /** + * 判定为空 + * + * @param column 列名 + * @return 结果 + */ + C isNull(String column); + + /** + * 小于指定的值 + * + * @param column 列名 + * @param value 类型 + * @return 结果 + */ + C lt(String column, Object value); + + /** + * 小于等于指定的值 + * + * @param column 列名 + * @param value 类型 + * @return 结果 + */ + C lte(String column, Object value); + + /** + * 大于指定的值 + * + * @param column 列名 + * @param value 类型 + * @return 结果 + */ + C gt(String column, Object value); + + /** + * 大于等于指定的值 + * + * @param column 列名 + * @param value 类型 + * @return 结果 + */ + C gte(String column, Object value); + + /** + * 包含在内 + * + * @param column 列名 + * @param values 集合 + * @return 结果 + */ + C in(String column, Collection values); + + /** + * 包含在内 + * 注意,需要根据字段类型推断。 + * 如果是json数组,需要进行双向匹配 + * + * @param column 列名 + * @param values 值们 + * @return 结果 + */ + C in(String column, Object... values); + + /** + * 不包含在内 + * 注意,需要根据字段类型推断。 + * 如果是json数组,需要进行双向匹配 + * + * @param column 列名 + * @param values 值们 + * @return 结果 + */ + C nin(String column, Object... values); + + /** + * 不包含在内 + * + * @param column 列名 + * @param values 集合 + * @return 结果 + */ + C nin(String column, Collection values); +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/converter/QueryConverter.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/converter/QueryConverter.java new file mode 100644 index 0000000..ca7cb9f --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/converter/QueryConverter.java @@ -0,0 +1,19 @@ +package com.flyfish.framework.query.spi.converter; + +import com.flyfish.framework.query.Query; + +/** + * 原生查询转换器 + * + * @author wangyu + */ +public interface QueryConverter { + + /** + * 转换查询 + * + * @param query 封装的查询 + * @return 本地查询 + */ + T convert(Query query); +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/DomainFunction.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/DomainFunction.java new file mode 100644 index 0000000..21aa93a --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/DomainFunction.java @@ -0,0 +1,21 @@ +package com.flyfish.framework.query.support; + +import com.flyfish.framework.domain.base.Domain; + +/** + * 支持序列化的实体方法 + * + * @param 泛型,父类为实体 + */ +@FunctionalInterface +public interface DomainFunction extends SFunction { + + /** + * 快速获取名称 + * + * @return 序列化后的名称 + */ + default String getName() { + return EntityNameUtils.getName(this); + } +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/EntityNameUtils.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/EntityNameUtils.java new file mode 100644 index 0000000..5bc9dcc --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/EntityNameUtils.java @@ -0,0 +1,170 @@ +package com.flyfish.framework.query.support; + + +import com.flyfish.framework.annotations.Property; +import com.flyfish.framework.utils.LRUCache; +import org.springframework.core.annotation.MergedAnnotations; +import org.springframework.util.ReflectionUtils; +import org.springframework.util.StringUtils; + +import java.lang.ref.WeakReference; +import java.lang.reflect.Field; +import java.security.InvalidParameterException; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + +public class EntityNameUtils { + + // SerializedLambda 反序列化缓存 + private static final Map> FUNC_CACHE = new ConcurrentHashMap<>(); + + // 列别名缓存 + private static final Map, Map> COLUMN_CACHE = new LRUCache<>(5); + + private static final String MONGO_FIELD = "org.springframework.data.mongodb.core.mapping.Field"; + + private static final String RELATIONAL_COLUMN = "org.springframework.data.relational.core.mapping.Column"; + + /** + * 方法转为属性 + * + * @param name 方法名称 + * @return 最终属性 + */ + public static String methodToProperty(String name) { + if (name.startsWith("is")) { + name = name.substring(2); + } else { + if (!name.startsWith("get") && !name.startsWith("set")) { + throw new InvalidParameterException("不是正确的getter或setter"); + } + name = name.substring(3); + } + if (name.length() == 1 || name.length() > 1 && !Character.isUpperCase(name.charAt(1))) { + name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1); + } + return name; + } + + /** + * 将驼峰命名转化成下划线 + * + * @param param 参数 + * @return 结果 + */ + public static String camelToUnderline(String param) { + if (param.length() < 3) { + return param.toLowerCase(); + } + StringBuilder sb = new StringBuilder(param); + int temp = 0;//定位 + //从第三个字符开始 避免命名不规范 + for (int i = 2; i < param.length(); i++) { + if (Character.isUpperCase(param.charAt(i))) { + sb.insert(i + temp, "_"); + temp += 1; + } + } + return sb.toString().toLowerCase(); + } + + /** + * 解析列并使用处理函数处理 + * + * @param func 方法引用 + * @param 实体泛型 + * @return 处理结果 + */ + public static String getName(SFunction func) { + SerializedLambda lambda = resolve(func); + String property = methodToProperty(lambda.getImplMethodName()); + Class beanClass = resolveEntityClass(lambda); + return tryCache(beanClass).getOrDefault(property, property); + } + + /** + * 解析获得实体类 + * + * @param lambda 序列化的lambda + * @return 最终获取的类 + */ + private static Class resolveEntityClass(SerializedLambda lambda) { + Class type = lambda.getInstantiatedType(); + tryCache(type); + return type; + } + + /** + * 尝试缓存 + * + * @param entityClass bean的类型 + */ + private static Map tryCache(Class entityClass) { + return COLUMN_CACHE.computeIfAbsent(entityClass, EntityNameUtils::buildFieldsCache); + } + + + /** + * 构建字段缓存 + * + * @param type 类型 + * @return 构建后的缓存 + */ + private static Map buildFieldsCache(Class type) { + Map fields = new HashMap<>(); + ReflectionUtils.doWithFields(type, field -> fields.put(field.getName(), resolveFinalName(field))); + return fields; + } + + + /** + * 解析字段注解或直接取用下划线逻辑 + * + * @return 解析结果 + */ + private static String resolveFinalName(Field field) { + MergedAnnotations annotations = MergedAnnotations.from(field); + if (annotations.isPresent(Property.class)) { + String key = annotations.get(Property.class).getString("key"); + if (StringUtils.hasText(key)) { + return key; + } + } + if (annotations.isPresent(MONGO_FIELD)) { + String name = annotations.get(MONGO_FIELD).getString("name"); + if (StringUtils.hasText(name)) { + return name; + } + } + if (annotations.isPresent(RELATIONAL_COLUMN)) { + String name = annotations.get(RELATIONAL_COLUMN).getString("value"); + if (StringUtils.hasText(name)) { + return name; + } + } + return field.getName(); + } + + /** + * 解析方法引用为序列化lambda实例 + * 该方式会使用缓存 + * + * @param func 方法引用 + * @param 泛型 + * @return 解析结果 + */ + private static SerializedLambda resolve(SFunction func) { + Class clazz = func.getClass(); + String name = clazz.getName(); + return Optional.ofNullable(FUNC_CACHE.get(name)) + .map(WeakReference::get) + .orElseGet(() -> { + SerializedLambda lambda = SerializedLambda.resolve(func); + FUNC_CACHE.put(name, new WeakReference<>(lambda)); + return lambda; + }); + } +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/SFunction.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/SFunction.java new file mode 100644 index 0000000..ccffeb9 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/SFunction.java @@ -0,0 +1,14 @@ +package com.flyfish.framework.query.support; + +import java.io.Serializable; +import java.util.function.Function; + +/** + * 支持序列化的function + * + * @param 泛型入参 + * @param 泛型返回值 + */ +@FunctionalInterface +public interface SFunction extends Function, Serializable { +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/SerializedLambda.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/SerializedLambda.java new file mode 100644 index 0000000..574a027 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/SerializedLambda.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2011-2021, baomidou (jobob@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.flyfish.framework.query.support; + +import lombok.Getter; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; +import org.springframework.util.SerializationUtils; + +import java.io.*; + +/** + * 这个类是从 {@link java.lang.invoke.SerializedLambda} 里面 copy 过来的, + * 字段信息完全一样 + *

负责将一个支持序列的 Function 序列化为 SerializedLambda

+ * + * @author mbp + */ +@SuppressWarnings("unused") +class SerializedLambda implements Serializable { + + private static final long serialVersionUID = 8025925345765570181L; + + private Class capturingClass; + private String functionalInterfaceClass; + private String functionalInterfaceMethodName; + private String functionalInterfaceMethodSignature; + private String implClass; + /** + * -- GETTER -- + * 获取实现者的方法名称 + * + * @return 方法名称 + */ + @Getter + private String implMethodName; + private String implMethodSignature; + private int implMethodKind; + private String instantiatedMethodType; + private Object[] capturedArgs; + + /** + * 通过反序列化转换 lambda 表达式,该方法只能序列化 lambda 表达式,不能序列化接口实现或者正常非 lambda 写法的对象 + * + * @param lambda lambda对象 + * @return 返回解析后的 SerializedLambda + */ + public static SerializedLambda resolve(SFunction lambda) { + Assert.isTrue(lambda.getClass().isSynthetic(), "该方法仅能传入 lambda 表达式产生的合成类"); + byte[] stream = SerializationUtils.serialize(lambda); + Assert.notNull(stream, "序列化类失败!"); + try (ObjectInputStream objIn = new ObjectInputStream(new ByteArrayInputStream(stream)) { + @Override + protected Class resolveClass(ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException { + Class clazz; + try { + clazz = forName(objectStreamClass.getName()); + } catch (Exception ex) { + clazz = super.resolveClass(objectStreamClass); + } + return clazz == java.lang.invoke.SerializedLambda.class ? SerializedLambda.class : clazz; + } + }) { + return (SerializedLambda) objIn.readObject(); + } catch (ClassNotFoundException | IOException e) { + throw new NullPointerException("不应该发生这件事"); + } + } + + /** + * 以类名实例化类,会隐藏报错,需要在确定有该类的情况下调用 + * + * @param name 类型 + * @return 实例 + */ + private static Class forName(String name) { + try { + return ClassUtils.forName(name, null); + } catch (ClassNotFoundException e) { + return null; + } + } + + /** + * 获取接口 class + * + * @return 返回 class 名称 + */ + public String getFunctionalInterfaceClassName() { + return normalizedName(functionalInterfaceClass); + } + + /** + * 获取实现的 class + * + * @return 实现类 + */ + public Class getImplClass() { + return forName(getImplClassName()); + } + + /** + * 获取 class 的名称 + * + * @return 类名 + */ + public String getImplClassName() { + return normalizedName(implClass); + } + + /** + * 正常化类名称,将类名称中的 / 替换为 . + * + * @param name 名称 + * @return 正常的类名 + */ + private String normalizedName(String name) { + return name.replace('/', '.'); + } + + /** + * @return 获取实例化方法的类型 + */ + public Class getInstantiatedType() { + String instantiatedTypeName = normalizedName(instantiatedMethodType.substring(2, instantiatedMethodType.indexOf(';'))); + return forName(instantiatedTypeName); + } + + /** + * @return 字符串形式 + */ + @Override + public String toString() { + String interfaceName = getFunctionalInterfaceClassName(); + String implName = getImplClassName(); + return String.format("%s -> %s::%s", + interfaceName.substring(interfaceName.lastIndexOf('.') + 1), + implName.substring(implName.lastIndexOf('.') + 1), + implMethodName); + } + +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/DefaultReactiveRepository.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/DefaultReactiveRepository.java new file mode 100644 index 0000000..19ded1c --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/DefaultReactiveRepository.java @@ -0,0 +1,50 @@ +package com.flyfish.framework.repository; + +import com.flyfish.framework.repository.base.DomainRepository; +import org.reactivestreams.Publisher; +import org.springframework.data.repository.NoRepositoryBean; +import org.springframework.data.repository.reactive.ReactiveCrudRepository; +import org.springframework.lang.NonNull; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + + +/** + * 默认的持久层dao + * + * @param 泛型 + */ +@NoRepositoryBean +public interface DefaultReactiveRepository extends ReactiveCrudRepository, ReactiveQueryModelExecutor, DomainRepository { + + /** + * 插入给定的实体. 假设该实体是新的,以便应用插入优化。 + * 使用返回的实例进行后续操作,因为保存操作可能会完全改变实体实例。 + * 建议使用 {@link #save(Object)} 来避免使用特定存储的 API。 + * + * @param entity 要插入的实体,不能为空 + * @return 保存后的实体 + */ + @NonNull + Mono insert(@NonNull S entity); + + /** + * 插入给定的实体列表. 假设这些实体是新的,以便应用插入优化。 + * 使用返回的实例进行后续操作,因为保存操作可能会完全改变实体实例。 + * 建议使用 {@link #save(Object)} 来避免使用特定存储的 API。 + * + * @param entities 实体列表,不能为空 + * @return 保存后的实体列表 + */ + Flux insert(Iterable entities); + + /** + * 插入给定的实体发布者发布的实体. 假设这些实体是新的,以便应用插入优化。 + * 使用返回的实例进行后续操作,因为保存操作可能会完全改变实体实例。 + * 建议使用 {@link #save(Object)} 来避免使用特定存储的 API。 + * + * @param entities 发布的实体列表,不能为空 + * @return 保存后的实体列表 + */ + Flux insert(Publisher entities); +} diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/DefaultRepository.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/DefaultRepository.java new file mode 100644 index 0000000..dea4ad7 --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/DefaultRepository.java @@ -0,0 +1,53 @@ +package com.flyfish.framework.repository; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.repository.base.DomainRepository; +import org.springframework.data.domain.Sort; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.NoRepositoryBean; +import org.springframework.data.repository.PagingAndSortingRepository; + +import java.util.List; + +/** + * 默认的仓库 + * + * @author wangyu + */ +@NoRepositoryBean +public interface DefaultRepository extends CrudRepository, PagingAndSortingRepository, + QueryModelExecutor, + DomainRepository { + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.CrudRepository#saveAll(java.lang.Iterable) + */ + @Override + List saveAll(Iterable entities); + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.CrudRepository#findAll() + */ + @Override + List findAll(); + + /** + * 插入新对象 + * + * @param entity 实体 + * @param 泛型 + * @return 插入的实体,带id + */ + S insert(S entity); + + /** + * 批量插入对象 + * + * @param entities 对象列表 + * @param 泛型 + * @return 结果列表 + */ + List insert(Iterable entities); +} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/QueryModelExecutor.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/QueryModelExecutor.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/repository/QueryModelExecutor.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/QueryModelExecutor.java diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/ReactiveEntityOperations.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/ReactiveEntityOperations.java new file mode 100644 index 0000000..b7ad5fe --- /dev/null +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/ReactiveEntityOperations.java @@ -0,0 +1,60 @@ +package com.flyfish.framework.repository; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.query.Queries; +import com.flyfish.framework.query.Query; +import org.springframework.data.repository.core.EntityInformation; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * 高层封装的模型操作 + * + * @author wangyu + */ +public interface ReactiveEntityOperations { + + /** + * 查询,通过查询条件和类进行精确查询 + * + * @param query 查询 + * @param entityInformation 实体信息 + * @param 实体类的实例化结果 + * @param 实体信息具体实现类 + * @return 查询结果 + */ + > Mono find(Query query, E entityInformation); + + /** + * 查询全部符合条件的实体 + * + * @param query 查询 + * @param entityInformation 实体信息 + * @param 实体类的实例化结果 + * @param 实体信息具体实现类 + * @return 结果 + */ + > Flux findAll(Query query, E entityInformation); + + /** + * 保存实体 + * + * @param bean 实体 + * @param 实体类的实例化结果 + * @return 结果 + */ + Mono save(T bean); + + /** + * 转换为原生查询 + * + * @param query 查询 + * @param entityInformation 实体信息 + * @param 泛型,原生查询类型 + * @param 泛型,实体类型 + * @return 结果 + */ + default R toNative(Query query, EntityInformation entityInformation) { + return Queries.convert(query, entityInformation); + } +} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/ReactiveQueryModelExecutor.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/ReactiveQueryModelExecutor.java similarity index 94% rename from flyfish-data/src/main/java/com/flyfish/framework/repository/ReactiveQueryModelExecutor.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/ReactiveQueryModelExecutor.java index ff30e7e..8f91404 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/repository/ReactiveQueryModelExecutor.java +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/ReactiveQueryModelExecutor.java @@ -31,8 +31,7 @@ public interface ReactiveQueryModelExecutor { * * @param query must not be {@literal null}. * @return a single entity matching the given {@link Qo} or {@link Optional#empty()} if none was found. - * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the Qo yields more than one - * result. + * result. */ Mono findOne(Qo query); diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/base/DomainRepository.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/base/DomainRepository.java similarity index 60% rename from flyfish-data/src/main/java/com/flyfish/framework/repository/base/DomainRepository.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/base/DomainRepository.java index cc2fba6..348babc 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/repository/base/DomainRepository.java +++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/base/DomainRepository.java @@ -1,6 +1,6 @@ package com.flyfish.framework.repository.base; -import org.springframework.data.mongodb.repository.query.MongoEntityInformation; +import org.springframework.data.repository.core.EntityInformation; /** * 标记实体的仓库 @@ -14,5 +14,5 @@ public interface DomainRepository { * * @return 结果 */ - MongoEntityInformation getEntityInformation(); + EntityInformation getEntityInformation(); } diff --git a/flyfish-data/src/main/java/com/flyfish/framework/utils/CopyUtils.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/utils/CopyUtils.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/utils/CopyUtils.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/utils/CopyUtils.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/utils/DataUtils.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/utils/DataUtils.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/utils/DataUtils.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/utils/DataUtils.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/utils/DateRangeUtil.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/utils/DateRangeUtil.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/utils/DateRangeUtil.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/utils/DateRangeUtil.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/utils/DepartUtils.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/utils/DepartUtils.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/utils/DepartUtils.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/utils/DepartUtils.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/utils/FieldUtils.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/utils/FieldUtils.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/utils/FieldUtils.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/utils/FieldUtils.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/utils/HexUtils.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/utils/HexUtils.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/utils/HexUtils.java rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/utils/HexUtils.java diff --git a/flyfish-data/flyfish-data-domain/pom.xml b/flyfish-data/flyfish-data-domain/pom.xml new file mode 100644 index 0000000..57248f8 --- /dev/null +++ b/flyfish-data/flyfish-data-domain/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + com.flyfish.framework + flyfish-data + ${revision} + + + flyfish-data-domain + + + 8 + 8 + UTF-8 + + + + + com.flyfish.framework + flyfish-common + + + org.springframework.data + spring-data-relational + true + + + org.springframework.data + spring-data-mongodb + true + + + io.projectreactor + reactor-core + true + + + org.apache.commons + commons-lang3 + + + + diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/CodeRule.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/CodeRule.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/CodeRule.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/CodeRule.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/ComputedProps.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/ComputedProps.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/ComputedProps.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/ComputedProps.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/ConditionOn.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/ConditionOn.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/ConditionOn.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/ConditionOn.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/DBRefValue.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/DBRefValue.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/DBRefValue.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/DBRefValue.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/DateRange.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/DateRange.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/DateRange.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/DateRange.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/DictValue.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/DictValue.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/DictValue.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/DictValue.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/EnumValue.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/EnumValue.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/EnumValue.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/EnumValue.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/FormItem.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/FormItem.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/FormItem.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/FormItem.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/Generation.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/Generation.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/Generation.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/Generation.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/MappedTo.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/MappedTo.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/MappedTo.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/MappedTo.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/Operation.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/Operation.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/Operation.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/Operation.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/Order.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/Order.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/Order.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/Order.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/Properties.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/Properties.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/Properties.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/Properties.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/Property.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/Property.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/Property.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/Property.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/PropertyGroup.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/PropertyGroup.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/PropertyGroup.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/PropertyGroup.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/PropertyGroups.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/PropertyGroups.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/PropertyGroups.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/PropertyGroups.java diff --git a/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/query/QueryField.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/query/QueryField.java new file mode 100644 index 0000000..bf1c978 --- /dev/null +++ b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/annotations/query/QueryField.java @@ -0,0 +1,100 @@ +package com.flyfish.framework.annotations.query; + +import com.flyfish.framework.enums.NamedEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.core.annotation.AliasFor; + +import java.lang.annotation.*; + +/** + * 查询字段注解,声明映射,查询逻辑 + * + * @author wangyu + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface QueryField { + + /** + * @return 绑定的持久层字段 + */ + @AliasFor("name") + String value() default ""; + + /** + * @return 绑定的持久层字段 + */ + String name() default ""; + + /** + * @return 表达式类型 + */ + Type type() default Type.EQ; + + /** + * 拼接在某个字段前 + * + * @return + */ + String before() default ""; + + /** + * @return 和前面条件表达式的连接方式 + */ + Logistic[] start() default Logistic.AND; + + /** + * @return 和后面条件表达式的连接方式 + */ + Logistic[] end() default Logistic.NULL; + + /** + * @return 当前类内排序值 + */ + int order() default 0; + + /** + * 查询类型 + */ + @AllArgsConstructor + @Getter + enum Type implements NamedEnum { + + EQ("等于字段值"), + NE("不等于字段值"), + GT("大于字段值"), + GTE("大于等于字段值"), + LT("小于字段值"), + LTE("小于等于字段值"), + LIKE("模糊匹配字段值"), + LIKE_LEFT("匹配左半部分字段值"), + LIKE_RIGHT("匹配有半部分字段值"), + IN("在字段值列表内"), + NIN("不再字段值列表内"), + NOT_NULL("不为空"), + IS_NULL("为空"), + BETWEEN("介于列表下标0和1的值之间"), + DATE_GTE("日期大于字段值"), + DATE_LTE("日期小于字段值"); + + private final String name; + } + + /** + * 查询逻辑 + */ + @AllArgsConstructor + @Getter + enum Logistic implements NamedEnum { + + NULL("无"), + AND("与"), + OR("或"), + BRACKET_START("左括号"), + BRACKET_END("右括号"); + + private final String name; + } +} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/context/ViewModelContext.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/context/ViewModelContext.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/context/ViewModelContext.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/context/ViewModelContext.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/context/interceptor/ViewModelInterceptor.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/context/interceptor/ViewModelInterceptor.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/context/interceptor/ViewModelInterceptor.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/context/interceptor/ViewModelInterceptor.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedDomain.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedDomain.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedDomain.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedDomain.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedUserDetails.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedUserDetails.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedUserDetails.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedUserDetails.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedVo.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedVo.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedVo.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedVo.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/advanced/OwnedAuthorizedDomain.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/authorized/advanced/OwnedAuthorizedDomain.java similarity index 89% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/advanced/OwnedAuthorizedDomain.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/authorized/advanced/OwnedAuthorizedDomain.java index a10877c..028ad60 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/advanced/OwnedAuthorizedDomain.java +++ b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/authorized/advanced/OwnedAuthorizedDomain.java @@ -6,6 +6,7 @@ import com.flyfish.framework.domain.authorized.AuthorizedDomain; import com.flyfish.framework.domain.po.User; import lombok.Getter; import lombok.Setter; +import org.springframework.data.annotation.Reference; import org.springframework.data.mongodb.core.mapping.DBRef; import java.util.List; @@ -22,7 +23,7 @@ public abstract class OwnedAuthorizedDomain extends AuthorizedDomain { // 关联账号 @Property("关联账号") @Order(Integer.MAX_VALUE) - @DBRef + @Reference(User.class) private List owners; } diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/AuditDomain.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/AuditDomain.java similarity index 94% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/base/AuditDomain.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/AuditDomain.java index df243c0..4fde435 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/AuditDomain.java +++ b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/AuditDomain.java @@ -7,7 +7,6 @@ import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.mongodb.core.mapping.Document; import java.util.Date; @@ -16,7 +15,6 @@ import java.util.Date; * * @author wangyu */ -@Document @Getter @Setter public abstract class AuditDomain extends Domain { diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/Domain.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/Domain.java similarity index 95% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/base/Domain.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/Domain.java index 8871938..330f701 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/Domain.java +++ b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/Domain.java @@ -10,12 +10,11 @@ import lombok.Setter; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Transient; import org.springframework.data.mongodb.core.index.Indexed; -import org.springframework.data.mongodb.core.mapping.Document; +import javax.persistence.Index; import javax.validation.constraints.NotBlank; import java.io.Serializable; -@Document @Getter @Setter public abstract class Domain implements Po, Named, Serializable { @@ -32,6 +31,7 @@ public abstract class Domain implements Po, Named, Serializable { /** * 编号 */ + @Indexed(unique = true) @Property(title = "编码", inherited = true) @NotBlank(message = "编码不可为空", groups = CodeValid.class) @Generation(Generation.Strategy.CODE) @@ -40,7 +40,6 @@ public abstract class Domain implements Po, Named, Serializable { /** * 名称 */ - @Indexed @Property(title = "名称", inherited = true) @NotBlank(message = "名称不可为空", groups = NameValid.class) @Generation(Generation.Strategy.NAME) diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/DomainService.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/DomainService.java similarity index 54% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/base/DomainService.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/DomainService.java index d53943a..b41bd41 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/DomainService.java +++ b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/DomainService.java @@ -1,6 +1,6 @@ package com.flyfish.framework.domain.base; -import org.springframework.data.mongodb.repository.query.MongoEntityInformation; +import org.springframework.data.repository.core.EntityInformation; /** * 占位,标记service @@ -12,5 +12,5 @@ public interface DomainService { * * @return 结果 */ - MongoEntityInformation getEntityInformation(); + EntityInformation getEntityInformation(); } diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/Dto.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/Dto.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/base/Dto.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/Dto.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/IUser.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/IUser.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/base/IUser.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/IUser.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/Named.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/Named.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/base/Named.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/Named.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/Po.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/Po.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/base/Po.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/Po.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/Qo.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/Qo.java similarity index 79% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/base/Qo.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/Qo.java index 50e3ace..d4c2a48 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/Qo.java +++ b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/Qo.java @@ -4,9 +4,10 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import org.springframework.data.domain.Example; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; -import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.repository.core.EntityInformation; import java.util.List; +import java.util.Optional; /** * 查询模型 @@ -66,12 +67,13 @@ public interface Qo { Example getExample(); /** - * 获取data-mongo的对象Predicate + * 获取spring data的对象Predicate * + * @param entityInformation 实体信息,来自上下文 * @return 结果 */ @JsonIgnore - Criteria getCriteria(); + Optional getQuery(EntityInformation entityInformation); /** * 获取查询的字段 @@ -96,13 +98,9 @@ public interface Qo { Sort sorts(); /** - * 判断查询是否为空 + * 判断当前查询是否为空 * * @return 结果 */ - default boolean isEmpty() { - Criteria criteria = getCriteria(); - Example example = getExample(); - return example == null && (null == criteria.getCriteriaObject() || criteria.getCriteriaObject().size() == 0); - } + boolean isEmpty(); } diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/Vo.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/Vo.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/base/Vo.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/base/Vo.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/po/Department.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/po/Department.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/po/Department.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/po/Department.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/po/ExcelMapping.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/po/ExcelMapping.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/po/ExcelMapping.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/po/ExcelMapping.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/po/Permission.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/po/Permission.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/po/Permission.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/po/Permission.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/po/Role.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/po/Role.java similarity index 93% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/po/Role.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/po/Role.java index ca2a85c..8423660 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/po/Role.java +++ b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/po/Role.java @@ -4,7 +4,7 @@ import com.flyfish.framework.domain.base.AuditDomain; import com.flyfish.framework.enums.NamedEnum; import com.flyfish.framework.enums.RoleType; import lombok.*; -import org.springframework.data.mongodb.core.mapping.DBRef; +import org.springframework.data.annotation.Reference; import org.springframework.data.mongodb.core.mapping.Document; import java.util.List; @@ -45,7 +45,7 @@ public class Role extends AuditDomain { /** * 角色拥有的权限 */ - @DBRef + @Reference(Permission.class) private List permissions; /** diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/po/User.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/po/User.java similarity index 95% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/po/User.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/po/User.java index e823dc3..66d3a0e 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/po/User.java +++ b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/po/User.java @@ -8,9 +8,9 @@ import com.flyfish.framework.enums.UserStatus; import com.flyfish.framework.enums.UserType; import com.flyfish.framework.validation.spi.ConditionalGroup; import lombok.*; +import org.springframework.data.annotation.Reference; import org.springframework.data.annotation.Transient; import org.springframework.data.mongodb.core.index.Indexed; -import org.springframework.data.mongodb.core.mapping.DBRef; import org.springframework.data.mongodb.core.mapping.Document; import java.util.Date; @@ -73,13 +73,13 @@ public class User extends AuditDomain implements IUser { /** * 可操作校区 */ - @DBRef + @Reference(Department.class) private List departments; /** * 所属角色 */ - @DBRef + @Reference(Role.class) private List roles; /** diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/tree/RootTreeNode.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/tree/RootTreeNode.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/tree/RootTreeNode.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/tree/RootTreeNode.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/tree/TreeDomain.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/tree/TreeDomain.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/domain/tree/TreeDomain.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/domain/tree/TreeDomain.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/generation/CodeRuleStrategy.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/generation/CodeRuleStrategy.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/generation/CodeRuleStrategy.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/generation/CodeRuleStrategy.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/generation/CodeRules.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/generation/CodeRules.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/generation/CodeRules.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/generation/CodeRules.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/generation/strategy/TransactionCodeRuleStrategy.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/generation/strategy/TransactionCodeRuleStrategy.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/generation/strategy/TransactionCodeRuleStrategy.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/generation/strategy/TransactionCodeRuleStrategy.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/generation/strategy/UUIDCodeRuleStrategy.java b/flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/generation/strategy/UUIDCodeRuleStrategy.java similarity index 100% rename from flyfish-data/src/main/java/com/flyfish/framework/generation/strategy/UUIDCodeRuleStrategy.java rename to flyfish-data/flyfish-data-domain/src/main/java/com/flyfish/framework/generation/strategy/UUIDCodeRuleStrategy.java diff --git a/flyfish-data/flyfish-data-mongodb/pom.xml b/flyfish-data/flyfish-data-mongodb/pom.xml new file mode 100644 index 0000000..9a1885c --- /dev/null +++ b/flyfish-data/flyfish-data-mongodb/pom.xml @@ -0,0 +1,35 @@ + + + + flyfish-data + com.flyfish.framework + ${revision} + + 4.0.0 + + flyfish-data-mongodb + + + 8 + 8 + + + + + org.springframework.boot + spring-boot-starter-data-mongodb-reactive + + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + + com.flyfish.framework + flyfish-data-common + + + diff --git a/flyfish-data/src/main/java/com/flyfish/framework/builder/CriteriaBuilder.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/builder/CriteriaBuilder.java similarity index 99% rename from flyfish-data/src/main/java/com/flyfish/framework/builder/CriteriaBuilder.java rename to flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/builder/CriteriaBuilder.java index b84cdc4..c232000 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/builder/CriteriaBuilder.java +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/builder/CriteriaBuilder.java @@ -1,4 +1,4 @@ -package com.flyfish.framework.builder; +package com.flyfish.framework.mongodb.builder; import com.flyfish.framework.context.DateContext; import com.flyfish.framework.domain.base.Domain; diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/config/MongoDataConfig.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/config/MongoDataConfig.java new file mode 100644 index 0000000..ccefb06 --- /dev/null +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/config/MongoDataConfig.java @@ -0,0 +1,27 @@ +package com.flyfish.framework.mongodb.config; + +import com.flyfish.framework.mongodb.operations.MongoReactiveEntityOperations; +import com.flyfish.framework.mongodb.repository.factory.DefaultRepositoryFactoryBean; +import com.flyfish.framework.mongodb.repository.impl.DefaultRepositoryImpl; +import com.flyfish.framework.repository.ReactiveEntityOperations; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.config.EnableMongoAuditing; +import org.springframework.data.mongodb.core.ReactiveMongoOperations; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; + +@EnableMongoRepositories( + repositoryFactoryBeanClass = DefaultRepositoryFactoryBean.class, + repositoryBaseClass = DefaultRepositoryImpl.class +) +@EnableMongoAuditing +@Configuration +public class MongoDataConfig { + + @Bean + @ConditionalOnBean(ReactiveMongoOperations.class) + public ReactiveEntityOperations mongoReactiveEntityOperations(ReactiveMongoOperations reactiveMongoOperations) { + return new MongoReactiveEntityOperations(reactiveMongoOperations); + } +} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/EnableMongoRepo.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/config/annotations/EnableMongoRepo.java similarity index 76% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/EnableMongoRepo.java rename to flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/config/annotations/EnableMongoRepo.java index ce3d182..d41e37e 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/annotations/EnableMongoRepo.java +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/config/annotations/EnableMongoRepo.java @@ -1,7 +1,7 @@ -package com.flyfish.framework.annotations; +package com.flyfish.framework.mongodb.config.annotations; -import com.flyfish.framework.repository.factory.DefaultRepositoryFactoryBean; -import com.flyfish.framework.repository.impl.DefaultRepositoryImpl; +import com.flyfish.framework.mongodb.repository.factory.DefaultRepositoryFactoryBean; +import com.flyfish.framework.mongodb.repository.impl.DefaultRepositoryImpl; import org.springframework.core.annotation.AliasFor; import org.springframework.data.mongodb.config.EnableMongoAuditing; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; diff --git a/flyfish-data/src/main/java/com/flyfish/framework/annotations/EnableReactiveMongoRepo.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/config/annotations/EnableReactiveMongoRepo.java similarity index 77% rename from flyfish-data/src/main/java/com/flyfish/framework/annotations/EnableReactiveMongoRepo.java rename to flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/config/annotations/EnableReactiveMongoRepo.java index 920b08a..7fad1ed 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/annotations/EnableReactiveMongoRepo.java +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/config/annotations/EnableReactiveMongoRepo.java @@ -1,7 +1,7 @@ -package com.flyfish.framework.annotations; +package com.flyfish.framework.mongodb.config.annotations; -import com.flyfish.framework.repository.factory.DefaultReactiveRepositoryFactoryBean; -import com.flyfish.framework.repository.impl.DefaultReactiveRepositoryImpl; +import com.flyfish.framework.mongodb.repository.factory.DefaultReactiveRepositoryFactoryBean; +import com.flyfish.framework.mongodb.repository.impl.DefaultReactiveRepositoryImpl; import org.springframework.core.annotation.AliasFor; import org.springframework.data.mongodb.config.EnableReactiveMongoAuditing; import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories; diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/operations/MongoReactiveEntityOperations.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/operations/MongoReactiveEntityOperations.java new file mode 100644 index 0000000..018cf4a --- /dev/null +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/operations/MongoReactiveEntityOperations.java @@ -0,0 +1,57 @@ +package com.flyfish.framework.mongodb.operations; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.query.Query; +import com.flyfish.framework.repository.ReactiveEntityOperations; +import lombok.RequiredArgsConstructor; +import org.springframework.data.mongodb.core.ReactiveMongoOperations; +import org.springframework.data.mongodb.repository.query.MongoEntityInformation; +import org.springframework.data.repository.core.EntityInformation; +import org.springframework.data.util.CastUtils; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@RequiredArgsConstructor +public class MongoReactiveEntityOperations implements ReactiveEntityOperations { + + private final ReactiveMongoOperations reactiveOperations; + + /** + * 查询,通过查询条件和类进行精确查询 + * + * @param query 查询 + * @param entityInformation 实体信息 + * @return 查询结果 + */ + @Override + public > Mono find(Query query, E entityInformation) { + return reactiveOperations.findOne(toNative(query, entityInformation), cast(entityInformation).getJavaType()); + } + + /** + * 查询全部符合条件的实体 + * + * @param query 查询 + * @param entityInformation 实体信息 + * @return 结果 + */ + @Override + public > Flux findAll(Query query, E entityInformation) { + return reactiveOperations.find(toNative(query, entityInformation), cast(entityInformation).getJavaType()); + } + + private MongoEntityInformation cast(EntityInformation entityInformation) { + return CastUtils.cast(entityInformation); + } + + /** + * 保存实体 + * + * @param bean 实体 + * @return 结果 + */ + @Override + public Mono save(T bean) { + return reactiveOperations.save(bean); + } +} diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/converter/MongoQueryConverter.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/converter/MongoQueryConverter.java new file mode 100644 index 0000000..ab5a2b2 --- /dev/null +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/converter/MongoQueryConverter.java @@ -0,0 +1,70 @@ +package com.flyfish.framework.mongodb.query.converter; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.query.spi.converter.QueryConverter; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.data.mongodb.repository.query.MongoEntityInformation; +import org.springframework.data.repository.core.EntityInformation; + +public class MongoQueryConverter implements QueryConverter { + + /** + * 判断是否支持实体 + * + * @param entity 实体信息 + * @return 结果 + */ + @Override + public boolean supports(EntityInformation entity) { + return entity instanceof MongoEntityInformation; + } + + /** + * 转换查询 + * + * @param query 封装的查询 + * @return 本地查询 + */ + @Override + public Query convert(com.flyfish.framework.query.Query query) { + Criteria condition = Criteria.where("delete").ne(true); + // 添加条件 + Criteria criteria = getCriteria(query); + if (null != criteria) { + condition = condition.andOperator(criteria); + } + // 构建查询 + Query result = Query.query(condition); + if (null != query.getSort()) { + result = result.with(query.getSort()); + } + if (null != query.getPageable()) { + result = result.with(query.getPageable()); + } + if (CollectionUtils.isNotEmpty(query.getFields())) { + result.fields().include(query.getFields().toArray(new String[]{})); + } + return result; + } + + /** + * 获取真实条件 + * + * @param query 查询信息 + * @return 结果 + */ + private Criteria getCriteria(com.flyfish.framework.query.Query query) { + // 当且仅当有example且正确生成条件时,才允许使用example构造 + if (null != query.getExample()) { + return new Criteria().alike(query.getExample()); + } + // 如果存在查询定义,直接使用查询定义 + if (null != query.getDefinition()) { + return query.getDefinition().build(); + } + return null; + } + +} diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/factory/MongoLambdaQueryFactory.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/factory/MongoLambdaQueryFactory.java new file mode 100644 index 0000000..6bba662 --- /dev/null +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/factory/MongoLambdaQueryFactory.java @@ -0,0 +1,36 @@ +package com.flyfish.framework.mongodb.query.factory; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.mongodb.query.impl.MongoLambdaQueryChain; +import com.flyfish.framework.query.LambdaQueryChain; +import com.flyfish.framework.query.spi.QueryChainFactory; + +/** + * mongo lambda 查询工厂 + * + * @author wangyu + */ +public class MongoLambdaQueryFactory implements QueryChainFactory> { + + /** + * 生产适配器 + * 此接口为高度抽象接口,目的是兼容更多的查询链类型,便于后续扩展 + * + * @return 生产结果 + */ + @Override + public LambdaQueryChain produce() { + return new MongoLambdaQueryChain<>(); + } + + /** + * 判定是否支持特定的实例类型 + * + * @param targetType 工厂目标类型 + * @return 是否匹配 + */ + @Override + public boolean supports(Class targetType) { + return targetType.isAssignableFrom(MongoLambdaQueryChain.class); + } +} diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/factory/MongoNamedQueryFactory.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/factory/MongoNamedQueryFactory.java new file mode 100644 index 0000000..92444e7 --- /dev/null +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/factory/MongoNamedQueryFactory.java @@ -0,0 +1,35 @@ +package com.flyfish.framework.mongodb.query.factory; + +import com.flyfish.framework.mongodb.query.impl.MongoNamedQueryChain; +import com.flyfish.framework.query.NamedQueryChain; +import com.flyfish.framework.query.spi.QueryChainFactory; + +/** + * mongo名称查询工厂 + * + * @author wangyu + */ +public class MongoNamedQueryFactory implements QueryChainFactory { + + /** + * 生产适配器 + * 此接口为高度抽象接口,目的是兼容更多的查询链类型,便于后续扩展 + * + * @return 生产结果 + */ + @Override + public NamedQueryChain produce() { + return new MongoNamedQueryChain(); + } + + /** + * 判定是否支持特定的实例类型 + * + * @param targetType 工厂目标类型 + * @return 是否匹配 + */ + @Override + public boolean supports(Class targetType) { + return targetType.isAssignableFrom(MongoNamedQueryChain.class); + } +} diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoLambdaQueryChain.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoLambdaQueryChain.java new file mode 100644 index 0000000..04687af --- /dev/null +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoLambdaQueryChain.java @@ -0,0 +1,239 @@ +package com.flyfish.framework.mongodb.query.impl; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.query.LambdaQueryChain; +import com.flyfish.framework.query.Queries; +import com.flyfish.framework.query.QueryChain; +import com.flyfish.framework.query.QueryCondition; +import com.flyfish.framework.query.support.DomainFunction; +import lombok.RequiredArgsConstructor; + +import java.util.Collection; +import java.util.List; +import java.util.function.Supplier; + +/** + * mongodb实现的基于lambda的查询链 + * + * @author wangyu + */ +public class MongoLambdaQueryChain extends MongoQueryDefinition implements LambdaQueryChain { + + /** + * 以且连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + public QueryCondition> and(DomainFunction column) { + return null; + } + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @return 结果 + */ + @Override + public > LambdaQueryChain and(Supplier> supplier) { + return null; + } + + /** + * 条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + @Override + public LambdaQueryChain and(LambdaQueryChain chain) { + return null; + } + + /** + * 多个嵌套子条件列表 + * + * @param lambdaQueryChains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + @Override + public LambdaQueryChain and(List> lambdaQueryChains, Queries.Combinator combinator) { + return null; + } + + /** + * 以或连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + public QueryCondition> or(DomainFunction column) { + return null; + } + + /** + * 以或连接条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + @Override + public LambdaQueryChain or(LambdaQueryChain chain) { + return null; + } + + /** + * 以或连接嵌套多个子条件列表 + * + * @param lambdaQueryChains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + @Override + public LambdaQueryChain or(List> lambdaQueryChains, Queries.Combinator combinator) { + return null; + } + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @return 结果 + */ + @Override + public > LambdaQueryChain or(Supplier> supplier) { + return null; + } + + /** + * 用于lambda的条件拼接 + */ + @RequiredArgsConstructor + class LambdaQueryCondition implements QueryCondition> { + + private final DomainFunction field; + + /** + * 相等判定 + * + * @param value 值 + * @return 结果 + */ + @Override + public LambdaQueryChain eq(Object value) { + criteria.and("").is(value); + return MongoLambdaQueryChain.this; + } + + /** + * 判定某列的值中存在指定值,特指json array数据类型且子类型中带有id的场景 + * 用于兼容mongodb查询,mysql查询使用JSON_CONTAINS进行判定。 + * 当且仅当mongodb会拼接.$id,mysql一律匹配id字段 + *

+ * 等价于 .eq(value) + * + * @param value 值 + * @return 结果 + */ + @Override + public LambdaQueryChain hasId(Object value) { + return null; + } + + /** + * 对于mongodb,自动处理。对于关系型数据库,代表json array中是否包含对应值,值仅支持基本数据类型 + *

+ * 等价于 .eq(value) + * + * @param value 基本数据类型的值 + * @return 结果 + */ + @Override + public LambdaQueryChain has(Object value) { + return null; + } + + /** + * 不等判定 + * + * @param value 值 + * @return 结果 + */ + @Override + public LambdaQueryChain ne(Object value) { + return null; + } + + /** + * 值介于两者之间 + * + * @param items 双值列表 + * @return 结果 + */ + @Override + public LambdaQueryChain between(List items) { + return null; + } + + /** + * 模糊匹配,这里是全模糊 + * + * @param keyword 查询关键字 + * @return 结果 + */ + @Override + public LambdaQueryChain like(String keyword) { + return null; + } + + /** + * 根据指定的方向进行模糊查询 + * + * @param keyword 关键字 + * @param direction 方向,可以匹配开头和结尾 + * @return 结果 + */ + @Override + public LambdaQueryChain like(String keyword, Queries.Direction direction) { + return null; + } + + /** + * 判定为空 + * + * @return 结果 + */ + @Override + public LambdaQueryChain isNull() { + return null; + } + + /** + * 包含在内 + * + * @param list 集合 + * @return 结果 + */ + @Override + public LambdaQueryChain in(Collection list) { + return null; + } + + /** + * 包含在内 + * 注意,需要根据字段类型推断。 + * 如果是json数组,需要进行双向匹配 + * + * @param values 值们 + * @return 结果 + */ + @Override + public LambdaQueryChain in(Object... values) { + return null; + } + } +} diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoNamedQueryChain.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoNamedQueryChain.java new file mode 100644 index 0000000..99fac7f --- /dev/null +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoNamedQueryChain.java @@ -0,0 +1,318 @@ +package com.flyfish.framework.mongodb.query.impl; + +import com.flyfish.framework.query.NamedQueryChain; +import com.flyfish.framework.query.Queries; +import com.flyfish.framework.query.QueryChain; +import com.flyfish.framework.query.QueryCondition; +import com.flyfish.framework.query.holder.QueryChainHolder; +import lombok.RequiredArgsConstructor; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.bson.types.ObjectId; +import org.springframework.data.mongodb.core.query.Criteria; + +import java.util.Collection; +import java.util.List; +import java.util.function.Supplier; + +/** + * mongodb实现的基于名称的查询链 + * 这里需要一个机制,能够将父类上下文带入,并且能够知晓实际查询对象的连接方式 + * 这就需要用到观察者模式,以便延迟执行。将动作作为事件发布到对象里,在具体的执行时机再进行fire。 + * 于是乎,我们便可以优雅而且低耦合的实现链式了。 + * + * @author wangyu + */ +public class MongoNamedQueryChain extends MongoQueryDefinition implements NamedQueryChain { + + /** + * 以且连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + public QueryCondition and(String column) { + and(); + return new NamedQueryCondition(column); + } + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @return 结果 + */ + @Override + public > NamedQueryChain and(Supplier> supplier) { + and().with(() -> supplier.get().build()); + return this; + } + + /** + * 条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + @Override + public NamedQueryChain and(NamedQueryChain chain) { + and().with(chain::build); + return this; + } + + /** + * 多个嵌套子条件列表 + * + * @param chains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + @Override + public NamedQueryChain and(List chains, Queries.Combinator combinator) { + return and(combine(chains, combinator)); + } + + /** + * 以或连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + public QueryCondition or(String column) { + or(); + return new NamedQueryCondition(column); + } + + /** + * 以或连接条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + @Override + public NamedQueryChain or(NamedQueryChain chain) { + or().with(chain::build); + return this; + } + + /** + * 以或连接嵌套多个子条件列表 + * + * @param chains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + @Override + public NamedQueryChain or(List chains, Queries.Combinator combinator) { + return or(combine(chains, combinator)); + } + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @return 结果 + */ + @Override + public > NamedQueryChain or(Supplier> supplier) { + or().with(() -> supplier.get().build()); + return this; + } + + /** + * 以且的关系进行拼接 + * + * @return 结果 + */ + private QueryChainHolder and() { + return holder.link(Criteria::andOperator); + } + + /** + * 以或的关系进行拼接 + * + * @return 结果 + */ + private QueryChainHolder or() { + return holder.link(Criteria::orOperator); + } + + /** + * 结合多个查询链,并根据组合方式进行处理 + * + * @param chains 查询链集合 + * @param combinator 组合方式 + * @return 结果 + */ + private NamedQueryChain combine(List chains, Queries.Combinator combinator) { + return chains.stream().reduce((left, right) -> combinator == Queries.Combinator.OR ? left.or(right) : left.and(right)) + .orElse(new MongoNamedQueryChain()); + } + + + /** + * 条件操作实现 + * + * @author wangyu + */ + @RequiredArgsConstructor + class NamedQueryCondition implements QueryCondition { + + private final String column; + + /** + * 相等判定 + * + * @param value 值 + * @return 结果 + */ + @Override + public NamedQueryChain eq(Object value) { + if (null != value) { + holder.with(Criteria.where(column).is(value)); + } + return MongoNamedQueryChain.this; + } + + /** + * 判定某列的值中存在指定值,特指json array数据类型且子类型中带有id的场景 + * 用于兼容mongodb查询,mysql查询使用JSON_CONTAINS进行判定。 + * 当且仅当mongodb会拼接.$id,mysql一律匹配id字段 + *

+ * 等价于 .eq(value) + * + * @param value 值 + * @return 结果 + */ + @Override + public NamedQueryChain hasId(Object value) { + if (null != value) { + holder.with(Criteria.where(column + ".$id").is(new ObjectId(String.valueOf(value)))); + } + return MongoNamedQueryChain.this; + } + + /** + * 对于mongodb,自动处理。对于关系型数据库,代表json array中是否包含对应值,值仅支持基本数据类型 + *

+ * 等价于 .eq(value) + * + * @param value 基本数据类型的值 + * @return 结果 + */ + @Override + public NamedQueryChain has(Object value) { + if (null != value) { + holder.with(Criteria.where(column).is(value)); + } + return MongoNamedQueryChain.this; + } + + /** + * 不等判定 + * + * @param value 值 + * @return 结果 + */ + @Override + public NamedQueryChain ne(Object value) { + if (null != value) { + holder.with(Criteria.where(column).ne(value)); + } + return MongoNamedQueryChain.this; + } + + /** + * 值介于两者之间 + * + * @param items 双值列表 + * @return 结果 + */ + @Override + public NamedQueryChain between(List items) { + if (CollectionUtils.size(items) == 2) { + holder.with(Criteria.where(column).gte(items.get(0)).lte(items.get(1))); + } + return MongoNamedQueryChain.this; + } + + /** + * 模糊匹配,这里是全模糊 + * + * @param keyword 查询关键字 + * @return 结果 + */ + @Override + public NamedQueryChain like(String keyword) { + if (StringUtils.isNotBlank(keyword)) { + holder.with(Criteria.where(column).regex(keyword)); + } + return MongoNamedQueryChain.this; + } + + /** + * 根据指定的方向进行模糊查询 + * + * @param keyword 关键字 + * @param direction 方向,可以匹配开头和结尾 + * @return 结果 + */ + @Override + public NamedQueryChain like(String keyword, Queries.Direction direction) { + if (StringUtils.isNotBlank(keyword)) { + // 匹配开头 + if (direction == Queries.Direction.LEFT) { + keyword = "^" + keyword; + } else if (direction == Queries.Direction.RIGHT) { + keyword = keyword + "$"; + } + holder.with(Criteria.where(column).regex(keyword)); + } + return MongoNamedQueryChain.this; + } + + /** + * 判定为空 + * + * @return 结果 + */ + @Override + public NamedQueryChain isNull() { + holder.with(Criteria.where(column).isNull()); + return MongoNamedQueryChain.this; + } + + /** + * 包含在内 + * + * @param list 集合 + * @return 结果 + */ + @Override + public NamedQueryChain in(Collection list) { + if (CollectionUtils.isNotEmpty(list)) { + holder.with(Criteria.where(column).in(list)); + } + return MongoNamedQueryChain.this; + } + + /** + * 包含在内 + * 注意,需要根据字段类型推断。 + * 如果是json数组,需要进行双向匹配 + * + * @param values 值们 + * @return 结果 + */ + @Override + public NamedQueryChain in(Object... values) { + if (ArrayUtils.isNotEmpty(values)) { + holder.with(Criteria.where(column).in(values)); + } + return MongoNamedQueryChain.this; + } + } +} diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoQueryChainHolder.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoQueryChainHolder.java new file mode 100644 index 0000000..b1ed94e --- /dev/null +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoQueryChainHolder.java @@ -0,0 +1,61 @@ +package com.flyfish.framework.mongodb.query.impl; + +import com.flyfish.framework.query.holder.QueryChainHolder; +import org.springframework.data.mongodb.core.query.Criteria; + +import java.util.function.BinaryOperator; +import java.util.function.Supplier; + +class MongoQueryChainHolder implements QueryChainHolder { + + /** + * 等待下一步消费 + * + * @param operator 操作方法 + * @return 本身 + */ + @Override + public QueryChainHolder link(BinaryOperator operator) { + return null; + } + + /** + * 拼接条件 + * + * @param criteria 条件 + */ + @Override + public void with(Criteria criteria) { + + } + + /** + * 拼接懒加载的条件 + * + * @param supplier 条件提供者 + */ + @Override + public void with(Supplier supplier) { + + } + + /** + * 触发动作,得到最终的 + * + * @return 本身 + */ + @Override + public Criteria get() { + return null; + } + + /** + * 判断条件是否为空 + * + * @return 结果 + */ + @Override + public boolean isEmpty() { + return false; + } +} diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoQueryDefinition.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoQueryDefinition.java new file mode 100644 index 0000000..2be68cd --- /dev/null +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoQueryDefinition.java @@ -0,0 +1,55 @@ +package com.flyfish.framework.mongodb.query.impl; + +import com.flyfish.framework.query.QueryDefinition; +import com.flyfish.framework.query.QueryMutation; + +/** + * mongo的查询定义 + * + * @author wangyu + */ +class MongoQueryDefinition implements QueryDefinition { + + protected final MongoQueryChainHolder holder = new MongoQueryChainHolder(); + + /** + * 构建 + * + * @return 构建结果 + */ + @SuppressWarnings("unchecked") + @Override + public T build() { + return (T) holder.get(); + } + + /** + * 修改,此修改会直接接着查询条件进行拼接 + * + * @return 修改句柄 + */ + @Override + public QueryMutation mutate() { + return null; + } + + /** + * 会直接添加嵌套查询到当前查询末尾 + * + * @return 修改句柄 + */ + @Override + public QueryMutation within() { + return null; + } + + /** + * 判断查询条件是否为空 + * + * @return 结果 + */ + @Override + public boolean isEmpty() { + return holder.isEmpty(); + } +} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/factory/DefaultReactiveRepositoryFactory.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/factory/DefaultReactiveRepositoryFactory.java similarity index 74% rename from flyfish-data/src/main/java/com/flyfish/framework/repository/factory/DefaultReactiveRepositoryFactory.java rename to flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/factory/DefaultReactiveRepositoryFactory.java index a58f320..20b4ba8 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/repository/factory/DefaultReactiveRepositoryFactory.java +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/factory/DefaultReactiveRepositoryFactory.java @@ -1,6 +1,6 @@ -package com.flyfish.framework.repository.factory; +package com.flyfish.framework.mongodb.repository.factory; -import com.flyfish.framework.repository.impl.DefaultReactiveRepositoryImpl; +import com.flyfish.framework.mongodb.repository.impl.DefaultReactiveRepositoryImpl; import org.springframework.data.mongodb.core.ReactiveMongoOperations; import org.springframework.data.mongodb.repository.support.ReactiveMongoRepositoryFactory; import org.springframework.data.repository.core.RepositoryMetadata; @@ -15,12 +15,12 @@ public class DefaultReactiveRepositoryFactory extends ReactiveMongoRepositoryFac */ public DefaultReactiveRepositoryFactory(ReactiveMongoOperations mongoOperations) { super(mongoOperations); - this.setRepositoryBaseClass(DefaultReactiveRepositoryFactory.class); + this.setRepositoryBaseClass(DefaultReactiveRepositoryImpl.class); } @Override @NonNull protected Class getRepositoryBaseClass(@NonNull RepositoryMetadata metadata) { - return DefaultReactiveRepositoryFactory.class; + return DefaultReactiveRepositoryImpl.class; } } diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/factory/DefaultReactiveRepositoryFactoryBean.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/factory/DefaultReactiveRepositoryFactoryBean.java similarity index 94% rename from flyfish-data/src/main/java/com/flyfish/framework/repository/factory/DefaultReactiveRepositoryFactoryBean.java rename to flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/factory/DefaultReactiveRepositoryFactoryBean.java index 74c90e7..2306f29 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/repository/factory/DefaultReactiveRepositoryFactoryBean.java +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/factory/DefaultReactiveRepositoryFactoryBean.java @@ -1,4 +1,4 @@ -package com.flyfish.framework.repository.factory; +package com.flyfish.framework.mongodb.repository.factory; import org.springframework.data.mongodb.core.ReactiveMongoOperations; import org.springframework.data.mongodb.repository.support.ReactiveMongoRepositoryFactoryBean; diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/factory/DefaultRepositoryFactory.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/factory/DefaultRepositoryFactory.java similarity index 86% rename from flyfish-data/src/main/java/com/flyfish/framework/repository/factory/DefaultRepositoryFactory.java rename to flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/factory/DefaultRepositoryFactory.java index 4f34969..a09b592 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/repository/factory/DefaultRepositoryFactory.java +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/factory/DefaultRepositoryFactory.java @@ -1,6 +1,6 @@ -package com.flyfish.framework.repository.factory; +package com.flyfish.framework.mongodb.repository.factory; -import com.flyfish.framework.repository.impl.DefaultRepositoryImpl; +import com.flyfish.framework.mongodb.repository.impl.DefaultRepositoryImpl; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.repository.support.MongoRepositoryFactory; import org.springframework.data.repository.core.RepositoryMetadata; diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/factory/DefaultRepositoryFactoryBean.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/factory/DefaultRepositoryFactoryBean.java similarity index 92% rename from flyfish-data/src/main/java/com/flyfish/framework/repository/factory/DefaultRepositoryFactoryBean.java rename to flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/factory/DefaultRepositoryFactoryBean.java index 09967a4..2afc503 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/repository/factory/DefaultRepositoryFactoryBean.java +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/factory/DefaultRepositoryFactoryBean.java @@ -1,4 +1,4 @@ -package com.flyfish.framework.repository.factory; +package com.flyfish.framework.mongodb.repository.factory; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean; @@ -6,7 +6,7 @@ import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.RepositoryFactorySupport; import org.springframework.lang.NonNull; -public class DefaultRepositoryFactoryBean, S> +public class DefaultRepositoryFactoryBean, S> extends MongoRepositoryFactoryBean { /** diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultReactiveRepositoryImpl.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/impl/DefaultReactiveRepositoryImpl.java similarity index 93% rename from flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultReactiveRepositoryImpl.java rename to flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/impl/DefaultReactiveRepositoryImpl.java index c4975fa..69771e4 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultReactiveRepositoryImpl.java +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/impl/DefaultReactiveRepositoryImpl.java @@ -1,4 +1,4 @@ -package com.flyfish.framework.repository.impl; +package com.flyfish.framework.mongodb.repository.impl; import com.flyfish.framework.domain.base.Domain; import com.flyfish.framework.domain.base.Qo; @@ -66,7 +66,7 @@ public class DefaultReactiveRepositoryImpl extends SimpleReact */ @Override public Mono findOne(Qo query) { - return Mono.justOrEmpty(QueryBuildUtils.getQuery(query)) + return Mono.justOrEmpty(getQuery(query)) .flatMap(querying -> mongoOperations.findOne(querying, entityInformation.getJavaType(), entityInformation.getCollectionName())); } @@ -80,7 +80,7 @@ public class DefaultReactiveRepositoryImpl extends SimpleReact */ @Override public Flux findAll(Qo query) { - return Mono.justOrEmpty(QueryBuildUtils.getQuery(query)) + return Mono.justOrEmpty(getQuery(query)) .flatMapMany(querying -> mongoOperations.find(querying, entityInformation.getJavaType(), entityInformation.getCollectionName())) @@ -99,7 +99,7 @@ public class DefaultReactiveRepositoryImpl extends SimpleReact */ @Override public Flux findAll(Qo query, Sort sort) { - return Mono.justOrEmpty(QueryBuildUtils.getQuery(query)) + return Mono.justOrEmpty(getQuery(query)) .flatMapMany(querying -> mongoOperations.find(querying.with(sort), entityInformation.getJavaType(), entityInformation.getCollectionName())); @@ -115,7 +115,7 @@ public class DefaultReactiveRepositoryImpl extends SimpleReact */ @Override public Mono> findAll(Qo query, Pageable pageable) { - return Mono.justOrEmpty(QueryBuildUtils.getQuery(query)) + return Mono.justOrEmpty(getQuery(query)) .flatMap(querying -> mongoOperations.find(querying.with(pageable), entityInformation.getJavaType(), entityInformation.getCollectionName()) .doOnNext(t -> t.setCurrentUser(query.getUser())) @@ -132,7 +132,7 @@ public class DefaultReactiveRepositoryImpl extends SimpleReact */ @Override public Mono count(Qo query) { - return Mono.justOrEmpty(QueryBuildUtils.getQuery(query)) + return Mono.justOrEmpty(getQuery(query)) .flatMap(querying -> this.mongoOperations.count(querying, entityInformation.getJavaType(), entityInformation.getCollectionName())) .defaultIfEmpty(0L); @@ -162,7 +162,7 @@ public class DefaultReactiveRepositoryImpl extends SimpleReact */ @Override public Mono exists(Qo query) { - return Mono.justOrEmpty(QueryBuildUtils.getQuery(query)) + return Mono.justOrEmpty(getQuery(query)) .flatMap(querying -> mongoOperations.exists(querying, entityInformation.getJavaType(), entityInformation.getCollectionName())) .defaultIfEmpty(false); @@ -176,9 +176,13 @@ public class DefaultReactiveRepositoryImpl extends SimpleReact */ @Override public Mono deleteAll(Qo qo) { - return Mono.justOrEmpty(QueryBuildUtils.getQuery(qo)) + return Mono.justOrEmpty(getQuery(qo)) .flatMap(querying -> mongoOperations.remove(querying, entityInformation.getJavaType(), entityInformation.getCollectionName())) .then(Mono.empty()); } + + private Optional getQuery(Qo qo) { + return qo.getQuery(entityInformation); + } } diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultRepositoryImpl.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/impl/DefaultRepositoryImpl.java similarity index 94% rename from flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultRepositoryImpl.java rename to flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/impl/DefaultRepositoryImpl.java index 2b00129..7c2cc8e 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultRepositoryImpl.java +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/impl/DefaultRepositoryImpl.java @@ -1,4 +1,4 @@ -package com.flyfish.framework.repository.impl; +package com.flyfish.framework.mongodb.repository.impl; import com.flyfish.framework.domain.base.Domain; import com.flyfish.framework.domain.base.Qo; @@ -71,7 +71,7 @@ public class DefaultRepositoryImpl extends SimpleMongoReposito */ @Override public Optional findOne(Qo query) { - return QueryBuildUtils.getQuery(query) + return getQuery(query) .map(querying -> mongoOperations.findOne(querying, entityInformation.getJavaType(), entityInformation.getCollectionName())); @@ -86,7 +86,7 @@ public class DefaultRepositoryImpl extends SimpleMongoReposito */ @Override public Iterable findAll(Qo query) { - return QueryBuildUtils.getQuery(query) + return getQuery(query) .map(querying -> mongoOperations.find(querying, entityInformation.getJavaType(), entityInformation.getCollectionName())) @@ -105,7 +105,7 @@ public class DefaultRepositoryImpl extends SimpleMongoReposito */ @Override public Iterable findAll(Qo query, Sort sort) { - return QueryBuildUtils.getQuery(query) + return getQuery(query) .map(querying -> mongoOperations.find(querying.with(sort), entityInformation.getJavaType(), entityInformation.getCollectionName())) @@ -122,7 +122,7 @@ public class DefaultRepositoryImpl extends SimpleMongoReposito */ @Override public Page findAll(Qo query, Pageable pageable) { - return QueryBuildUtils.getQuery(query).map(querying -> { + return getQuery(query).map(querying -> { List queryResult = mongoOperations.find(querying.with(pageable), entityInformation.getJavaType(), entityInformation.getCollectionName()); return PageableExecutionUtils.getPage(queryResult, pageable, () -> count(query)); @@ -137,7 +137,7 @@ public class DefaultRepositoryImpl extends SimpleMongoReposito */ @Override public long count(Qo query) { - return QueryBuildUtils.getQuery(query) + return getQuery(query) .map(q -> this.mongoOperations.count(q, entityInformation.getJavaType(), entityInformation.getCollectionName())) .orElse(0L); } @@ -166,8 +166,12 @@ public class DefaultRepositoryImpl extends SimpleMongoReposito */ @Override public boolean exists(Qo query) { - return QueryBuildUtils.getQuery(query).map(querying -> mongoOperations.exists(querying, + return getQuery(query).map(querying -> mongoOperations.exists(querying, entityInformation.getJavaType(), entityInformation.getCollectionName())) .orElse(false); } + + private Optional getQuery(Qo qo) { + return qo.getQuery(entityInformation); + } } diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/impl/ReactivePageableExecutionUtils.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/impl/ReactivePageableExecutionUtils.java new file mode 100644 index 0000000..a3bb98e --- /dev/null +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/impl/ReactivePageableExecutionUtils.java @@ -0,0 +1,68 @@ +/* + * Copyright 2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.flyfish.framework.mongodb.repository.impl; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.util.Assert; +import reactor.core.publisher.Mono; + +import java.util.List; + +/** + * Support for query execution using {@link Pageable}. Using {@link ReactivePageableExecutionUtils} assumes that data + * queries are cheaper than {@code COUNT} queries and so some cases can take advantage of optimizations. + * + * @author Mark Paluch + * @since 3.3 + */ +abstract class ReactivePageableExecutionUtils { + + private ReactivePageableExecutionUtils() {} + + /** + * Constructs a {@link Page} based on the given {@code content}, {@link Pageable} and {@link Mono} applying + * optimizations. The construction of {@link Page} omits a count query if the total can be determined based on the + * result size and {@link Pageable}. + * + * @param content must not be {@literal null}. + * @param pageable must not be {@literal null}. + * @param totalSupplier must not be {@literal null}. + * @return the {@link Page}. + */ + public static Mono> getPage(List content, Pageable pageable, Mono totalSupplier) { + + Assert.notNull(content, "Content must not be null!"); + Assert.notNull(pageable, "Pageable must not be null!"); + Assert.notNull(totalSupplier, "TotalSupplier must not be null!"); + + if (pageable.isUnpaged() || pageable.getOffset() == 0) { + + if (pageable.isUnpaged() || pageable.getPageSize() > content.size()) { + return Mono.just(new PageImpl<>(content, pageable, content.size())); + } + + return totalSupplier.map(total -> new PageImpl<>(content, pageable, total)); + } + + if (!content.isEmpty() && pageable.getPageSize() > content.size()) { + return Mono.just(new PageImpl<>(content, pageable, pageable.getOffset() + content.size())); + } + + return totalSupplier.map(total -> new PageImpl<>(content, pageable, total)); + } +} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/utils/CriteriaUtils.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/utils/CriteriaUtils.java similarity index 93% rename from flyfish-data/src/main/java/com/flyfish/framework/utils/CriteriaUtils.java rename to flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/utils/CriteriaUtils.java index bc35188..8c7aadd 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/utils/CriteriaUtils.java +++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/utils/CriteriaUtils.java @@ -1,4 +1,4 @@ -package com.flyfish.framework.utils; +package com.flyfish.framework.mongodb.utils; import org.springframework.data.mongodb.core.query.Criteria; diff --git a/flyfish-data/flyfish-data-mongodb/src/main/resources/META-INF/spring.factories b/flyfish-data/flyfish-data-mongodb/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..9f8a780 --- /dev/null +++ b/flyfish-data/flyfish-data-mongodb/src/main/resources/META-INF/spring.factories @@ -0,0 +1,9 @@ +com.flyfish.framework.query.spi.QueryChainFactory=\ + com.flyfish.framework.mongodb.query.factory.MongoNamedQueryFactory,\ + com.flyfish.framework.mongodb.query.factory.MongoLambdaQueryFactory + +com.flyfish.framework.query.spi.converter.QueryConverter=\ + com.flyfish.framework.mongodb.query.converter.MongoQueryConverter + +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + com.flyfish.framework.mongodb.config.MongoDataConfig diff --git a/flyfish-data/flyfish-data-r2dbc/pom.xml b/flyfish-data/flyfish-data-r2dbc/pom.xml new file mode 100644 index 0000000..0a8fde5 --- /dev/null +++ b/flyfish-data/flyfish-data-r2dbc/pom.xml @@ -0,0 +1,33 @@ + + + + flyfish-data + com.flyfish.framework + ${revision} + + 4.0.0 + + flyfish-data-r2dbc + + + 8 + 8 + + + + + org.springframework.boot + spring-boot-starter-data-r2dbc + + + io.asyncer + r2dbc-mysql + + + com.flyfish.framework + flyfish-data-common + + + diff --git a/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/config/R2dbcDataConfig.java b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/config/R2dbcDataConfig.java new file mode 100644 index 0000000..810e5aa --- /dev/null +++ b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/config/R2dbcDataConfig.java @@ -0,0 +1,39 @@ +package com.flyfish.framework.r2dbc.config; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.r2dbc.operations.R2dbcReactiveEntityOperations; +import com.flyfish.framework.r2dbc.repository.factory.DefaultReactiveRepositoryFactoryBean; +import com.flyfish.framework.r2dbc.repository.impl.DefaultReactiveRepositoryImpl; +import com.flyfish.framework.repository.ReactiveEntityOperations; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mapping.callback.EntityCallback; +import org.springframework.data.r2dbc.config.EnableR2dbcAuditing; +import org.springframework.data.r2dbc.core.R2dbcEntityOperations; +import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories; + +/** + * r2dbc数据配置 + * + * @author wangyu + */ +@EnableR2dbcRepositories( + repositoryFactoryBeanClass = DefaultReactiveRepositoryFactoryBean.class, + repositoryBaseClass = DefaultReactiveRepositoryImpl.class +) +@EnableR2dbcAuditing +@Configuration +public class R2dbcDataConfig { + + @Bean + public EntityCallback r2dbcReferenceEntityCallback() { + return new R2dbcReferenceEntityCallback(); + } + + @Bean + @ConditionalOnBean(R2dbcEntityOperations.class) + public ReactiveEntityOperations r2dbcReactiveEntityOperations(R2dbcEntityOperations r2dbcEntityOperations) { + return new R2dbcReactiveEntityOperations(r2dbcEntityOperations); + } +} diff --git a/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/config/R2dbcReferenceEntityCallback.java b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/config/R2dbcReferenceEntityCallback.java new file mode 100644 index 0000000..f541bd8 --- /dev/null +++ b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/config/R2dbcReferenceEntityCallback.java @@ -0,0 +1,27 @@ +package com.flyfish.framework.r2dbc.config; + +import com.flyfish.framework.domain.base.Domain; +import org.reactivestreams.Publisher; +import org.springframework.data.r2dbc.mapping.event.AfterConvertCallback; +import org.springframework.data.relational.core.sql.SqlIdentifier; + +/** + * 给r2dbc中的实体进行关联填充 + * + * @author wangyu + */ +public class R2dbcReferenceEntityCallback implements AfterConvertCallback { + + /** + * Entity callback method invoked after a domain object is materialized from a row. Can return either the same or a + * modified instance of the domain object. + * + * @param entity the domain object (the result of the conversion). + * @param table name of the table. + * @return the domain object that is the result of reading it from a row. + */ + @Override + public Publisher onAfterConvert(Domain entity, SqlIdentifier table) { + return null; + } +} diff --git a/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/config/annotations/EnableR2dbcRepo.java b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/config/annotations/EnableR2dbcRepo.java new file mode 100644 index 0000000..a341043 --- /dev/null +++ b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/config/annotations/EnableR2dbcRepo.java @@ -0,0 +1,34 @@ +package com.flyfish.framework.r2dbc.config.annotations; + +import com.flyfish.framework.r2dbc.repository.factory.DefaultReactiveRepositoryFactoryBean; +import com.flyfish.framework.r2dbc.repository.impl.DefaultReactiveRepositoryImpl; +import org.springframework.core.annotation.AliasFor; +import org.springframework.data.r2dbc.config.EnableR2dbcAuditing; +import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories; + +import java.lang.annotation.*; + +/** + * 启用注解,能够指定基本路径 + * + * @author wangyu + */ +@EnableR2dbcRepositories( + repositoryFactoryBeanClass = DefaultReactiveRepositoryFactoryBean.class, + repositoryBaseClass = DefaultReactiveRepositoryImpl.class +) +@EnableR2dbcAuditing +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +public @interface EnableR2dbcRepo { + + /** + * 扫描的基本路径 + * + * @return 结果 + */ + @AliasFor(annotation = EnableR2dbcRepositories.class) + String[] basePackages() default {}; +} diff --git a/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/operations/R2dbcReactiveEntityOperations.java b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/operations/R2dbcReactiveEntityOperations.java new file mode 100644 index 0000000..488487b --- /dev/null +++ b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/operations/R2dbcReactiveEntityOperations.java @@ -0,0 +1,61 @@ +package com.flyfish.framework.r2dbc.operations; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.query.Query; +import com.flyfish.framework.repository.ReactiveEntityOperations; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.data.r2dbc.core.R2dbcEntityOperations; +import org.springframework.data.relational.repository.query.RelationalEntityInformation; +import org.springframework.data.repository.core.EntityInformation; +import org.springframework.data.util.CastUtils; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@RequiredArgsConstructor +public class R2dbcReactiveEntityOperations implements ReactiveEntityOperations { + + private final R2dbcEntityOperations r2dbcEntityOperations; + + /** + * 查询,通过查询条件和类进行精确查询 + * + * @param query 查询 + * @param entityInformation 实体信息 + * @return 查询结果 + */ + @Override + public > Mono find(Query query, E entityInformation) { + return r2dbcEntityOperations.selectOne(toNative(query, entityInformation), cast(entityInformation).getJavaType()); + } + + /** + * 查询全部符合条件的实体 + * + * @param query 查询 + * @param entityInformation 实体信息 + * @return 结果 + */ + @Override + public > Flux findAll(Query query, E entityInformation) { + return r2dbcEntityOperations.select(toNative(query, entityInformation), cast(entityInformation).getJavaType()); + } + + private RelationalEntityInformation cast(EntityInformation entityInformation) { + return CastUtils.cast(entityInformation); + } + + /** + * 保存实体 + * + * @param bean 实体 + * @return 结果 + */ + @Override + public Mono save(T bean) { + if (StringUtils.isNotBlank(bean.getId())) { + return r2dbcEntityOperations.update(bean); + } + return r2dbcEntityOperations.insert(bean); + } +} diff --git a/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/converter/R2dbcQueryConverter.java b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/converter/R2dbcQueryConverter.java new file mode 100644 index 0000000..8d5dfd5 --- /dev/null +++ b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/converter/R2dbcQueryConverter.java @@ -0,0 +1,98 @@ +package com.flyfish.framework.r2dbc.query.converter; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.query.spi.converter.QueryConverter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.data.domain.Example; +import org.springframework.data.relational.core.query.Criteria; +import org.springframework.data.relational.core.query.Query; +import org.springframework.data.relational.repository.query.RelationalEntityInformation; +import org.springframework.data.relational.repository.query.RelationalExampleMapper; +import org.springframework.data.repository.core.EntityInformation; + +import java.util.Optional; + +/** + * r2dbc查询转换器 + * + * @author wangyu + */ +@Slf4j +public class R2dbcQueryConverter implements QueryConverter { + + @Setter + private static RelationalExampleMapper exampleMapper; + + /** + * 判断是否支持实体 + * + * @param entity 实体信息 + * @return 结果 + */ + @Override + public boolean supports(EntityInformation entity) { + return entity instanceof RelationalEntityInformation; + } + + /** + * 转换查询 + * + * @param query 封装的查询 + * @return 本地查询 + */ + @Override + public Query convert(com.flyfish.framework.query.Query query) { + Criteria condition = Criteria.where("delete").not(true); + // 添加条件 + Criteria criteria = getCriteria(query); + if (null != criteria) { + condition = condition.and(criteria); + } + // 构建查询 + Query result = Query.query(condition); + if (null != query.getSort()) { + result = result.sort(query.getSort()); + } + if (null != query.getPageable()) { + result = result.with(query.getPageable()); + } + if (CollectionUtils.isNotEmpty(query.getFields())) { + result = result.columns(query.getFields()); + } + return result; + } + + /** + * 获取真实条件 + * + * @param query 查询信息 + * @return 结果 + */ + private Criteria getCriteria(com.flyfish.framework.query.Query query) { + // 当且仅当有example且正确生成条件时,才允许使用example构造 + if (null != query.getExample()) { + Optional optional = ofExample(query.getExample()); + if (optional.isPresent()) { + return optional.get(); + } + } + // 如果存在查询定义,直接使用查询定义 + if (null != query.getDefinition()) { + return (Criteria) query.getDefinition().build(); + } + return null; + } + + /** + * 通过example进行匹配 + * + * @param example 示例对象 + * @return 结果 + */ + private Optional ofExample(Example example) { + return exampleMapper.getMappedExample(example).getCriteria() + .map(cd -> (Criteria) cd); + } +} diff --git a/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/factory/R2dbcLambdaQueryFactory.java b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/factory/R2dbcLambdaQueryFactory.java new file mode 100644 index 0000000..0f84d03 --- /dev/null +++ b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/factory/R2dbcLambdaQueryFactory.java @@ -0,0 +1,36 @@ +package com.flyfish.framework.r2dbc.query.factory; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.query.LambdaQueryChain; +import com.flyfish.framework.query.spi.QueryChainFactory; +import com.flyfish.framework.r2dbc.query.impl.R2dbcLambdaQueryChain; + +/** + * mongo lambda 查询工厂 + * + * @author wangyu + */ +public class R2dbcLambdaQueryFactory implements QueryChainFactory> { + + /** + * 生产适配器 + * 此接口为高度抽象接口,目的是兼容更多的查询链类型,便于后续扩展 + * + * @return 生产结果 + */ + @Override + public LambdaQueryChain produce() { + return new R2dbcLambdaQueryChain<>(); + } + + /** + * 判定是否支持特定的实例类型 + * + * @param targetType 工厂目标类型 + * @return 是否匹配 + */ + @Override + public boolean supports(Class targetType) { + return targetType.isAssignableFrom(R2dbcLambdaQueryChain.class); + } +} diff --git a/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/factory/R2dbcNamedQueryFactory.java b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/factory/R2dbcNamedQueryFactory.java new file mode 100644 index 0000000..68d1dd1 --- /dev/null +++ b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/factory/R2dbcNamedQueryFactory.java @@ -0,0 +1,35 @@ +package com.flyfish.framework.r2dbc.query.factory; + +import com.flyfish.framework.query.NamedQueryChain; +import com.flyfish.framework.query.spi.QueryChainFactory; +import com.flyfish.framework.r2dbc.query.impl.R2dbcNamedQueryChain; + +/** + * mongo名称查询工厂 + * + * @author wangyu + */ +public class R2dbcNamedQueryFactory implements QueryChainFactory { + + /** + * 生产适配器 + * 此接口为高度抽象接口,目的是兼容更多的查询链类型,便于后续扩展 + * + * @return 生产结果 + */ + @Override + public NamedQueryChain produce() { + return new R2dbcNamedQueryChain(); + } + + /** + * 判定是否支持特定的实例类型 + * + * @param targetType 工厂目标类型 + * @return 是否匹配 + */ + @Override + public boolean supports(Class targetType) { + return targetType.isAssignableFrom(R2dbcNamedQueryChain.class); + } +} diff --git a/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/impl/R2dbcLambdaQueryChain.java b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/impl/R2dbcLambdaQueryChain.java new file mode 100644 index 0000000..4927f59 --- /dev/null +++ b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/impl/R2dbcLambdaQueryChain.java @@ -0,0 +1,109 @@ +package com.flyfish.framework.r2dbc.query.impl; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.query.LambdaQueryChain; +import com.flyfish.framework.query.Queries; +import com.flyfish.framework.query.QueryChain; +import com.flyfish.framework.query.QueryCondition; +import com.flyfish.framework.query.support.DomainFunction; + +import java.util.List; +import java.util.function.Supplier; + +/** + * mongodb实现的基于lambda的查询链 + * + * @author wangyu + */ +public class R2dbcLambdaQueryChain extends R2dbcQueryDefinition implements LambdaQueryChain { + + /** + * 以且连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + public QueryCondition> and(DomainFunction column) { + return null; + } + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @return 结果 + */ + @Override + public > LambdaQueryChain and(Supplier> supplier) { + return null; + } + + /** + * 条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + @Override + public LambdaQueryChain and(LambdaQueryChain chain) { + return null; + } + + /** + * 多个嵌套子条件列表 + * + * @param lambdaQueryChains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + @Override + public LambdaQueryChain and(List> lambdaQueryChains, Queries.Combinator combinator) { + return null; + } + + /** + * 以或连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + public QueryCondition> or(DomainFunction column) { + return null; + } + + /** + * 以或连接条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + @Override + public LambdaQueryChain or(LambdaQueryChain chain) { + return null; + } + + /** + * 以或连接嵌套多个子条件列表 + * + * @param lambdaQueryChains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + @Override + public LambdaQueryChain or(List> lambdaQueryChains, Queries.Combinator combinator) { + return null; + } + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @return 结果 + */ + @Override + public > LambdaQueryChain or(Supplier> supplier) { + return null; + } +} diff --git a/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/impl/R2dbcNamedQueryChain.java b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/impl/R2dbcNamedQueryChain.java new file mode 100644 index 0000000..f8485bd --- /dev/null +++ b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/impl/R2dbcNamedQueryChain.java @@ -0,0 +1,107 @@ +package com.flyfish.framework.r2dbc.query.impl; + +import com.flyfish.framework.query.NamedQueryChain; +import com.flyfish.framework.query.Queries; +import com.flyfish.framework.query.QueryChain; +import com.flyfish.framework.query.QueryCondition; + +import java.util.List; +import java.util.function.Supplier; + +/** + * mongodb实现的基于名称的查询链 + * + * @author wangyu + */ +public class R2dbcNamedQueryChain extends R2dbcQueryDefinition implements NamedQueryChain { + + /** + * 以且连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + public QueryCondition and(String column) { + return null; + } + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @return 结果 + */ + @Override + public > NamedQueryChain and(Supplier> supplier) { + return null; + } + + /** + * 条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + @Override + public NamedQueryChain and(NamedQueryChain chain) { + return null; + } + + /** + * 多个嵌套子条件列表 + * + * @param chains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + @Override + public NamedQueryChain and(List chains, Queries.Combinator combinator) { + return null; + } + + /** + * 以或连接下一个字段 + * + * @param column 列 + * @return 查询条件 + */ + @Override + public QueryCondition or(String column) { + return null; + } + + /** + * 以或连接条件列表 + * + * @param chain 多个条件们 + * @return 结果 + */ + @Override + public NamedQueryChain or(NamedQueryChain chain) { + return null; + } + + /** + * 以或连接嵌套多个子条件列表 + * + * @param chains 多条链 + * @param combinator 各个链条之间的连接方式 + * @return 结果 + */ + @Override + public NamedQueryChain or(List chains, Queries.Combinator combinator) { + return null; + } + + /** + * 直接拼接提供者,此处懒加载,最终build才会执行 + * + * @param supplier 提供者 + * @return 结果 + */ + @Override + public > NamedQueryChain or(Supplier> supplier) { + return null; + } +} diff --git a/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/impl/R2dbcQueryDefinition.java b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/impl/R2dbcQueryDefinition.java new file mode 100644 index 0000000..01c4fde --- /dev/null +++ b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/impl/R2dbcQueryDefinition.java @@ -0,0 +1,56 @@ +package com.flyfish.framework.r2dbc.query.impl; + +import com.flyfish.framework.query.QueryDefinition; +import com.flyfish.framework.query.QueryMutation; +import org.springframework.data.relational.core.query.Criteria; +import org.springframework.data.util.CastUtils; + +/** + * mongo的查询定义 + * + * @author wangyu + */ +public class R2dbcQueryDefinition implements QueryDefinition { + + private Criteria criteria; + + /** + * 构建 + * + * @return 构建结果 + */ + @Override + public T build() { + return CastUtils.cast(criteria); + } + + /** + * 修改,此修改会直接接着查询条件进行拼接 + * + * @return 修改句柄 + */ + @Override + public QueryMutation mutate() { + return null; + } + + /** + * 会直接添加嵌套查询到当前查询末尾 + * + * @return 修改句柄 + */ + @Override + public QueryMutation within() { + return null; + } + + /** + * 判断查询条件是否为空 + * + * @return 结果 + */ + @Override + public boolean isEmpty() { + return false; + } +} diff --git a/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/repository/factory/DefaultReactiveRepositoryFactory.java b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/repository/factory/DefaultReactiveRepositoryFactory.java new file mode 100644 index 0000000..d2030eb --- /dev/null +++ b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/repository/factory/DefaultReactiveRepositoryFactory.java @@ -0,0 +1,27 @@ +package com.flyfish.framework.r2dbc.repository.factory; + +import com.flyfish.framework.r2dbc.repository.impl.DefaultReactiveRepositoryImpl; +import org.springframework.data.r2dbc.core.R2dbcEntityOperations; +import org.springframework.data.r2dbc.repository.support.R2dbcRepositoryFactory; +import org.springframework.data.repository.core.RepositoryMetadata; +import org.springframework.lang.NonNull; + +public class DefaultReactiveRepositoryFactory extends R2dbcRepositoryFactory { + + /** + * Creates a new {@link R2dbcRepositoryFactory} given {@link R2dbcEntityOperations}. + * + * @param operations must not be {@literal null}. + * @since 1.1.3 + */ + public DefaultReactiveRepositoryFactory(R2dbcEntityOperations operations) { + super(operations); + this.setRepositoryBaseClass(DefaultReactiveRepositoryImpl.class); + } + + @Override + @NonNull + protected Class getRepositoryBaseClass(@NonNull RepositoryMetadata metadata) { + return DefaultReactiveRepositoryImpl.class; + } +} diff --git a/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/repository/factory/DefaultReactiveRepositoryFactoryBean.java b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/repository/factory/DefaultReactiveRepositoryFactoryBean.java new file mode 100644 index 0000000..7b8d0d6 --- /dev/null +++ b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/repository/factory/DefaultReactiveRepositoryFactoryBean.java @@ -0,0 +1,26 @@ +package com.flyfish.framework.r2dbc.repository.factory; + +import org.springframework.data.r2dbc.core.R2dbcEntityOperations; +import org.springframework.data.r2dbc.repository.support.R2dbcRepositoryFactoryBean; +import org.springframework.data.repository.Repository; +import org.springframework.data.repository.core.support.RepositoryFactorySupport; +import org.springframework.lang.NonNull; + +public class DefaultReactiveRepositoryFactoryBean, S> + extends R2dbcRepositoryFactoryBean { + + /** + * Creates a new {@link R2dbcRepositoryFactoryBean} for the given repository interface. + * + * @param repositoryInterface must not be {@literal null}. + */ + public DefaultReactiveRepositoryFactoryBean(Class repositoryInterface) { + super(repositoryInterface); + } + + @Override + @NonNull + protected RepositoryFactorySupport getFactoryInstance(@NonNull R2dbcEntityOperations operations) { + return new DefaultReactiveRepositoryFactory(operations); + } +} diff --git a/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/repository/impl/DefaultReactiveRepositoryImpl.java b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/repository/impl/DefaultReactiveRepositoryImpl.java new file mode 100644 index 0000000..5077493 --- /dev/null +++ b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/repository/impl/DefaultReactiveRepositoryImpl.java @@ -0,0 +1,240 @@ +package com.flyfish.framework.r2dbc.repository.impl; + +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.domain.base.Qo; +import com.flyfish.framework.r2dbc.query.converter.R2dbcQueryConverter; +import com.flyfish.framework.repository.DefaultReactiveRepository; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; +import org.reactivestreams.Publisher; +import org.springframework.dao.IncorrectResultSizeDataAccessException; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.r2dbc.convert.R2dbcConverter; +import org.springframework.data.r2dbc.core.R2dbcEntityOperations; +import org.springframework.data.r2dbc.repository.support.SimpleR2dbcRepository; +import org.springframework.data.relational.core.query.Criteria; +import org.springframework.data.relational.core.query.Query; +import org.springframework.data.relational.repository.query.RelationalEntityInformation; +import org.springframework.data.relational.repository.query.RelationalExampleMapper; +import org.springframework.data.repository.core.EntityInformation; +import org.springframework.lang.NonNull; +import org.springframework.util.Assert; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.List; +import java.util.Optional; + +/** + * 默认的异步仓库实现 + * + * @param 泛型 + */ +public class DefaultReactiveRepositoryImpl extends SimpleR2dbcRepository + implements DefaultReactiveRepository { + + @Getter + private final RelationalEntityInformation entity; + + private final R2dbcEntityOperations entityOperations; + + /** + * 构造新的默认仓库 + * + * @param entity 实体信息 + * @param entityOperations 数据库操作模板 + * @param converter 转换器 + */ + public DefaultReactiveRepositoryImpl(RelationalEntityInformation entity, R2dbcEntityOperations entityOperations, R2dbcConverter converter) { + super(entity, entityOperations, converter); + this.entity = entity; + this.entityOperations = entityOperations; + R2dbcQueryConverter.setExampleMapper(new RelationalExampleMapper(converter.getMappingContext())); + } + + + /** + * 通过名称查找一个 + * + * @param name 名称 + * @return 结果 + */ + @Override + public Mono findByName(String name) { + if (StringUtils.isNotBlank(name)) { + return entityOperations.selectOne(Query.query(Criteria.where("name").is(name)), entity.getJavaType()); + } + return Mono.empty(); + } + + /** + * Returns a single entity matching the given {@link Qo} or {@link Optional#empty()} if none was found. + * + * @param query must not be {@literal null}. + * @return a single entity matching the given {@link Qo} or {@link Optional#empty()} if none was found. + * @throws IncorrectResultSizeDataAccessException if the Qo yields more than one + * result. + */ + @Override + public Mono findOne(Qo query) { + return Mono.justOrEmpty(getQuery(query)) + .flatMap(querying -> entityOperations.selectOne(querying, entity.getJavaType())); + } + + /** + * Returns all entities matching the given {@link Qo}. In case no match could be found an empty + * {@link Iterable} is returned. + * + * @param query must not be {@literal null}. + * @return all entities matching the given {@link Qo}. + */ + @Override + public Flux findAll(Qo query) { + return Mono.justOrEmpty(getQuery(query)) + .flatMapMany(querying -> entityOperations.select(querying, entity.getJavaType()) + .doOnNext(t -> t.setCurrentUser(query.getUser()))); + } + + /** + * Returns all entities matching the given {@link Qo} applying the given {@link Sort}. In case no match could + * be found an empty {@link Iterable} is returned. + * + * @param query must not be {@literal null}. + * @param sort the {@link Sort} specification to sort the results by, may be {@link Sort#empty()}, must not be + * {@literal null}. + * @return all entities matching the given {@link Qo}. + * @since 1.10 + */ + @Override + public Flux findAll(Qo query, Sort sort) { + return Mono.justOrEmpty(getQuery(query)) + .flatMapMany(querying -> entityOperations.select(querying.sort(sort), + entity.getJavaType())); + } + + /** + * Returns a {@link Page} of entities matching the given {@link Qo}. In case no match could be found, an empty + * {@link Page} is returned. + * + * @param query must not be {@literal null}. + * @param pageable may be {@link Pageable#unpaged()}, must not be {@literal null}. + * @return a {@link Page} of entities matching the given {@link Qo}. + */ + @Override + public Mono> findAll(Qo query, Pageable pageable) { + return Mono.justOrEmpty(getQuery(query)) + .flatMap(querying -> entityOperations.select(querying.with(pageable), + entity.getJavaType()) + .doOnNext(t -> t.setCurrentUser(query.getUser())) + .collectList() + .flatMap(list -> ReactivePageableExecutionUtils.getPage(list, pageable, this.count(query)))) + .defaultIfEmpty(Page.empty()); + } + + /** + * Returns the number of instances matching the given {@link Qo}. + * + * @param query the {@link Qo} to count instances for, must not be {@literal null}. + * @return the number of instances matching the {@link Qo}. + */ + @Override + public Mono count(Qo query) { + return Mono.justOrEmpty(getQuery(query)) + .flatMap(querying -> this.entityOperations.count(querying, entity.getJavaType())) + .defaultIfEmpty(0L); + } + + /** + * 通过特定键的集合查询 + * + * @param key 键 + * @param values 集合 + * @return 结果 + */ + @Override + public Flux findAllByValues(String key, List values) { + Criteria criteria = Criteria.where(key).in(values); + Query query = Query.query(criteria); + return entityOperations.select(query, entity.getJavaType()); + } + + /** + * Checks whether the data store contains elements that match the given {@link Qo}. + * + * @param query the {@link Qo} to use for the existence check, must not be {@literal null}. + * @return {@literal true} if the data store contains elements that match the given {@link Qo}. + */ + @Override + public Mono exists(Qo query) { + return Mono.justOrEmpty(getQuery(query)) + .flatMap(querying -> entityOperations.exists(querying, entity.getJavaType())) + .defaultIfEmpty(false); + } + + /** + * 删除全部 + * + * @param qo 查询实体 + * @return 结果 + */ + @Override + public Mono deleteAll(Qo qo) { + return Mono.justOrEmpty(getQuery(qo)) + .flatMap(querying -> entityOperations.delete(querying, entity.getJavaType())) + .then(Mono.empty()); + } + + /** + * 插入给定的实体. 假设该实体是新的,以便应用插入优化。 + * 使用返回的实例进行后续操作,因为保存操作可能会完全改变实体实例。 + * + * @param entity 要插入的实体,不能为空 + * @return 保存后的实体 + */ + @Override + @NonNull + public Mono insert(@NonNull S entity) { + Assert.notNull(entity, "Entity must not be null!"); + return entityOperations.insert(entity); + } + + /** + * 插入给定的实体列表. 假设这些实体是新的,以便应用插入优化。 + * 使用返回的实例进行后续操作,因为保存操作可能会完全改变实体实例。 + * + * @param entities 实体列表,不能为空 + * @return 保存后的实体列表 + */ + @Override + public Flux insert(Iterable entities) { + Assert.notNull(entities, "Objects to save must not be null!"); + return Flux.fromIterable(entities).concatMap(this::insert); + } + + /** + * 插入给定的实体发布者发布的实体. 假设这些实体是新的,以便应用插入优化。 + * 使用返回的实例进行后续操作,因为保存操作可能会完全改变实体实例。 + * + * @param entities 发布的实体列表,不能为空 + * @return 保存后的实体列表 + */ + @Override + public Flux insert(Publisher entities) { + Assert.notNull(entities, "The given Publisher of entities must not be null!"); + return Flux.from(entities).flatMap(this::insert); + } + + @Override + public EntityInformation getEntityInformation() { + return entity; + } + + private Optional getQuery(Qo qo) { + if (null != qo.getExample()) { + + } + return qo.getQuery(entity); + } +} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/ReactivePageableExecutionUtils.java b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/repository/impl/ReactivePageableExecutionUtils.java similarity index 97% rename from flyfish-data/src/main/java/com/flyfish/framework/repository/impl/ReactivePageableExecutionUtils.java rename to flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/repository/impl/ReactivePageableExecutionUtils.java index 28b94e0..9faf997 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/ReactivePageableExecutionUtils.java +++ b/flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/repository/impl/ReactivePageableExecutionUtils.java @@ -13,16 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.flyfish.framework.repository.impl; - -import reactor.core.publisher.Mono; - -import java.util.List; +package com.flyfish.framework.r2dbc.repository.impl; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.util.Assert; +import reactor.core.publisher.Mono; + +import java.util.List; /** * Support for query execution using {@link Pageable}. Using {@link ReactivePageableExecutionUtils} assumes that data diff --git a/flyfish-data/flyfish-data-r2dbc/src/main/resources/META-INF/spring.factories b/flyfish-data/flyfish-data-r2dbc/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..aee2084 --- /dev/null +++ b/flyfish-data/flyfish-data-r2dbc/src/main/resources/META-INF/spring.factories @@ -0,0 +1,9 @@ +com.flyfish.framework.query.spi.QueryChainFactory=\ + com.flyfish.framework.r2dbc.query.factory.R2dbcLambdaQueryFactory,\ + com.flyfish.framework.r2dbc.query.factory.R2dbcNamedQueryFactory + +com.flyfish.framework.query.spi.converter.QueryConverter=\ + com.flyfish.framework.r2dbc.query.converter.R2dbcQueryConverter + +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + com.flyfish.framework.r2dbc.config.R2dbcDataConfig diff --git a/flyfish-data/pom.xml b/flyfish-data/pom.xml index fc4abcd..760b8c0 100644 --- a/flyfish-data/pom.xml +++ b/flyfish-data/pom.xml @@ -5,42 +5,17 @@ flyfish-framework com.flyfish.framework - 0.0.2-SNAPSHOT + ${revision} 4.0.0 flyfish-data + pom + + flyfish-data-r2dbc + flyfish-data-mongodb + flyfish-data-common + flyfish-data-domain + - - - com.flyfish.framework - flyfish-common - ${project.version} - - - - org.springframework.data - spring-data-mongodb - - - - org.springframework.security - spring-security-core - - - - org.springframework.boot - spring-boot-starter-data-mongodb-reactive - - - - org.springframework.boot - spring-boot-starter-data-mongodb - - - - com.github.ulisesbocchio - jasypt-spring-boot-starter - - diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedQo.java b/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedQo.java deleted file mode 100644 index 58e923d..0000000 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedQo.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.flyfish.framework.domain.authorized; - -import com.flyfish.framework.builder.CriteriaBuilder; -import com.flyfish.framework.enums.UserType; -import lombok.Getter; -import lombok.Setter; -import org.apache.commons.lang3.BooleanUtils; -import org.springframework.data.mongodb.core.query.Criteria; - -/** - * 带鉴权的查询实体,主要以部门隔绝 - * - * @param - */ -@Getter -@Setter -public class AuthorizedQo extends AbstractAuthorizedQo { - - @Override - public CriteriaBuilder criteriaBuilder() { - // 超级管理员拥有查看所有草稿的权限 - if (user.getType() == UserType.SUPER_ADMIN) { - return super.criteriaBuilder().with(this::withPublished); - } - // 查询草稿,只查询自己的 - if (BooleanUtils.isFalse(published)) { - return super.criteriaBuilder() - .with(this::withPublished) - .with(() -> Criteria.where("creatorId").is(user.getId())); - } - // 普通查询,根据权限配置查询 - return super.criteriaBuilder() - .with(this::withPublished) - .with(() -> Criteria.where("$or").is( - CriteriaBuilder.createCriteriaList( - Criteria.where("authorizeId").in(authorizeIds()), - Criteria.where("creatorId").is(user.getId()) - .and("authorizeId").in(((AuthorizedUserDetails) user).getVisibleDeparts()) - ) - )); - } - -} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/advanced/OwnedAuthorizedQo.java b/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/advanced/OwnedAuthorizedQo.java deleted file mode 100644 index e2c6cfc..0000000 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/advanced/OwnedAuthorizedQo.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.flyfish.framework.domain.authorized.advanced; - -import com.flyfish.framework.builder.CriteriaBuilder; -import com.flyfish.framework.domain.authorized.AbstractAuthorizedQo; -import com.flyfish.framework.domain.authorized.AuthorizedUserDetails; -import com.flyfish.framework.enums.UserType; -import lombok.Getter; -import lombok.Setter; -import org.apache.commons.lang3.BooleanUtils; -import org.bson.types.ObjectId; -import org.springframework.data.mongodb.core.query.Criteria; - -/** - * 拥有归属权的授权查询 - * - * @param 泛型 - * @author wangyu - * 将会额外查询归属者的内容 - */ -@Getter -@Setter -public class OwnedAuthorizedQo extends AbstractAuthorizedQo { - - @Override - public CriteriaBuilder criteriaBuilder() { - // 超级管理员拥有查看所有草稿的权限 - if (user.getType() == UserType.SUPER_ADMIN) { - return super.criteriaBuilder().with(this::withPublished); - } - // 查询草稿,只查询自己的 - if (BooleanUtils.isFalse(published)) { - return super.criteriaBuilder() - .with(this::withPublished) - .with(() -> Criteria.where("$or").is( - CriteriaBuilder.createCriteriaList( - Criteria.where("creatorId").is(user.getId()), - Criteria.where("owners.$id").is(new ObjectId(user.getId())) - ) - )); - } - // 普通查询,根据权限配置查询 - return super.criteriaBuilder() - .with(this::withPublished) - .with(() -> Criteria.where("$or").is( - CriteriaBuilder.createCriteriaList( - Criteria.where("authorizeId").in(authorizeIds()), - Criteria.where("creatorId").is(user.getId()) - .and("authorizeId").in(((AuthorizedUserDetails) user).getVisibleDeparts()), - Criteria.where("owners.$id").is(new ObjectId(user.getId())) - ) - )); - } -} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/tree/TreeQo.java b/flyfish-data/src/main/java/com/flyfish/framework/domain/tree/TreeQo.java deleted file mode 100644 index 35a87c8..0000000 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/tree/TreeQo.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.flyfish.framework.domain.tree; - -import com.flyfish.framework.builder.CriteriaBuilder; -import com.flyfish.framework.domain.base.Domain; -import com.flyfish.framework.domain.base.NameLikeQo; -import lombok.Getter; -import lombok.Setter; -import org.apache.commons.lang3.BooleanUtils; -import org.springframework.data.mongodb.core.query.Criteria; - -import java.util.List; - -/** - * 属性菜单的qo - */ -@Getter -@Setter -public class TreeQo extends NameLikeQo { - - private Integer depth; - - private String parentId; - - private List parentIds; - - private Boolean recursive; - - @Override - public CriteriaBuilder criteriaBuilder() { - CriteriaBuilder builder = super.criteriaBuilder().with("depth"); - if (BooleanUtils.isTrue(recursive)) { - builder.with("parentId", "parentIds", Criteria::is) - .with("parentIds", "parentIds", CriteriaBuilder.Builders.IN); - } else { - builder.with("parentId").with("parentIds", "parentId", CriteriaBuilder.Builders.IN); - } - return builder; - } -} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/DefaultReactiveRepository.java b/flyfish-data/src/main/java/com/flyfish/framework/repository/DefaultReactiveRepository.java deleted file mode 100644 index 3d48183..0000000 --- a/flyfish-data/src/main/java/com/flyfish/framework/repository/DefaultReactiveRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.flyfish.framework.repository; - -import com.flyfish.framework.repository.base.DomainRepository; -import org.springframework.data.mongodb.repository.ReactiveMongoRepository; -import org.springframework.data.repository.NoRepositoryBean; - - -/** - * 默认的持久层dao - * - * @param 泛型 - */ -@NoRepositoryBean -public interface DefaultReactiveRepository extends ReactiveMongoRepository, ReactiveQueryModelExecutor, - DomainRepository { - -} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/DefaultRepository.java b/flyfish-data/src/main/java/com/flyfish/framework/repository/DefaultRepository.java deleted file mode 100644 index 22ed705..0000000 --- a/flyfish-data/src/main/java/com/flyfish/framework/repository/DefaultRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.flyfish.framework.repository; - -import com.flyfish.framework.domain.base.Domain; -import com.flyfish.framework.repository.base.DomainRepository; -import org.springframework.data.mongodb.repository.MongoRepository; -import org.springframework.data.repository.NoRepositoryBean; - -/** - * 默认的仓库 - * - * @author wangyu - */ -@NoRepositoryBean -public interface DefaultRepository extends MongoRepository, QueryModelExecutor, - DomainRepository { - -} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/QueryBuildUtils.java b/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/QueryBuildUtils.java deleted file mode 100644 index 2dedee1..0000000 --- a/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/QueryBuildUtils.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.flyfish.framework.repository.impl; - -import com.flyfish.framework.domain.base.Qo; -import com.flyfish.framework.utils.CopyUtils; -import org.apache.commons.collections4.CollectionUtils; -import org.springframework.data.domain.Example; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; - -import java.util.Optional; - -abstract class QueryBuildUtils { - - /** - * 从查询实体抽取内部查询信息 - * - * @param qo 查询实体 - * @return 结果 - */ - static Optional getQuery(Qo qo) { - return buildQuery(qo).map(query -> { - if (CollectionUtils.isNotEmpty(qo.getFields())) { - query.fields().include(qo.getFields().toArray(new String[]{})); - } - return query; - }); - } - - /** - * 构建查询 - * - * @param qo 查询实体 - * @param 泛型 - * @return 结果 - */ - static Optional buildQuery(Qo qo) { - Criteria criteria = null; - if (null != qo.getCriteria()) { - criteria = qo.getCriteria(); - } else if (null != qo.getExample()) { - criteria = new Criteria().alike(qo.getExample()); - } else { - Class type = qo.pojoType(); - if (null != type && !Object.class.equals(type)) { - try { - T pojo = CopyUtils.copyQueryProps(qo, qo.pojoType().newInstance()); - criteria = new Criteria().alike(Example.of(pojo)); - } catch (InstantiationException | IllegalAccessException e) { - e.printStackTrace(); - } - } - } - if (criteria != null) { - // 针对删除状态全局筛选 - return Optional.of(new Query(Criteria.where("delete").ne(true).andOperator(criteria)) - .with(qo.sorts())); - } - return Optional.empty(); - } -} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/utils/Query.java b/flyfish-data/src/main/java/com/flyfish/framework/utils/Query.java deleted file mode 100644 index afb659a..0000000 --- a/flyfish-data/src/main/java/com/flyfish/framework/utils/Query.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.flyfish.framework.utils; - - -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * 查询参数 - */ -public class Query extends LinkedHashMap { - private static final long serialVersionUID = 1L; - //当前页码 - private int page = 1; - //每页条数 - private int limit = 10; - - public Query(Map params) { - this.putAll(params); - //分页参数 - if (params.get("page") != null) { - this.page = Integer.parseInt(params.get("page").toString()); - } - if (params.get("limit") != null) { - this.limit = Integer.parseInt(params.get("limit").toString()); - } - this.remove("page"); - this.remove("limit"); - } - - - public int getPage() { - return page; - } - - public void setPage(int page) { - this.page = page; - } - - public int getLimit() { - return limit; - } - - public void setLimit(int limit) { - this.limit = limit; - } -} diff --git a/flyfish-dict/pom.xml b/flyfish-dict/pom.xml index 0b69516..09fbacb 100644 --- a/flyfish-dict/pom.xml +++ b/flyfish-dict/pom.xml @@ -5,7 +5,7 @@ flyfish-framework com.flyfish.framework - 0.0.2-SNAPSHOT + ${revision} 4.0.0 @@ -18,10 +18,20 @@ + + org.springframework.data + spring-data-relational + true + + + org.springframework.data + spring-data-mongodb + true + com.flyfish.framework flyfish-web - ${project.version} + ${revision} true diff --git a/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/AutoComplete.java b/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/AutoComplete.java index ebdbae0..2f87476 100644 --- a/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/AutoComplete.java +++ b/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/AutoComplete.java @@ -3,7 +3,9 @@ package com.flyfish.framework.dict.domain; import com.flyfish.framework.domain.base.AuditDomain; import lombok.Getter; import lombok.Setter; +import org.springframework.data.annotation.Reference; import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.relational.core.mapping.Table; import java.util.List; @@ -15,9 +17,11 @@ import java.util.List; @Getter @Setter @Document(collection = "auto-completes") +@Table("auto_completes") public class AutoComplete extends AuditDomain { // 候选值列表 + @Reference private List values; // 是否多级联动 diff --git a/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/Dictionary.java b/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/Dictionary.java index c736038..b2719ed 100644 --- a/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/Dictionary.java +++ b/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/Dictionary.java @@ -5,6 +5,7 @@ import lombok.Getter; import lombok.Setter; import org.apache.commons.lang3.StringUtils; import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.relational.core.mapping.Table; import java.util.List; import java.util.Objects; @@ -17,6 +18,7 @@ import java.util.Objects; @Getter @Setter @Document(collection = "dictionaries") +@Table("dictionary") public class Dictionary extends AuditDomain { // 字典表的值 diff --git a/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/DictionaryQo.java b/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/DictionaryQo.java index 0fc7c81..0b1c6ad 100644 --- a/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/DictionaryQo.java +++ b/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/DictionaryQo.java @@ -1,7 +1,7 @@ package com.flyfish.framework.dict.domain; -import com.flyfish.framework.builder.CriteriaBuilder; import com.flyfish.framework.domain.base.NameLikeQo; +import com.flyfish.framework.query.QueryDefinition; import lombok.Getter; import lombok.Setter; import org.apache.commons.collections4.CollectionUtils; @@ -22,8 +22,8 @@ public class DictionaryQo extends NameLikeQo { private List codes; @Override - public CriteriaBuilder criteriaBuilder() { - return super.criteriaBuilder().with("codes", "code", CriteriaBuilder.Builders.IN); + public QueryDefinition queryBuilder() { + return super.queryBuilder().mutate().and(Dictionary::getCode).in(codes); } @Override diff --git a/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/DictionaryValue.java b/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/DictionaryValue.java index 966fcc0..cedc489 100644 --- a/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/DictionaryValue.java +++ b/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/DictionaryValue.java @@ -1,6 +1,7 @@ package com.flyfish.framework.dict.domain; import lombok.Data; +import org.springframework.data.relational.core.mapping.Table; /** * 字典表的值 @@ -8,6 +9,7 @@ import lombok.Data; * @author wangyu */ @Data +@Table("dictionary_value") public class DictionaryValue { // 显示文字 diff --git a/flyfish-file/pom.xml b/flyfish-file/pom.xml index ad161c3..ac81a8b 100644 --- a/flyfish-file/pom.xml +++ b/flyfish-file/pom.xml @@ -5,7 +5,7 @@ flyfish-framework com.flyfish.framework - 0.0.2-SNAPSHOT + ${revision} 4.0.0 @@ -17,10 +17,20 @@ + + org.springframework.data + spring-data-relational + true + + + org.springframework.data + spring-data-mongodb + true + com.flyfish.framework flyfish-web - ${project.version} + ${revision} true diff --git a/flyfish-file/src/main/java/com/flyfish/framework/file/domain/Attachment.java b/flyfish-file/src/main/java/com/flyfish/framework/file/domain/Attachment.java index 74ab193..8673d31 100644 --- a/flyfish-file/src/main/java/com/flyfish/framework/file/domain/Attachment.java +++ b/flyfish-file/src/main/java/com/flyfish/framework/file/domain/Attachment.java @@ -4,8 +4,10 @@ import com.flyfish.framework.annotations.Property; import com.flyfish.framework.domain.base.AuditDomain; import lombok.*; import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.relational.core.mapping.Table; @Document(collection = "attachments") +@Table("attachment") @Getter @Setter @AllArgsConstructor diff --git a/flyfish-form/pom.xml b/flyfish-form/pom.xml index 724ec7d..2dd4b17 100644 --- a/flyfish-form/pom.xml +++ b/flyfish-form/pom.xml @@ -5,7 +5,7 @@ flyfish-framework com.flyfish.framework - 0.0.2-SNAPSHOT + ${revision} 4.0.0 @@ -19,13 +19,22 @@ com.flyfish.framework - flyfish-data - ${project.version} + flyfish-data-common com.flyfish.framework flyfish-web - ${project.version} + ${revision} + + + org.springframework.data + spring-data-relational + true + + + org.springframework.data + spring-data-mongodb + true diff --git a/flyfish-form/src/main/java/com/flyfish/framework/form/domain/OnlineForm.java b/flyfish-form/src/main/java/com/flyfish/framework/form/domain/OnlineForm.java index 06b14ee..79ada3f 100644 --- a/flyfish-form/src/main/java/com/flyfish/framework/form/domain/OnlineForm.java +++ b/flyfish-form/src/main/java/com/flyfish/framework/form/domain/OnlineForm.java @@ -6,6 +6,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.data.mongodb.core.index.CompoundIndex; import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.relational.core.mapping.Table; import java.util.ArrayList; import java.util.List; @@ -14,9 +15,10 @@ import java.util.List; * 在线表单 */ @Document("online-forms") +@CompoundIndex(name = "uniq_code", def = "{code: 1}", unique = true) +@Table("online_form") @Data @EqualsAndHashCode(callSuper = true) -@CompoundIndex(name = "uniq_code", def = "{code: 1}", unique = true) public class OnlineForm extends Domain { // 表单描述 diff --git a/flyfish-logging/pom.xml b/flyfish-logging/pom.xml index fcfca11..b0bff11 100644 --- a/flyfish-logging/pom.xml +++ b/flyfish-logging/pom.xml @@ -5,7 +5,7 @@ flyfish-framework com.flyfish.framework - 0.0.2-SNAPSHOT + ${revision} 4.0.0 @@ -18,10 +18,20 @@ + + org.springframework.data + spring-data-relational + true + + + org.springframework.data + spring-data-mongodb + true + com.flyfish.framework flyfish-web - ${project.version} + ${revision} diff --git a/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/Log.java b/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/Log.java index 7aa7574..1d2e017 100644 --- a/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/Log.java +++ b/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/Log.java @@ -4,6 +4,7 @@ import com.flyfish.framework.domain.base.Domain; import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.relational.core.mapping.Table; import java.util.Date; @@ -11,6 +12,7 @@ import java.util.Date; * 日志集合 */ @Document +@Table @Data @EqualsAndHashCode(callSuper = true) public class Log extends Domain { diff --git a/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/LogQo.java b/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/LogQo.java index 49b578b..c42d9fb 100644 --- a/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/LogQo.java +++ b/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/LogQo.java @@ -1,8 +1,7 @@ package com.flyfish.framework.logging.domain; -import com.flyfish.framework.builder.CriteriaBuilder; -import com.flyfish.framework.domain.base.BaseQo; import com.flyfish.framework.domain.base.NameLikeQo; +import com.flyfish.framework.query.QueryDefinition; import lombok.Getter; import lombok.Setter; import org.springframework.data.domain.Sort; @@ -29,11 +28,14 @@ public class LogQo extends NameLikeQo { private String type; @Override - public CriteriaBuilder criteriaBuilder() { - return super.criteriaBuilder() - .with("operator", CriteriaBuilder.Builders.LIKE) - .with("type", "module", "success") - .with("range", "startTime", CriteriaBuilder.Builders.DATE_RANGE); + public QueryDefinition queryBuilder() { + return super.queryBuilder() + .mutate() + .and(Log::getOperator).like(operator) + .and(Log::getType).eq(type) + .and(Log::getModule).eq(module) + .and(Log::getSuccess).eq(success) + .and(Log::getStartTime).between(range); } @Override diff --git a/flyfish-user/pom.xml b/flyfish-user/pom.xml index 78829bb..74bbb3e 100644 --- a/flyfish-user/pom.xml +++ b/flyfish-user/pom.xml @@ -5,7 +5,7 @@ flyfish-framework com.flyfish.framework - 0.0.2-SNAPSHOT + ${revision} 4.0.0 @@ -18,15 +18,24 @@ + + org.springframework.data + spring-data-r2dbc + true + + + org.springframework.data + spring-data-mongodb + true + com.flyfish.framework - flyfish-data - ${project.version} + flyfish-data-common com.flyfish.framework flyfish-web - ${project.version} + ${revision} com.dingxiang-inc diff --git a/flyfish-user/src/main/java/com/flyfish/framework/annotations/EnableAutoSecurity.java b/flyfish-user/src/main/java/com/flyfish/framework/annotations/EnableAutoSecurity.java index 8a9617e..b8d25fc 100644 --- a/flyfish-user/src/main/java/com/flyfish/framework/annotations/EnableAutoSecurity.java +++ b/flyfish-user/src/main/java/com/flyfish/framework/annotations/EnableAutoSecurity.java @@ -3,7 +3,6 @@ package com.flyfish.framework.annotations; import com.flyfish.framework.config.WebSecurityConfig; import com.flyfish.framework.configuration.redis.EnableReactiveRedis; import org.springframework.context.annotation.Import; -import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories; import java.lang.annotation.*; @@ -16,7 +15,6 @@ import java.lang.annotation.*; @Target({ElementType.TYPE}) @Documented @Import(WebSecurityConfig.class) -@EnableReactiveMongoRepo @EnableReactiveRedis public @interface EnableAutoSecurity { } diff --git a/flyfish-user/src/main/java/com/flyfish/framework/domain/PermissionQo.java b/flyfish-user/src/main/java/com/flyfish/framework/domain/PermissionQo.java index 98e5832..fb78326 100644 --- a/flyfish-user/src/main/java/com/flyfish/framework/domain/PermissionQo.java +++ b/flyfish-user/src/main/java/com/flyfish/framework/domain/PermissionQo.java @@ -1,9 +1,9 @@ package com.flyfish.framework.domain; -import com.flyfish.framework.builder.CriteriaBuilder; -import com.flyfish.framework.domain.tree.TreeQo; import com.flyfish.framework.domain.po.Permission; +import com.flyfish.framework.domain.tree.TreeQo; +import com.flyfish.framework.query.QueryDefinition; import lombok.Getter; import lombok.Setter; import org.springframework.data.domain.Sort; @@ -27,7 +27,9 @@ public class PermissionQo extends TreeQo { } @Override - public CriteriaBuilder criteriaBuilder() { - return super.criteriaBuilder().with("admin", "type"); + public QueryDefinition queryBuilder() { + return super.queryBuilder().mutate() + .and(Permission::isAdmin).eq(admin) + .and(Permission::getType).eq(type); } } diff --git a/flyfish-user/src/main/java/com/flyfish/framework/domain/RoleQo.java b/flyfish-user/src/main/java/com/flyfish/framework/domain/RoleQo.java index bc842dd..ff48ddc 100644 --- a/flyfish-user/src/main/java/com/flyfish/framework/domain/RoleQo.java +++ b/flyfish-user/src/main/java/com/flyfish/framework/domain/RoleQo.java @@ -1,8 +1,8 @@ package com.flyfish.framework.domain; -import com.flyfish.framework.builder.CriteriaBuilder; import com.flyfish.framework.domain.base.NameLikeQo; import com.flyfish.framework.domain.po.Role; +import com.flyfish.framework.query.QueryDefinition; import lombok.Getter; import lombok.Setter; @@ -33,8 +33,11 @@ public class RoleQo extends NameLikeQo { private List additions; @Override - public CriteriaBuilder criteriaBuilder() { - return super.criteriaBuilder().with("admin", "system"); + public QueryDefinition queryBuilder() { + return super.queryBuilder() + .mutate() + .and(Role::getAdmin).eq(admin) + .and(Role::isSystem).eq(system); } /** diff --git a/flyfish-user/src/main/java/com/flyfish/framework/domain/UserQo.java b/flyfish-user/src/main/java/com/flyfish/framework/domain/UserQo.java index 5dc29d9..fd667cb 100644 --- a/flyfish-user/src/main/java/com/flyfish/framework/domain/UserQo.java +++ b/flyfish-user/src/main/java/com/flyfish/framework/domain/UserQo.java @@ -1,10 +1,9 @@ package com.flyfish.framework.domain; -import com.flyfish.framework.builder.CriteriaBuilder; import com.flyfish.framework.domain.base.NameLikeQo; import com.flyfish.framework.domain.po.User; +import com.flyfish.framework.query.QueryDefinition; import lombok.*; -import org.springframework.data.mongodb.core.query.Criteria; import java.util.List; @@ -28,8 +27,14 @@ public class UserQo extends NameLikeQo { private List departments; @Override - public CriteriaBuilder criteriaBuilder() { - return super.criteriaBuilder().with("type", "username", "password", "phone", "status") - .with("departments", "departments", CriteriaBuilder.Builders.IN); + public QueryDefinition queryBuilder() { + return super.queryBuilder() + .mutate() + .and(User::getType).eq(type) + .and(User::getUsername).eq(username) + .and(User::getPassword).eq(password) + .and(User::getPhone).eq(phone) + .and(User::getStatus).eq(status) + .and(User::getDepartments).in(departments); } } diff --git a/flyfish-user/src/main/java/com/flyfish/framework/service/DepartmentService.java b/flyfish-user/src/main/java/com/flyfish/framework/service/DepartmentService.java index e9de4b2..c8efb90 100644 --- a/flyfish-user/src/main/java/com/flyfish/framework/service/DepartmentService.java +++ b/flyfish-user/src/main/java/com/flyfish/framework/service/DepartmentService.java @@ -1,126 +1,22 @@ package com.flyfish.framework.service; -import com.flyfish.framework.domain.AdminUserDetails; -import com.flyfish.framework.domain.DepartmentQo; -import com.flyfish.framework.domain.base.Qo; import com.flyfish.framework.domain.po.Department; -import com.flyfish.framework.domain.tree.TreeDomain; -import com.flyfish.framework.enums.UserType; -import com.flyfish.framework.service.impl.BaseReactiveServiceImpl; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.BooleanUtils; -import org.apache.commons.lang3.StringUtils; -import org.springframework.data.mongodb.core.ReactiveMongoOperations; -import org.springframework.data.mongodb.core.aggregation.Aggregation; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.stereotype.Service; -import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import javax.annotation.Resource; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; import java.util.Set; -import java.util.stream.Collectors; - -import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; /** * 部门服务 * * @author wangyu */ -@Service -@Slf4j -public class DepartmentService extends BaseReactiveServiceImpl { +public interface DepartmentService extends BaseReactiveService { - @Resource - private ReactiveMongoOperations reactiveMongoOperations; /** * 获取子部门列表 * * @return 结果 */ - public Mono> getSubCodes(Set parents) { - Query query = Query.query(Criteria.where("parentIds").in(parents)); - query.fields().include("_id"); - return reactiveMongoOperations.find(query, Department.class).map(Department::getId).collect(Collectors.toSet()); - } - - /** - * 查询列表 - * - * @param query 查询 - * @return 结果 - */ - @Override - public Flux getList(Qo query) { - return convertQo(query).flatMapMany(super::getList); - } - - /** - * 在一批编码中找到深度最小的值 - * - * @param codes 编码们 - * @return 结果 - */ - private Mono getMinDepthInIds(Collection codes) { - return reactiveMongoOperations.aggregate( - Aggregation.newAggregation( - Aggregation.match(Criteria.where("_id").in(codes)), - Aggregation.group().min("depth").as("depth")), - Department.class, Department.class) - .single() - .map(TreeDomain::getDepth); - } - - /** - * 转换qo,经过可见部门转换,更加私密 - * - * @param query 查询 - * @return 结果 - */ - private Mono> convertQo(Qo query) { - if (query instanceof DepartmentQo) { - DepartmentQo qo = (DepartmentQo) query; - // 如果是非管理员 - if (null != qo.getUser() && qo.getUser().getType() != UserType.SUPER_ADMIN) { - // 占位,包装查询实体 - Mono> mono = Mono.just(qo); - // 使用列表内的部门作为条件 - AdminUserDetails userDetails = (AdminUserDetails) query.getUser(); - // 是否设置过 - qo.setIds(userDetails.getVisibleDeparts()); - // 查询根节点下的节点 - if (Department.ROOT.equals(qo.getParentId())) { - qo.setParentId(null); - // 不递归,指定深度,保证单层 - if (BooleanUtils.isNotTrue(qo.getRecursive())) { - // 指定深度,从可见的列表中获取 - mono = getMinDepthInIds(userDetails.getVisibleDeparts()) - .map(depth -> { - qo.setDepth(depth); - return qo; - }); - } - } - // 如果存在额外的id,追加记录 - if (StringUtils.isNotBlank(qo.getAdditional())) { - Collection ids = defaultIfNull(qo.getIds(), new HashSet<>()); - ids.add(qo.getAdditional()); - qo.setIds(ids); - } - // 如果设置过ids,但是qo中ids为空,返回无效查询 - if (CollectionUtils.isEmpty(qo.getIds())) { - qo.setIds(Collections.singleton("null")); - } - return mono; - } - } - return Mono.just(query); - } + Mono> getSubCodes(Set parents); } diff --git a/flyfish-user/src/main/java/com/flyfish/framework/service/MongoUserDetailsServiceImpl.java b/flyfish-user/src/main/java/com/flyfish/framework/service/FlyfishUserDetailsServiceImpl.java similarity index 98% rename from flyfish-user/src/main/java/com/flyfish/framework/service/MongoUserDetailsServiceImpl.java rename to flyfish-user/src/main/java/com/flyfish/framework/service/FlyfishUserDetailsServiceImpl.java index 375384d..b8f0d78 100644 --- a/flyfish-user/src/main/java/com/flyfish/framework/service/MongoUserDetailsServiceImpl.java +++ b/flyfish-user/src/main/java/com/flyfish/framework/service/FlyfishUserDetailsServiceImpl.java @@ -29,13 +29,13 @@ import java.util.function.Function; import java.util.function.Supplier; /** - * 基于mongo实现的用户详情 + * 基于通用实现的用户详情 * * @author wangyu */ @RequiredArgsConstructor @Service -public class MongoUserDetailsServiceImpl implements MongoUserDetailsService { +public class FlyfishUserDetailsServiceImpl implements FlyfishUserDetailsService { // 存储用户校验规则的map private static final Map, Supplier> checkMap; diff --git a/flyfish-user/src/main/java/com/flyfish/framework/service/RoleService.java b/flyfish-user/src/main/java/com/flyfish/framework/service/RoleService.java index e45f330..0896eef 100644 --- a/flyfish-user/src/main/java/com/flyfish/framework/service/RoleService.java +++ b/flyfish-user/src/main/java/com/flyfish/framework/service/RoleService.java @@ -10,14 +10,13 @@ import com.flyfish.framework.domain.po.Permission; import com.flyfish.framework.domain.po.Role; import com.flyfish.framework.enums.RoleType; import com.flyfish.framework.enums.UserType; +import com.flyfish.framework.query.Queries; +import com.flyfish.framework.query.Query; +import com.flyfish.framework.repository.ReactiveEntityOperations; import com.flyfish.framework.service.impl.BaseReactiveServiceImpl; import lombok.RequiredArgsConstructor; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; -import org.apache.commons.lang3.StringUtils; -import org.springframework.data.mongodb.core.ReactiveMongoOperations; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -32,7 +31,7 @@ public class RoleService extends BaseReactiveServiceImpl { private final PermissionService permissionService; - private final ReactiveMongoOperations reactiveMongoOperations; + private final ReactiveEntityOperations reactiveEntityOperations; /** * 如果是管理员,设置拥有所有权限 @@ -69,9 +68,8 @@ public class RoleService extends BaseReactiveServiceImpl { * @return 结果 */ private Mono> getOwnedIds(IUser user) { - Query query = Query.query(Criteria.where("creatorId").is(user.getId())); - query.fields().include("_id"); - return reactiveMongoOperations.find(query, Role.class).map(Domain::getId).collect(Collectors.toSet()); + Query query = Query.query(Queries.where(Role::getCreatorId).eq(user.getId())).select(Role::getId); + return reactiveEntityOperations.findAll(query, this.getEntityInformation()).map(Domain::getId).collect(Collectors.toSet()); } /** diff --git a/flyfish-user/src/main/java/com/flyfish/framework/service/impl/DepartmentServiceHelper.java b/flyfish-user/src/main/java/com/flyfish/framework/service/impl/DepartmentServiceHelper.java new file mode 100644 index 0000000..097544e --- /dev/null +++ b/flyfish-user/src/main/java/com/flyfish/framework/service/impl/DepartmentServiceHelper.java @@ -0,0 +1,68 @@ +package com.flyfish.framework.service.impl; + +import com.flyfish.framework.domain.AdminUserDetails; +import com.flyfish.framework.domain.DepartmentQo; +import com.flyfish.framework.domain.base.Qo; +import com.flyfish.framework.domain.po.Department; +import com.flyfish.framework.enums.UserType; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import reactor.core.publisher.Mono; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.function.Function; + +import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; + +class DepartmentServiceHelper { + + /** + * 转换qo,经过可见部门转换,更加私密 + * + * @param query 查询 + * @return 结果 + */ + static Mono> convertQo(Qo query, Function, Mono> minDeptIds) { + if (query instanceof DepartmentQo) { + DepartmentQo qo = (DepartmentQo) query; + // 如果是非管理员 + if (null != qo.getUser() && qo.getUser().getType() != UserType.SUPER_ADMIN) { + // 占位,包装查询实体 + Mono> mono = Mono.just(qo); + // 使用列表内的部门作为条件 + AdminUserDetails userDetails = (AdminUserDetails) query.getUser(); + // 是否设置过 + qo.setIds(userDetails.getVisibleDeparts()); + // 查询根节点下的节点 + if (Department.ROOT.equals(qo.getParentId())) { + qo.setParentId(null); + // 不递归,指定深度,保证单层 + if (BooleanUtils.isNotTrue(qo.getRecursive())) { + // 指定深度,从可见的列表中获取 + mono = minDeptIds.apply(userDetails.getVisibleDeparts()) + .map(depth -> { + qo.setDepth(depth); + return qo; + }); + } + } + // 如果存在额外的id,追加记录 + if (StringUtils.isNotBlank(qo.getAdditional())) { + Collection ids = defaultIfNull(qo.getIds(), new HashSet<>()); + ids.add(qo.getAdditional()); + qo.setIds(ids); + } + // 如果设置过ids,但是qo中ids为空,返回无效查询 + if (CollectionUtils.isEmpty(qo.getIds())) { + qo.setIds(Collections.singleton("null")); + } + return mono; + } + } + return Mono.just(query); + } +} diff --git a/flyfish-user/src/main/java/com/flyfish/framework/service/impl/MongoDepartmentServiceImpl.java b/flyfish-user/src/main/java/com/flyfish/framework/service/impl/MongoDepartmentServiceImpl.java new file mode 100644 index 0000000..644b621 --- /dev/null +++ b/flyfish-user/src/main/java/com/flyfish/framework/service/impl/MongoDepartmentServiceImpl.java @@ -0,0 +1,75 @@ +package com.flyfish.framework.service.impl; + +import com.flyfish.framework.domain.base.Qo; +import com.flyfish.framework.domain.po.Department; +import com.flyfish.framework.domain.tree.TreeDomain; +import com.flyfish.framework.service.DepartmentService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.data.mongodb.core.ReactiveMongoOperations; +import org.springframework.data.mongodb.core.aggregation.Aggregation; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.Set; +import java.util.stream.Collectors; + +import static com.flyfish.framework.service.impl.DepartmentServiceHelper.convertQo; + +/** + * 部门服务 + * + * @author wangyu + */ +@Service +@Slf4j +@ConditionalOnClass(ReactiveMongoOperations.class) +public class MongoDepartmentServiceImpl extends BaseReactiveServiceImpl implements DepartmentService { + + @Resource + private ReactiveMongoOperations reactiveMongoOperations; + + /** + * 获取子部门列表 + * + * @return 结果 + */ + public Mono> getSubCodes(Set parents) { + Query query = Query.query(Criteria.where("parentIds").in(parents)); + query.fields().include("_id"); + return reactiveMongoOperations.find(query, Department.class).map(Department::getId).collect(Collectors.toSet()); + } + + /** + * 查询列表 + * + * @param query 查询 + * @return 结果 + */ + @Override + public Flux getList(Qo query) { + return convertQo(query, this::getMinDepthInIds).flatMapMany(super::getList); + } + + /** + * 在一批编码中找到深度最小的值 + * + * @param codes 编码们 + * @return 结果 + */ + private Mono getMinDepthInIds(Collection codes) { + return reactiveMongoOperations.aggregate( + Aggregation.newAggregation( + Aggregation.match(Criteria.where("_id").in(codes)), + Aggregation.group().min("depth").as("depth")), + Department.class, Department.class) + .single() + .map(TreeDomain::getDepth); + } + +} diff --git a/flyfish-user/src/main/java/com/flyfish/framework/service/impl/R2dbcDepartmentServiceImpl.java b/flyfish-user/src/main/java/com/flyfish/framework/service/impl/R2dbcDepartmentServiceImpl.java new file mode 100644 index 0000000..c75a7b4 --- /dev/null +++ b/flyfish-user/src/main/java/com/flyfish/framework/service/impl/R2dbcDepartmentServiceImpl.java @@ -0,0 +1,70 @@ +package com.flyfish.framework.service.impl; + +import com.flyfish.framework.domain.base.Qo; +import com.flyfish.framework.domain.po.Department; +import com.flyfish.framework.service.DepartmentService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.data.r2dbc.core.R2dbcEntityOperations; +import org.springframework.data.relational.core.query.Criteria; +import org.springframework.data.relational.core.query.Query; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.Set; +import java.util.stream.Collectors; + +import static com.flyfish.framework.service.impl.DepartmentServiceHelper.convertQo; + +/** + * 部门服务 + * + * @author wangyu + */ +@Service +@Slf4j +@ConditionalOnClass(R2dbcEntityOperations.class) +public class R2dbcDepartmentServiceImpl extends BaseReactiveServiceImpl implements DepartmentService { + + @Resource + private R2dbcEntityOperations r2dbcEntityOperations; + + /** + * 获取子部门列表 + * + * @return 结果 + */ + public Mono> getSubCodes(Set parents) { + Query query = Query.query(Criteria.where("parentIds").in(parents)); + query.columns("id"); + return r2dbcEntityOperations.select(query, Department.class).map(Department::getId).collect(Collectors.toSet()); + } + + /** + * 查询列表 + * + * @param query 查询 + * @return 结果 + */ + @Override + public Flux getList(Qo query) { + return convertQo(query, this::getMinDepthInIds).flatMapMany(super::getList); + } + + /** + * 在一批编码中找到深度最小的值 + * + * @param codes 编码们 + * @return 结果 + */ + private Mono getMinDepthInIds(Collection codes) { + return repository.findAllById(codes) + .map(Department::getDepth) + .reduce(Integer::min); + } + + +} diff --git a/flyfish-user/src/main/java/com/flyfish/framework/validation/.gitkeep b/flyfish-user/src/main/java/com/flyfish/framework/validation/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/flyfish-web/pom.xml b/flyfish-web/pom.xml index c1df05a..ce579af 100644 --- a/flyfish-web/pom.xml +++ b/flyfish-web/pom.xml @@ -5,7 +5,7 @@ flyfish-framework com.flyfish.framework - 0.0.2-SNAPSHOT + ${revision} 4.0.0 @@ -14,8 +14,7 @@ com.flyfish.framework - flyfish-data - ${project.version} + flyfish-data-common @@ -33,6 +32,17 @@ spring-boot-starter-cache + + org.springframework.data + spring-data-relational + true + + + org.springframework.data + spring-data-mongodb + true + + diff --git a/flyfish-web/src/main/java/com/flyfish/framework/beans/enums/ValidationCandidate.java b/flyfish-web/src/main/java/com/flyfish/framework/beans/enums/ValidationCandidate.java index 0fe49a1..1f18fe6 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/beans/enums/ValidationCandidate.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/beans/enums/ValidationCandidate.java @@ -78,7 +78,7 @@ public enum ValidationCandidate { ID_CARD((annotation, validation) -> validation.setValidator("idCard"), IdCard.class), // 唯一字段 UNIQUE_FIELD((annotation, validation) -> validation.setValidator("uniqueField") - .prop("field", annotation.getString("value")), UniqueField.class); + .prop("column", annotation.getString("value")), UniqueField.class); private final BiConsumer, BeanValidation> mapper; diff --git a/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanProperty.java b/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanProperty.java index cc1e8be..dee59bc 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanProperty.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanProperty.java @@ -26,7 +26,7 @@ import org.springframework.beans.BeanUtils; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.annotation.MergedAnnotation; import org.springframework.core.annotation.MergedAnnotations; -import org.springframework.data.mongodb.core.mapping.DBRef; +import org.springframework.data.annotation.Reference; import org.springframework.data.mongodb.core.mapping.Document; import java.beans.PropertyDescriptor; @@ -250,7 +250,7 @@ public class BeanProperty { property.prop("uri", ref).prop("mode", "multiple"); })) .or() - .as(DBRef.class) + .as(Reference.class) .then(a -> processDbRef(elementClass).ifPresent(ref -> { property.setType(BeanPropertyType.DB_REF); property.prop("uri", ref).prop("mode", "multiple"); diff --git a/flyfish-web/src/main/java/com/flyfish/framework/configuration/jwt/JwtSecurityContextRepository.java b/flyfish-web/src/main/java/com/flyfish/framework/configuration/jwt/JwtSecurityContextRepository.java index b8d34e1..2c6cffa 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/configuration/jwt/JwtSecurityContextRepository.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/configuration/jwt/JwtSecurityContextRepository.java @@ -1,6 +1,6 @@ package com.flyfish.framework.configuration.jwt; -import com.flyfish.framework.service.MongoUserDetailsService; +import com.flyfish.framework.service.FlyfishUserDetailsService; import lombok.extern.slf4j.Slf4j; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -18,7 +18,7 @@ import java.net.URI; public class JwtSecurityContextRepository implements ServerSecurityContextRepository { @Resource - private MongoUserDetailsService userDetailsService; + private FlyfishUserDetailsService userDetailsService; @Resource private TokenProvider tokenProvider; diff --git a/flyfish-web/src/main/java/com/flyfish/framework/configuration/redis/EnableRedis.java b/flyfish-web/src/main/java/com/flyfish/framework/configuration/redis/EnableRedis.java index 0142110..b40c7c6 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/configuration/redis/EnableRedis.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/configuration/redis/EnableRedis.java @@ -1,12 +1,12 @@ package com.flyfish.framework.configuration.redis; import org.springframework.context.annotation.Import; -import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories; import java.lang.annotation.*; /** * 启用自动security配置 + * * @author wangyu */ @Retention(RetentionPolicy.RUNTIME) diff --git a/flyfish-web/src/main/java/com/flyfish/framework/service/BaseReactiveService.java b/flyfish-web/src/main/java/com/flyfish/framework/service/BaseReactiveService.java index a44f3ce..8c760f2 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/service/BaseReactiveService.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/service/BaseReactiveService.java @@ -4,7 +4,6 @@ import com.flyfish.framework.bean.SyncVo; import com.flyfish.framework.domain.base.Domain; import com.flyfish.framework.domain.base.DomainService; import com.flyfish.framework.domain.base.Qo; -import com.flyfish.framework.repository.DefaultReactiveRepository; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import reactor.core.publisher.Flux; @@ -20,14 +19,6 @@ import java.util.List; */ public interface BaseReactiveService extends DomainService { - /** - * 查询 - * - * @param entity 实体本身 - * @return 结果 - */ - Mono getOne(T entity); - /** * 查询 * @@ -69,14 +60,6 @@ public interface BaseReactiveService extends DomainService { */ Flux getByValues(String key, List values); - /** - * 查询列表 - * - * @param entity 实体本身 - * @return 结果 - */ - Flux getList(T entity); - /** * 查询列表 * @@ -85,14 +68,6 @@ public interface BaseReactiveService extends DomainService { */ Flux getList(Qo query); - /** - * 分页查询列表 - * - * @param entity 实体本身 - * @return 结果 - */ - Mono> getPageList(T entity, Pageable pageable); - /** * 分页查询列表 * @@ -115,14 +90,6 @@ public interface BaseReactiveService extends DomainService { */ Mono countAll(); - /** - * 查询总记录数 - * - * @param entity 通过实体查询个数 - * @return 结果 - */ - Mono count(T entity); - /** * 查询总记录数 * @@ -195,13 +162,6 @@ public interface BaseReactiveService extends DomainService { */ Mono deleteAll(Qo qo); - /** - * 通过某一个键删除所有 - * - * @param entity 查询 - */ - Mono deleteAll(T entity); - /** * 删除全部实体,危险! */ diff --git a/flyfish-web/src/main/java/com/flyfish/framework/service/BaseService.java b/flyfish-web/src/main/java/com/flyfish/framework/service/BaseService.java index e02b42b..755391d 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/service/BaseService.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/service/BaseService.java @@ -5,7 +5,6 @@ import com.flyfish.framework.domain.base.Domain; import com.flyfish.framework.domain.base.DomainService; import com.flyfish.framework.domain.base.Qo; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import java.util.Collection; import java.util.List; @@ -19,14 +18,6 @@ import java.util.Optional; */ public interface BaseService extends DomainService { - /** - * 查询 - * - * @param entity 实体本身 - * @return 结果 - */ - Optional getOne(T entity); - /** * 查询 * @@ -68,14 +59,6 @@ public interface BaseService extends DomainService { */ List getByValues(String key, List values); - /** - * 查询列表 - * - * @param entity 实体本身 - * @return 结果 - */ - List getList(T entity); - /** * 查询列表 * @@ -84,14 +67,6 @@ public interface BaseService extends DomainService { */ List getList(Qo query); - /** - * 分页查询列表 - * - * @param entity 实体本身 - * @return 结果 - */ - Page getPageList(T entity, Pageable pageable); - /** * 分页查询列表 * @@ -114,14 +89,6 @@ public interface BaseService extends DomainService { */ Long countAll(); - /** - * 查询总记录数 - * - * @param entity 通过实体查询个数 - * @return 结果 - */ - Long count(T entity); - /** * 查询总记录数 * @@ -186,13 +153,6 @@ public interface BaseService extends DomainService { */ void deleteAll(Qo qo); - /** - * 通过某一个键删除所有 - * - * @param entity 查询 - */ - void deleteAll(T entity); - /** * 删除全部实体,危险! */ diff --git a/flyfish-web/src/main/java/com/flyfish/framework/service/MongoUserDetailsService.java b/flyfish-web/src/main/java/com/flyfish/framework/service/FlyfishUserDetailsService.java similarity index 88% rename from flyfish-web/src/main/java/com/flyfish/framework/service/MongoUserDetailsService.java rename to flyfish-web/src/main/java/com/flyfish/framework/service/FlyfishUserDetailsService.java index 1b95d10..ca1846b 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/service/MongoUserDetailsService.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/service/FlyfishUserDetailsService.java @@ -14,8 +14,8 @@ import reactor.core.publisher.Mono; * * @author wangyu */ -@Qualifier("mongoUserDetailsService") -public interface MongoUserDetailsService extends ReactiveUserDetailsService, ReactiveUserDetailsPasswordService { +@Qualifier("flyfishUserDetailsService") +public interface FlyfishUserDetailsService extends ReactiveUserDetailsService, ReactiveUserDetailsPasswordService { /** * 针对微信端,即时校验登录 diff --git a/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseReactiveServiceImpl.java b/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseReactiveServiceImpl.java index 4751747..6da1ac7 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseReactiveServiceImpl.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseReactiveServiceImpl.java @@ -14,17 +14,13 @@ import com.flyfish.framework.utils.Assert; import com.flyfish.framework.utils.CopyUtils; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Example; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.data.mongodb.repository.query.MongoEntityInformation; +import org.springframework.data.repository.core.EntityInformation; import org.springframework.data.util.CastUtils; import org.springframework.transaction.annotation.Transactional; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -51,17 +47,6 @@ public class BaseReactiveServiceImpl implements BaseReactiveSe @Autowired private ReactiveBeanAuditor authorizeAuditor; - /** - * 查询 - * - * @param entity 实体本身 - * @return 结果 - */ - @Override - public Mono getOne(T entity) { - return repository.findOne(Example.of(entity)); - } - /** * 查询 * @@ -118,17 +103,6 @@ public class BaseReactiveServiceImpl implements BaseReactiveSe return repository.findAllByValues(key, values); } - /** - * 查询列表 - * - * @param entity 实体本身 - * @return 结果 - */ - @Override - public Flux getList(T entity) { - return repository.findAll(Example.of(entity)); - } - /** * 查询列表 * @@ -140,24 +114,6 @@ public class BaseReactiveServiceImpl implements BaseReactiveSe return repository.findAll(query); } - /** - * 分页查询列表 - * - * @param entity 实体本身 - * @param pageable 分页 - * @return 结果 - */ - @Override - public Mono> getPageList(T entity, Pageable pageable) { - return repository.findAll(Example.of(entity), pageable.getSort()) - .buffer(pageable.getPageSize(), (int) pageable.getOffset()) - .reduce(new PageImpl<>(new ArrayList<>()), (result, item) -> { - List list = result.getContent(); - list.addAll(item); - return new PageImpl<>(list, pageable, result.getTotalElements()); - }); - } - /** * 分页查询列表 * @@ -189,17 +145,6 @@ public class BaseReactiveServiceImpl implements BaseReactiveSe return repository.count(); } - /** - * 查询总记录数 - * - * @param entity 通过实体查询个数 - * @return 结果 - */ - @Override - public Mono count(T entity) { - return repository.count(Example.of(entity)); - } - /** * 查询总记录数 * @@ -316,17 +261,6 @@ public class BaseReactiveServiceImpl implements BaseReactiveSe return repository.deleteAll(qo); } - /** - * 通过某一个键删除所有 - * - * @param entity 查询 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public Mono deleteAll(T entity) { - return repository.delete(entity); - } - /** * 删除全部实体,危险! */ @@ -431,7 +365,7 @@ public class BaseReactiveServiceImpl implements BaseReactiveSe * @return 结果 */ @Override - public MongoEntityInformation getEntityInformation() { + public EntityInformation getEntityInformation() { return repository.getEntityInformation(); } } diff --git a/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseServiceImpl.java b/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseServiceImpl.java index 9f9d105..3a81f10 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseServiceImpl.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseServiceImpl.java @@ -13,10 +13,8 @@ import com.flyfish.framework.utils.Assert; import com.flyfish.framework.utils.CopyUtils; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Example; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.mongodb.repository.query.MongoEntityInformation; +import org.springframework.data.repository.core.EntityInformation; import java.util.*; import java.util.stream.Collectors; @@ -41,17 +39,6 @@ public class BaseServiceImpl implements BaseService { @Autowired private BeanAuditor authorizeAuditor; - /** - * 查询 - * - * @param entity 实体本身 - * @return 结果 - */ - @Override - public Optional getOne(T entity) { - return repository.findOne(Example.of(entity)); - } - /** * 查询 * @@ -101,17 +88,6 @@ public class BaseServiceImpl implements BaseService { return repository.findAllByValues(key, values); } - /** - * 查询列表 - * - * @param entity 实体本身 - * @return 结果 - */ - @Override - public List getList(T entity) { - return repository.findAll(Example.of(entity)); - } - /** * 查询列表 * @@ -123,17 +99,6 @@ public class BaseServiceImpl implements BaseService { return (List) repository.findAll(query); } - /** - * 分页查询列表 - * - * @param entity 实体本身 - * @return 结果 - */ - @Override - public Page getPageList(T entity, Pageable pageable) { - return repository.findAll(Example.of(entity), pageable); - } - /** * 分页查询列表 * @@ -165,17 +130,6 @@ public class BaseServiceImpl implements BaseService { return repository.count(); } - /** - * 查询总记录数 - * - * @param entity 通过实体查询个数 - * @return 结果 - */ - @Override - public Long count(T entity) { - return repository.count(Example.of(entity)); - } - /** * 查询总记录数 * @@ -274,16 +228,6 @@ public class BaseServiceImpl implements BaseService { repository.deleteAll(list); } - /** - * 通过某一个键删除所有 - * - * @param entity 查询 - */ - @Override - public void deleteAll(T entity) { - repository.delete(entity); - } - /** * 删除全部实体,危险! */ @@ -386,7 +330,7 @@ public class BaseServiceImpl implements BaseService { * @return 结果 */ @Override - public MongoEntityInformation getEntityInformation() { + public EntityInformation getEntityInformation() { return repository.getEntityInformation(); } } diff --git a/pom.xml b/pom.xml index 135cb67..50a8693 100644 --- a/pom.xml +++ b/pom.xml @@ -6,17 +6,18 @@ com.flyfish.framework flyfish-framework - 0.0.2-SNAPSHOT + ${revision} pom org.springframework.boot spring-boot-starter-parent - 2.7.14 + 2.7.18 + 1.0.0-SNAPSHOT flyfish 0.27.2 UTF-8 @@ -26,6 +27,8 @@ Finchley.SR1 0.11.0 0.10.2 + 1.1.3 + 1.5.0 @@ -77,12 +80,26 @@ com.alibaba fastjson - 1.2.56 + 2.0.51 + + + com.flyfish.framework + flyfish-common + ${revision} + + + + com.flyfish.framework + flyfish-data-common + ${revision} + compile + + org.apache.commons commons-collections4 @@ -108,6 +125,12 @@ ctu-client-sdk 2.4 + + + io.asyncer + r2dbc-mysql + ${r2dbc-mysql.version} + @@ -127,6 +150,32 @@ org.apache.maven.plugins maven-source-plugin + + + org.codehaus.mojo + flatten-maven-plugin + ${flatten-maven-plugin.version} + + resolveCiFriendliesOnly + true + + + + + flatten + + flatten + process-resources + + + + clean + + flatten.clean + clean + + +