feat: 实现各种关联条件

This commit is contained in:
wangyu 2024-06-29 14:08:02 +08:00
parent 89eaae41d5
commit 7f48c55203
16 changed files with 97 additions and 25 deletions

View File

@ -24,7 +24,7 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.flyfish.framework</groupId> <groupId>com.flyfish.framework</groupId>
<artifactId>flyfish-data-r2dbc</artifactId> <artifactId>flyfish-data-relational</artifactId>
<version>${revision}</version> <version>${revision}</version>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>

View File

@ -3,7 +3,7 @@ package com.flyfish.framework.domain.po;
import com.flyfish.framework.domain.base.AuditDomain; import com.flyfish.framework.domain.base.AuditDomain;
import com.flyfish.framework.enums.NamedEnum; import com.flyfish.framework.enums.NamedEnum;
import com.flyfish.framework.enums.RoleType; import com.flyfish.framework.enums.RoleType;
import com.flyfish.framework.r2dbc.mapping.Association; import com.flyfish.framework.relational.mapping.Association;
import lombok.*; import lombok.*;
import org.springframework.data.mongodb.core.mapping.DBRef; import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;

View File

@ -6,7 +6,7 @@ import com.flyfish.framework.domain.base.AuditDomain;
import com.flyfish.framework.domain.base.IUser; import com.flyfish.framework.domain.base.IUser;
import com.flyfish.framework.enums.UserStatus; import com.flyfish.framework.enums.UserStatus;
import com.flyfish.framework.enums.UserType; import com.flyfish.framework.enums.UserType;
import com.flyfish.framework.r2dbc.mapping.Association; import com.flyfish.framework.relational.mapping.Association;
import com.flyfish.framework.validation.spi.ConditionalGroup; import com.flyfish.framework.validation.spi.ConditionalGroup;
import lombok.*; import lombok.*;
import org.springframework.data.annotation.Transient; import org.springframework.data.annotation.Transient;

View File

@ -21,6 +21,11 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId> <artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.flyfish.framework</groupId>
<artifactId>flyfish-data-relational</artifactId>
<version>${revision}</version>
</dependency>
<dependency> <dependency>
<groupId>io.asyncer</groupId> <groupId>io.asyncer</groupId>
<artifactId>r2dbc-mysql</artifactId> <artifactId>r2dbc-mysql</artifactId>

View File

@ -45,9 +45,8 @@ public class R2dbcDataConfig {
} }
@Bean @Bean
public EntityCallback<Domain> referenceR2dbcCallback(R2dbcEntityOperations entityOperations, R2dbcMetadataManager metadataManager) { public EntityCallback<Domain> referenceR2dbcCallback(R2dbcMetadataManager metadataManager) {
return new ReferenceR2dbcCallback(metadataManager, entityOperations.getDatabaseClient(), entityOperations.getDataAccessStrategy() return new ReferenceR2dbcCallback(metadataManager);
.getStatementMapper());
} }
@Bean @Bean

View File

