feat: 最终使用回调+反射解决

This commit is contained in:
wangyu 2024-06-27 00:10:40 +08:00
parent 9ab6918432
commit 873635d6a9
14 changed files with 126 additions and 126 deletions

View File

@ -1,10 +0,0 @@
package com.flyfish.framework.builder;
/**
* 查询构建器提供者
* @author wangyu-
*/
public interface CriteriaBuilderProvider {
}

View File

@ -1,7 +1,7 @@
package com.flyfish.framework.r2dbc.config;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.r2dbc.repository.decorator.DomainEntityOperations;
import com.flyfish.framework.r2dbc.config.callback.ReferenceR2dbcCallback;
import com.flyfish.framework.r2dbc.operations.R2dbcReactiveEntityOperations;
import com.flyfish.framework.r2dbc.repository.factory.DefaultReactiveRepositoryFactoryBean;
import com.flyfish.framework.r2dbc.repository.impl.DefaultReactiveRepositoryImpl;
@ -10,12 +10,10 @@ import io.r2dbc.spi.ConnectionFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
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.core.R2dbcEntityTemplate;
import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
import org.springframework.r2dbc.connection.init.CompositeDatabasePopulator;
import org.springframework.r2dbc.connection.init.ConnectionFactoryInitializer;
@ -38,22 +36,16 @@ import java.util.Optional;
@AutoConfiguration(before = R2dbcAutoConfiguration.class)
public class R2dbcDataConfig {
@Bean
public EntityCallback<Domain> r2dbcReferenceEntityCallback() {
return new R2dbcReferenceEntityCallback();
}
@Bean
@Primary
public R2dbcEntityTemplate r2dbcEntityTemplate(ConnectionFactory connectionFactory) {
return new DomainEntityOperations(connectionFactory);
}
@Bean
public ReactiveEntityOperations r2dbcReactiveEntityOperations(R2dbcEntityOperations r2dbcEntityOperations) {
return new R2dbcReactiveEntityOperations(r2dbcEntityOperations);
}
@Bean
public EntityCallback<Domain> referenceR2dbcCallback() {
return new ReferenceR2dbcCallback();
}
/**
* 数据库初始化
*

View File

@ -1,28 +0,0 @@
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;
import reactor.core.publisher.Mono;
/**
* 给r2dbc中的实体进行关联填充
*
* @author wangyu
*/
public class R2dbcReferenceEntityCallback implements AfterConvertCallback<Domain> {
/**
* 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<Domain> onAfterConvert(Domain entity, SqlIdentifier table) {
return Mono.just(entity);
}
}

View File

@ -0,0 +1,32 @@
package com.flyfish.framework.r2dbc.config.callback;
import com.flyfish.framework.domain.base.Domain;
import lombok.Setter;
import org.reactivestreams.Publisher;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.r2dbc.core.R2dbcEntityOperations;
import org.springframework.data.r2dbc.mapping.event.AfterConvertCallback;
import org.springframework.data.relational.core.sql.SqlIdentifier;
import org.springframework.lang.NonNull;
import reactor.core.publisher.Mono;
public class ReferenceR2dbcCallback implements AfterConvertCallback<Domain>, ApplicationContextAware {
@Setter
private ApplicationContext applicationContext;
@Setter(onMethod_ = @Autowired)
private ObjectProvider<R2dbcEntityOperations> entityOperations;
@Override
@NonNull
public Publisher<Domain> onAfterConvert(@NonNull Domain entity, @NonNull SqlIdentifier table) {
// 遍历fields找到要注入的数据
entityOperations.getIfAvailable();
return Mono.just(entity);
}
}

View File

@ -1,33 +0,0 @@
package com.flyfish.framework.r2dbc.repository.fill;
import com.flyfish.framework.domain.base.Domain;
import org.springframework.data.r2dbc.convert.R2dbcConverter;
import org.springframework.data.relational.repository.query.RelationalEntityInformation;
import reactor.core.publisher.Mono;
/**
* r2dbc引用填充
*
* @author wangyu
*/
@FunctionalInterface
public interface R2dbcReferenceFiller<T extends Domain> {
/**
* 创建新的填充器
*
* @param <T> 泛型
* @return 结果
*/
static <T extends Domain> R2dbcReferenceFiller<T> newFiller(RelationalEntityInformation<T, String> entityInformation, R2dbcConverter converter) {
return new SimpleR2dbcReferenceFiller<>(entityInformation, converter);
}
/**
* 填充附加值
*
* @param bean 实体信息
* @return 结果
*/
Mono<T> fill(T bean);
}

View File

@ -1,30 +0,0 @@
package com.flyfish.framework.r2dbc.repository.fill;
import com.flyfish.framework.domain.base.Domain;
import org.springframework.data.r2dbc.convert.R2dbcConverter;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.repository.query.RelationalEntityInformation;
import org.springframework.data.util.Lazy;
import reactor.core.publisher.Mono;
public class SimpleR2dbcReferenceFiller<T extends Domain> implements R2dbcReferenceFiller<T> {
private final Lazy<RelationalPersistentEntity<T>> persistentEntity;
public SimpleR2dbcReferenceFiller(RelationalEntityInformation<T, String> entity, R2dbcConverter converter) {
this.persistentEntity = Lazy.of(() -> (RelationalPersistentEntity<T>) converter
.getMappingContext()
.getRequiredPersistentEntity(entity.getJavaType()));
}
/**
* 填充附加值
*
* @param bean 实体信息
* @return 结果
*/
@Override
public Mono<T> fill(T bean) {
return null;
}
}

View File

@ -2,7 +2,6 @@ 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.repository.fill.R2dbcReferenceFiller;
import com.flyfish.framework.repository.DefaultReactiveRepository;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
@ -14,10 +13,13 @@ 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.mapping.RelationalPersistentEntity;
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.repository.core.EntityInformation;
import org.springframework.data.util.CastUtils;
import org.springframework.data.util.Lazy;
import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
import reactor.core.publisher.Flux;
@ -39,7 +41,7 @@ public class DefaultReactiveRepositoryImpl<T extends Domain> extends SimpleR2dbc
private final R2dbcEntityOperations entityOperations;
private final R2dbcReferenceFiller<T> filler;
private final Lazy<RelationalPersistentEntity<T>> persistentEntity;
/**
* 构造新的默认仓库
@ -52,9 +54,16 @@ public class DefaultReactiveRepositoryImpl<T extends Domain> extends SimpleR2dbc
super(entity, entityOperations, converter);
this.entity = entity;
this.entityOperations = entityOperations;
this.filler = R2dbcReferenceFiller.newFiller(entity, converter);
this.persistentEntity = Lazy.of(() -> (RelationalPersistentEntity<T>) converter
.getMappingContext()
.getRequiredPersistentEntity(entity.getJavaType()));
}
@Override
@NonNull
public Mono<T> findById(@NonNull String id) {
return super.findById(id).flatMap(this::afterSelect);
}
/**
* 通过名称查找一个
@ -240,14 +249,11 @@ public class DefaultReactiveRepositoryImpl<T extends Domain> extends SimpleR2dbc
}
private Mono<T> afterSelect(T entity) {
return filler.fill(entity);
return Mono.just(entity);
}
private Mono<T> afterSelect(Qo<T> qo, T entity) {
entity.setCurrentUser(qo.getUser());
if (qo.isFetchRef()) {
return filler.fill(entity);
}
return Mono.just(entity);
return afterSelect(entity);
}
}

View File

@ -4,6 +4,7 @@ import com.flyfish.framework.r2dbc.config.R2dbcDataConfig;
import com.flyfish.framework.r2dbc.repository.TestDO;
import com.flyfish.framework.r2dbc.repository.TestQO;
import com.flyfish.framework.r2dbc.repository.TestRepository;
import com.flyfish.framework.r2dbc.repository.reference.TestAsso;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -30,6 +31,7 @@ public class R2DbcRepositoryTest {
test.setId("1");
test.setCode("ttt");
test.setName("测试名称");
test.setOtherId("1");
System.out.println(testRepository.insert(test).block());
System.out.println(testRepository.findAll(qo).collectList().block());

View File

@ -1,11 +1,25 @@
package com.flyfish.framework.r2dbc.repository;
import com.flyfish.framework.domain.base.AuditDomain;
import com.flyfish.framework.r2dbc.repository.reference.TestAsso;
import com.flyfish.framework.r2dbc.repository.reference.TestChild;
import lombok.Data;
import org.springframework.data.annotation.Reference;
import org.springframework.data.annotation.Transient;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
import java.util.List;
@Table("test")
@Data
public class TestDO extends AuditDomain {
@Column("other_id")
@Reference
private String otherId;
@Reference(TestChild.class)
@Transient
private List<TestChild> children;
}

View File

@ -0,0 +1,8 @@
package com.flyfish.framework.r2dbc.repository.reference;
import com.flyfish.framework.domain.base.AuditDomain;
import org.springframework.data.relational.core.mapping.Table;
@Table("test_asso")
public class TestAsso extends AuditDomain {
}

View File

@ -0,0 +1,14 @@
package com.flyfish.framework.r2dbc.repository.reference;
import com.flyfish.framework.domain.base.AuditDomain;
import lombok.Data;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
@Table("test_child")
@Data
public class TestChild extends AuditDomain {
@Column("parent_id")
private String parentId;
}

View File

@ -1,5 +1,5 @@
spring:
r2dbc:
url: r2dbc:mysql://192.168.33.205:3306/test?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true
url: r2dbc:mysql://127.0.0.1:3306/test?allowMultiQueries=true&useUnicode=true&ssl=false&characterEncoding=UTF-8&serverZoneId=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true
username: root
password: baiewf9XMq5K9Z2LiCXZ
password: Unicom#2018

View File

@ -1 +1,2 @@
DROP TABLE IF EXISTS `test`;
DROP TABLE IF EXISTS `test_child`;

View File

@ -1,4 +1,36 @@
CREATE TABLE IF NOT EXISTS `test`
(
`id` VARCHAR(36) NOT NULL COMMENT '主键',
`code` VARCHAR(32) NOT NULL COMMENT '编码',
`name` VARCHAR(100) NOT NULL COMMENT '名称',
`other_id` VARCHAR(36) NULL COMMENT '其他id',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`modify_time` DATETIME NOT NULL COMMENT '修改时间',
`creator` VARCHAR(36) NULL COMMENT '创建人名称',
`creator_id` VARCHAR(36) NULL COMMENT '创建人id',
`modifier` VARCHAR(36) NULL COMMENT '修改人名称',
`modifier_id` VARCHAR(36) NULL COMMENT '修改人id',
`delete` BIT(1) NOT NULL DEFAULT b'0',
PRIMARY KEY (`id`)
) COMMENT '测试表';
CREATE TABLE IF NOT EXISTS `test_child`
(
`id` VARCHAR(36) NOT NULL COMMENT '主键',
`code` VARCHAR(32) NOT NULL COMMENT '编码',
`name` VARCHAR(100) NOT NULL COMMENT '名称',
`parent_id` VARCHAR(36) NOT NULL COMMENT '父id',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`modify_time` DATETIME NOT NULL COMMENT '修改时间',
`creator` VARCHAR(36) NULL COMMENT '创建人名称',
`creator_id` VARCHAR(36) NULL COMMENT '创建人id',
`modifier` VARCHAR(36) NULL COMMENT '修改人名称',
`modifier_id` VARCHAR(36) NULL COMMENT '修改人id',
`delete` BIT(1) NOT NULL DEFAULT b'0',
PRIMARY KEY (`id`)
) COMMENT '测试子表';
CREATE TABLE IF NOT EXISTS `test_asso`
(
`id` VARCHAR(36) NOT NULL COMMENT '主键',
`code` VARCHAR(32) NOT NULL COMMENT '编码',
@ -11,4 +43,4 @@ CREATE TABLE IF NOT EXISTS `test`
`modifier_id` VARCHAR(36) NULL COMMENT '修改人id',
`delete` BIT(1) NOT NULL DEFAULT b'0',
PRIMARY KEY (`id`)
) COMMENT '测试';
) COMMENT '测试关联';