@ -19,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.r2dbc.core.R2dbcEntityOperations;
import org.springframework.data.r2dbc.core.StatementMapper; import org.springframework.data.r2dbc.core.StatementMapper;
import org.springframework.data.r2dbc.mapping.event.AfterConvertCallback; import org.springframework.data.r2dbc.mapping.event.AfterConvertCallback;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
@ -43,8 +44,7 @@ import java.util.stream.Collectors;
public class ReferenceR2dbcCallback implements AfterConvertCallback<Domain> { public class ReferenceR2dbcCallback implements AfterConvertCallback<Domain> {
private final R2dbcMetadataManager r2dbcMetadataManager; private final R2dbcMetadataManager r2dbcMetadataManager;
private final DatabaseClient databaseClient; private Lazy<R2dbcEntityOperations> operations;
private final StatementMapper statementMapper;
private Lazy<Map<Class<?>, DefaultReactiveRepository<?>>> repositories; private Lazy<Map<Class<?>, DefaultReactiveRepository<?>>> repositories;
@Override @Override
@ -77,13 +77,13 @@ public class ReferenceR2dbcCallback implements AfterConvertCallback<Domain> {
// 获取属性设置器 // 获取属性设置器
PersistentPropertyAccessor<Domain> accessor = persistentEntity.getPropertyAccessor(entity); PersistentPropertyAccessor<Domain> accessor = persistentEntity.getPropertyAccessor(entity);
// 尝试填充一对一关联 // 尝试填充各种关联方式
List<Mono<Domain>> signals = new ArrayList<>(); List<Mono<Domain>> signals = new ArrayList<>();
signals.addAll(fetchAssociation(metadata.getAssociations(), accessor)); signals.addAll(fetchAssociation(metadata.getAssociations(), accessor));
signals.addAll(fetchCollections(metadata.getCollections(), accessor)); signals.addAll(fetchCollections(metadata.getCollections(), accessor));
signals.addAll(fetchAssociation()) signals.addAll(fetchRelations(metadata.getRelations(), accessor));
// 尝试填充一对多关联 // 尝试填充
if (CollectionUtils.isNotEmpty(signals)) { if (CollectionUtils.isNotEmpty(signals)) {
return Mono.zip(signals, objs -> entity); return Mono.zip(signals, objs -> entity);
} }
@ -100,6 +100,11 @@ public class ReferenceR2dbcCallback implements AfterConvertCallback<Domain> {
.collect(Collectors.toMap(repo -> repo.getEntityInformation().getJavaType(), Function.identity()))); .collect(Collectors.toMap(repo -> repo.getEntityInformation().getJavaType(), Function.identity())));
} }
@Autowired
public void setR2dbcEntityOperations(ObjectProvider<R2dbcEntityOperations> operations) {
this.operations = Lazy.of(operations::getIfAvailable);
}
/** /**
* 拉取一对一关联 * 拉取一对一关联
* *
@ -197,13 +202,8 @@ public class ReferenceR2dbcCallback implements AfterConvertCallback<Domain> {
DefaultReactiveRepository<Domain> repository = getRepository(relation.getEntity().getType()); DefaultReactiveRepository<Domain> repository = getRepository(relation.getEntity().getType());
// 准备查询参数 // 准备查询参数
String id = accessor.getBean().getId(); String id = accessor.getBean().getId();
StatementMapper.SelectSpec select = statementMapper.createSelect("rel_table") // 查询关联id集合
.withProjection(relation.getForeignField()).withCriteria(Criteria.where(relation.getField()).is(id)); Flux<String> ids = fetchRelationIds(relation, id);
PreparedOperation<?> operation = statementMapper.getMappedObject(select);
// 执行查询
Flux<String> ids = databaseClient.sql(operation)
.map(row -> row.get(0, String.class))
.all();
// 准备设置 // 准备设置
FieldSetter setter = relation.getSetter(); FieldSetter setter = relation.getSetter();
// 查询最终结果 // 查询最终结果
@ -217,6 +217,27 @@ public class ReferenceR2dbcCallback implements AfterConvertCallback<Domain> {
return signals; return signals;
} }
/**
* 查询当前实体关联的ids
*
* @param relation 关联信息
* @return 结果
*/
private Flux<String> fetchRelationIds(R2dbcRelation relation, String id) {
// 准备查询器
R2dbcEntityOperations entityOperations = operations.get();
StatementMapper statementMapper = entityOperations.getDataAccessStrategy().getStatementMapper();
DatabaseClient databaseClient = entityOperations.getDatabaseClient();
// 构建查询
StatementMapper.SelectSpec select = statementMapper.createSelect(relation.getTableName())
.withProjection(relation.getForeignField()).withCriteria(Criteria.where(relation.getField()).is(id));
PreparedOperation<?> operation = statementMapper.getMappedObject(select);
// 执行查询
return databaseClient.sql(operation)
.map(row -> row.get(0, String.class))
.all();
}
/** /**
* 通过持久化属性获取真实的列名 * 通过持久化属性获取真实的列名
* *

View File

@ -1,7 +1,7 @@
package com.flyfish.framework.r2dbc.metadata; package com.flyfish.framework.r2dbc.metadata;
import com.flyfish.framework.annotations.Property; import com.flyfish.framework.annotations.Property;
import com.flyfish.framework.r2dbc.mapping.Association; import com.flyfish.framework.relational.mapping.Association;
import com.flyfish.framework.r2dbc.metadata.reference.FieldSetter; import com.flyfish.framework.r2dbc.metadata.reference.FieldSetter;
import com.flyfish.framework.r2dbc.metadata.reference.R2dbcAssociation; import com.flyfish.framework.r2dbc.metadata.reference.R2dbcAssociation;
import com.flyfish.framework.r2dbc.metadata.reference.R2dbcCollection; import com.flyfish.framework.r2dbc.metadata.reference.R2dbcCollection;

View File

@ -1,6 +1,6 @@
package com.flyfish.framework.r2dbc.metadata.impl; package com.flyfish.framework.r2dbc.metadata.impl;
import com.flyfish.framework.r2dbc.mapping.Association; import com.flyfish.framework.relational.mapping.Association;
import com.flyfish.framework.domain.base.Domain; import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.r2dbc.metadata.R2dbcMetadataManager; import com.flyfish.framework.r2dbc.metadata.R2dbcMetadataManager;
import com.flyfish.framework.r2dbc.metadata.R2dbcTableMetadata; import com.flyfish.framework.r2dbc.metadata.R2dbcTableMetadata;

View File

@ -1,7 +1,7 @@
package com.flyfish.framework.r2dbc.metadata.reference; package com.flyfish.framework.r2dbc.metadata.reference;
import com.flyfish.framework.annotations.Property; import com.flyfish.framework.annotations.Property;
import com.flyfish.framework.r2dbc.mapping.Association; import com.flyfish.framework.relational.mapping.Association;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentEntity;

View File

@ -1,6 +1,6 @@
package com.flyfish.framework.r2dbc.domain; package com.flyfish.framework.r2dbc.domain;
import com.flyfish.framework.r2dbc.mapping.Association; import com.flyfish.framework.relational.mapping.Association;
import com.flyfish.framework.domain.base.AuditDomain; import com.flyfish.framework.domain.base.AuditDomain;
import com.flyfish.framework.r2dbc.domain.reference.TestAsso; import com.flyfish.framework.r2dbc.domain.reference.TestAsso;
import com.flyfish.framework.r2dbc.domain.reference.TestChild; import com.flyfish.framework.r2dbc.domain.reference.TestChild;
@ -32,6 +32,9 @@ public class TestDO extends AuditDomain {
@Association @Association
private TestOther other; private TestOther other;
@Association(relationTable = "test_rel", field = "test_id", foreignField = "other_id")
private List<TestOther> others;
@Association @Association
private List<TestChild> children; private List<TestChild> children;
} }

View File

@ -77,8 +77,19 @@ CREATE TABLE IF NOT EXISTS `test_other`
`modifier_id` VARCHAR(36) NULL COMMENT '修改人id', `modifier_id` VARCHAR(36) NULL COMMENT '修改人id',
`delete` BIT(1) NOT NULL DEFAULT b'0', `delete` BIT(1) NOT NULL DEFAULT b'0',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) COMMENT '测试关联表'; ) COMMENT '测试关联表';
REPLACE INTO `test_other` REPLACE INTO `test_other`
VALUES ('1', '1', 'baba ', 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, null, null, null, false), VALUES ('1', '1', 'baba ', 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, null, null, null, false),
('2', '1', 'mama ', 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, null, null, null, false),
('2', '1', 'mama ', 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, null, null, null, false); ('2', '1', 'mama ', 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, null, null, null, false);
CREATE TABLE IF NOT EXISTS `test_rel`
(
`test_id` VARCHAR(36) NOT NULL COMMENT 'test主键',
`other_id` VARCHAR(36) NOT NULL COMMENT 'other主键',
PRIMARY KEY (`test_id`, `other_id`)
) COMMENT '关系表';
REPLACE INTO `test_rel`
VALUES ('1', '1'), ('1', '2'), ('1', '3')

View File

@ -0,0 +1 @@
# 关系型数据库通用支持代码

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.flyfish.framework</groupId>
<artifactId>flyfish-data</artifactId>
<version>${revision}</version>
</parent>
<artifactId>flyfish-data-relational</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-relational</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,4 +1,4 @@
package com.flyfish.framework.r2dbc.mapping; package com.flyfish.framework.relational.mapping;
import org.springframework.data.annotation.Transient; import org.springframework.data.annotation.Transient;

View File

@ -0,0 +1 @@
package com.flyfish.framework.relational;

View File

@ -16,6 +16,7 @@
<module>flyfish-data-mongodb</module> <module>flyfish-data-mongodb</module>
<module>flyfish-data-common</module> <module>flyfish-data-common</module>
<module>flyfish-data-domain</module> <module>flyfish-data-domain</module>
<module>flyfish-data-relational</module>
</modules> </modules>
</project> </project>