feat: 完善r2dbc场景

This commit is contained in:
wangyu 2024-06-25 16:17:05 +08:00
parent 4dfe06ffb2
commit 2bf84f0c27
20 changed files with 135 additions and 24 deletions

View File

@ -40,7 +40,7 @@ public class ModuleDelegateService {
private Map<String, BaseReactiveService<ApprovalDomain>> approvalServices; private Map<String, BaseReactiveService<ApprovalDomain>> approvalServices;
private String getModuleName(BaseReactiveService<ApprovalDomain> service) { private String getModuleName(BaseReactiveService<ApprovalDomain> service) {
return ReflectionUtils.getGenericType(service.getClass()).map(Class::getSimpleName) return ReflectionUtils.getGenericType(service.getClass()).map(this::moduleName)
.orElseThrow(() -> new InvalidBusinessException("系统模块名称抽取失败!")); .orElseThrow(() -> new InvalidBusinessException("系统模块名称抽取失败!"));
} }

View File

@ -7,6 +7,7 @@ import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.relational.core.mapping.Column;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -24,6 +25,7 @@ public abstract class AuditDomain extends Domain {
*/ */
@CreatedDate @CreatedDate
@Property(value = "创建日期", readonly = true) @Property(value = "创建日期", readonly = true)
@Column("create_time")
protected LocalDateTime createTime; protected LocalDateTime createTime;
/** /**
@ -31,6 +33,7 @@ public abstract class AuditDomain extends Domain {
*/ */
@LastModifiedDate @LastModifiedDate
@Property(value = "更新日期", readonly = true) @Property(value = "更新日期", readonly = true)
@Column("modify_time")
protected LocalDateTime modifyTime; protected LocalDateTime modifyTime;
/** /**
@ -44,6 +47,7 @@ public abstract class AuditDomain extends Domain {
* 创建人id * 创建人id
*/ */
@Property(readonly = true) @Property(readonly = true)
@Column("creator_id")
protected String creatorId; protected String creatorId;
/** /**
@ -57,5 +61,6 @@ public abstract class AuditDomain extends Domain {
* 修改人id * 修改人id
*/ */
@Property(readonly = true) @Property(readonly = true)
@Column("modifier_id")
protected String modifierId; protected String modifierId;
} }

View File

@ -3,6 +3,7 @@ package com.flyfish.framework.domain.po;
import com.flyfish.framework.domain.tree.TreeDomain; import com.flyfish.framework.domain.tree.TreeDomain;
import lombok.*; import lombok.*;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.relational.core.mapping.Table;
/** /**
* 部门 * 部门
@ -10,6 +11,7 @@ import org.springframework.data.mongodb.core.mapping.Document;
* @author wangyu * @author wangyu
*/ */
@Document @Document
@Table
@Getter @Getter
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor

View File

@ -4,6 +4,7 @@ import com.flyfish.framework.domain.base.AuditDomain;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.relational.core.mapping.Table;
import java.util.Map; import java.util.Map;
@ -15,6 +16,7 @@ import java.util.Map;
@Getter @Getter
@Setter @Setter
@Document(collection = "excel-mappings") @Document(collection = "excel-mappings")
@Table("excel_mappings")
public class ExcelMapping extends AuditDomain { public class ExcelMapping extends AuditDomain {
// 映射关系 // 映射关系

View File

@ -7,6 +7,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.relational.core.mapping.Table;
/** /**
* 权限 * 权限
@ -14,6 +15,7 @@ import org.springframework.data.mongodb.core.mapping.Document;
* @author wangyu * @author wangyu
*/ */
@Document @Document
@Table
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class Permission extends TreeDomain<Permission> { public class Permission extends TreeDomain<Permission> {

View File

@ -6,6 +6,7 @@ import com.flyfish.framework.enums.RoleType;
import lombok.*; import lombok.*;
import org.springframework.data.annotation.Reference; import org.springframework.data.annotation.Reference;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.relational.core.mapping.Table;
import java.util.List; import java.util.List;
@ -15,6 +16,7 @@ import java.util.List;
* @author wangyu * @author wangyu
*/ */
@Document @Document
@Table
@Data @Data
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor

View File

@ -12,12 +12,13 @@ import org.springframework.data.annotation.Reference;
import org.springframework.data.annotation.Transient; import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.index.Indexed; import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.relational.core.mapping.Table;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Date;
import java.util.List; import java.util.List;
@Document @Document
@Table
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor

View File

@ -5,14 +5,20 @@ import com.flyfish.framework.r2dbc.operations.R2dbcReactiveEntityOperations;
import com.flyfish.framework.r2dbc.repository.factory.DefaultReactiveRepositoryFactoryBean; import com.flyfish.framework.r2dbc.repository.factory.DefaultReactiveRepositoryFactoryBean;
import com.flyfish.framework.r2dbc.repository.impl.DefaultReactiveRepositoryImpl; import com.flyfish.framework.r2dbc.repository.impl.DefaultReactiveRepositoryImpl;
import com.flyfish.framework.repository.ReactiveEntityOperations; import com.flyfish.framework.repository.ReactiveEntityOperations;
import org.springframework.boot.autoconfigure.AutoConfiguration; import io.r2dbc.spi.ConnectionFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.mapping.callback.EntityCallback; import org.springframework.data.mapping.callback.EntityCallback;
import org.springframework.data.r2dbc.config.EnableR2dbcAuditing; import org.springframework.data.r2dbc.config.EnableR2dbcAuditing;
import org.springframework.data.r2dbc.core.R2dbcEntityOperations; import org.springframework.data.r2dbc.core.R2dbcEntityOperations;
import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories; import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
import org.springframework.r2dbc.connection.init.CompositeDatabasePopulator;
import org.springframework.r2dbc.connection.init.ConnectionFactoryInitializer;
import org.springframework.r2dbc.connection.init.DatabasePopulator;
import org.springframework.r2dbc.connection.init.ResourceDatabasePopulator;
import java.util.Optional;
/** /**
* r2dbc数据配置 * r2dbc数据配置
@ -21,10 +27,10 @@ import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
*/ */
@EnableR2dbcRepositories( @EnableR2dbcRepositories(
repositoryFactoryBeanClass = DefaultReactiveRepositoryFactoryBean.class, repositoryFactoryBeanClass = DefaultReactiveRepositoryFactoryBean.class,
repositoryBaseClass = DefaultReactiveRepositoryImpl.class repositoryBaseClass = DefaultReactiveRepositoryImpl.class,
basePackages = "com.flyfish.framework"
) )
@EnableR2dbcAuditing @EnableR2dbcAuditing
@AutoConfiguration(after = R2dbcDataAutoConfiguration.class)
public class R2dbcDataConfig { public class R2dbcDataConfig {
@Bean @Bean
@ -37,4 +43,41 @@ public class R2dbcDataConfig {
public ReactiveEntityOperations r2dbcReactiveEntityOperations(R2dbcEntityOperations r2dbcEntityOperations) { public ReactiveEntityOperations r2dbcReactiveEntityOperations(R2dbcEntityOperations r2dbcEntityOperations) {
return new R2dbcReactiveEntityOperations(r2dbcEntityOperations); return new R2dbcReactiveEntityOperations(r2dbcEntityOperations);
} }
/**
* 数据库初始化
*
* @param connectionFactory 链接仓库
* @return 结果
*/
@Bean
public ConnectionFactoryInitializer connectionFactoryInitializer(ConnectionFactory connectionFactory) {
ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
initializer.setConnectionFactory(connectionFactory);
CompositeDatabasePopulator populator = new CompositeDatabasePopulator();
// 添加主要脚本
preparePopulator("schema.sql").ifPresent(populator::addPopulators);
// 动态执行方言脚本
preparePopulator("dialect/" + connectionFactory.getMetadata().getName().toLowerCase() + ".sql")
.ifPresent(populator::addPopulators);
initializer.setDatabasePopulator(populator);
// 添加清理脚本
preparePopulator("schema-clean.sql").ifPresent(initializer::setDatabaseCleaner);
// 返回初始化器
return initializer;
}
/**
* 动态判定存在性提供健壮的架构
*
* @param path 文件路径
* @return 结果
*/
private Optional<DatabasePopulator> preparePopulator(String path) {
ClassPathResource schema = new ClassPathResource(path);
if (schema.exists()) {
return Optional.of(new ResourceDatabasePopulator(schema));
}
return Optional.empty();
}
} }

View File

@ -4,6 +4,7 @@ import com.flyfish.framework.domain.base.Domain;
import org.reactivestreams.Publisher; import org.reactivestreams.Publisher;
import org.springframework.data.r2dbc.mapping.event.AfterConvertCallback; import org.springframework.data.r2dbc.mapping.event.AfterConvertCallback;
import org.springframework.data.relational.core.sql.SqlIdentifier; import org.springframework.data.relational.core.sql.SqlIdentifier;
import reactor.core.publisher.Mono;
/** /**
* 给r2dbc中的实体进行关联填充 * 给r2dbc中的实体进行关联填充
@ -22,6 +23,6 @@ public class R2dbcReferenceEntityCallback implements AfterConvertCallback<Domain
*/ */
@Override @Override
public Publisher<Domain> onAfterConvert(Domain entity, SqlIdentifier table) { public Publisher<Domain> onAfterConvert(Domain entity, SqlIdentifier table) {
return null; return Mono.just(entity);
} }
} }

View File

@ -229,9 +229,6 @@ public class DefaultReactiveRepositoryImpl<T extends Domain> extends SimpleR2dbc
} }
private Optional<Query> getQuery(Qo<T> qo) { private Optional<Query> getQuery(Qo<T> qo) {
if (null != qo.getExample()) {
}
return qo.getQuery(entity); return qo.getQuery(entity);
} }
} }

View File

@ -8,7 +8,10 @@ import com.flyfish.framework.r2dbc.repository.TestQO;
import com.flyfish.framework.r2dbc.repository.TestRepository; import com.flyfish.framework.r2dbc.repository.TestRepository;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcProperties;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringExtension;
@ -17,7 +20,7 @@ import java.util.Arrays;
@ExtendWith(SpringExtension.class) @ExtendWith(SpringExtension.class)
@SpringBootTest(classes = R2DbcRepositoryTest.class) @SpringBootTest(classes = R2DbcRepositoryTest.class)
@EnableR2dbcRepo(basePackages = "com.flyfish.framework.r2dbc.repository") @SpringBootApplication(scanBasePackages = "com.flyfish.framework")
@Import(R2dbcDataConfig.class) @Import(R2dbcDataConfig.class)
public class R2DbcRepositoryTest { public class R2DbcRepositoryTest {
@ -27,7 +30,13 @@ public class R2DbcRepositoryTest {
@Test @Test
public void test() { public void test() {
TestQO qo = new TestQO(); TestQO qo = new TestQO();
qo.setIds(Arrays.asList("1", "2")); qo.setName("");
testRepository.findAll(qo).subscribe(System.out::println); TestDO test = new TestDO();
test.setId("1");
test.setCode("ttt");
test.setName("测试名称");
System.out.println(testRepository.insert(test).block());
System.out.println(testRepository.findAll(qo).collectList().block());
} }
} }

View File

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

View File

@ -0,0 +1,14 @@
CREATE TABLE IF NOT EXISTS `test`
(
`id` VARCHAR(36) NOT NULL COMMENT '主键',
`code` VARCHAR(32) NOT NULL COMMENT '编码',
`name` VARCHAR(100) NOT NULL COMMENT '名称',
`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 '测试表';

View File

@ -34,7 +34,7 @@
<dependency> <dependency>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-relational</artifactId> <artifactId>spring-data-r2dbc</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ClassUtils; import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -27,6 +28,7 @@ import java.util.stream.Collectors;
*/ */
@RestController @RestController
@RequestMapping("beans") @RequestMapping("beans")
@ConditionalOnBean(DynamicRestBeanResolver.class)
@Slf4j @Slf4j
public class BeanController { public class BeanController {

View File

@ -23,11 +23,11 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils; import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.commons.lang3.reflect.TypeUtils; import org.apache.commons.lang3.reflect.TypeUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.MergedAnnotation; import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.data.annotation.Reference; import org.springframework.data.annotation.Reference;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.relational.core.mapping.Table;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -45,6 +45,10 @@ import java.util.stream.Collectors;
@Data @Data
public class BeanProperty { public class BeanProperty {
private static final String MONGO_DOCUMENT = "org.springframework.data.mongodb.core.mapping.Document";
private static final String R2DBC_TABLE = "org.springframework.data.relational.core.mapping.Table";
// 属性名称 // 属性名称
private String name; private String name;
@ -347,12 +351,17 @@ public class BeanProperty {
* @return 结果 * @return 结果
*/ */
private static Optional<String> processDbRef(Class<?> clazz) { private static Optional<String> processDbRef(Class<?> clazz) {
return Optional.ofNullable(AnnotatedElementUtils.findMergedAnnotation(clazz, Document.class)) MergedAnnotations annotations = MergedAnnotations.from(clazz);
.map(document -> { String name = null;
String collection = document.value(); if (annotations.isPresent(MONGO_DOCUMENT)) {
return StringUtils.isNotBlank(collection) ? collection : name = annotations.get(Document.class).getString("value");
BeanUris.getUri(clazz).orElse(StringFormats.camel2Line(clazz.getSimpleName())); }
}); if (annotations.isPresent(R2DBC_TABLE)) {
name = annotations.get(Table.class).getString("value");
}
name = StringUtils.isNotBlank(name) ? name :
BeanUris.getUri(clazz).orElse(StringFormats.camel2Line(clazz.getSimpleName()));
return Optional.of(name).filter(StringUtils::isNotBlank);
} }
/** /**

View File

@ -10,6 +10,7 @@ import com.flyfish.framework.repository.DefaultReactiveRepository;
import com.flyfish.framework.service.impl.BaseReactiveServiceImpl; import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
import org.springframework.core.annotation.AliasFor; import org.springframework.core.annotation.AliasFor;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.relational.core.mapping.Table;
import org.springframework.data.repository.Repository; import org.springframework.data.repository.Repository;
import java.lang.annotation.*; import java.lang.annotation.*;
@ -23,6 +24,7 @@ import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
@Document @Document
@Table
public @interface RestBean { public @interface RestBean {
/** /**
@ -33,6 +35,13 @@ public @interface RestBean {
@AliasFor(value = "collection", annotation = Document.class) @AliasFor(value = "collection", annotation = Document.class)
String value() default ""; String value() default "";
/**
* 表名
* @return
*/
@AliasFor(value = "value", annotation = Table.class)
String table() default "";
/** /**
* 名称可用于占位 * 名称可用于占位
* *

View File

@ -11,6 +11,8 @@ import org.springframework.data.mongodb.repository.config.EnableMongoRepositorie
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories; import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
import org.springframework.data.mongodb.repository.config.MongoRepositoryConfigurationExtension; import org.springframework.data.mongodb.repository.config.MongoRepositoryConfigurationExtension;
import org.springframework.data.mongodb.repository.config.ReactiveMongoRepositoryConfigurationExtension; import org.springframework.data.mongodb.repository.config.ReactiveMongoRepositoryConfigurationExtension;
import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
import org.springframework.data.r2dbc.repository.config.R2dbcRepositoryConfigurationExtension;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -24,16 +26,26 @@ class RepositoryRegistrarComposite implements RepositoryRegistrar {
private final List<RepositoryRegistrar> registrars; private final List<RepositoryRegistrar> registrars;
private final String ENABLE_MONGO_REPO_ANNO = "org.springframework.data.mongodb.repository.config.EnableMongoRepositories";
private final String ENABLE_REACTIVE_MONGO_REPO_ANNO = "org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories";
private final String ENABLE_R2DBC_REPO_ANNO = "org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories";
RepositoryRegistrarComposite(AnnotationMetadata metadata) { RepositoryRegistrarComposite(AnnotationMetadata metadata) {
List<RepositoryRegistrar> list = new ArrayList<>(); List<RepositoryRegistrar> list = new ArrayList<>();
if (metadata.hasMetaAnnotation(EnableMongoRepositories.class.getName())) { if (metadata.hasMetaAnnotation(ENABLE_MONGO_REPO_ANNO)) {
list.add(new SimpleRepositoryRegistrar(EnableMongoRepositories.class, new MongoRepositoryConfigurationExtension(), list.add(new SimpleRepositoryRegistrar(EnableMongoRepositories.class, new MongoRepositoryConfigurationExtension(),
DefaultRepository.class)); DefaultRepository.class));
} }
if (metadata.hasMetaAnnotation(EnableReactiveMongoRepositories.class.getName())) { if (metadata.hasMetaAnnotation(ENABLE_REACTIVE_MONGO_REPO_ANNO)) {
list.add(new SimpleRepositoryRegistrar(EnableReactiveMongoRepositories.class, new ReactiveMongoRepositoryConfigurationExtension(), list.add(new SimpleRepositoryRegistrar(EnableReactiveMongoRepositories.class, new ReactiveMongoRepositoryConfigurationExtension(),
DefaultReactiveRepository.class)); DefaultReactiveRepository.class));
} }
if (metadata.hasMetaAnnotation(ENABLE_R2DBC_REPO_ANNO)) {
list.add(new SimpleRepositoryRegistrar(EnableR2dbcRepositories.class, new R2dbcRepositoryConfigurationExtension(),
DefaultReactiveRepository.class));
}
this.registrars = list; this.registrars = list;
} }

View File

@ -27,7 +27,7 @@
<spring-cloud.version>Finchley.SR1</spring-cloud.version> <spring-cloud.version>Finchley.SR1</spring-cloud.version>
<jjwt.version>0.12.6</jjwt.version> <jjwt.version>0.12.6</jjwt.version>
<reflection.version>0.10.2</reflection.version> <reflection.version>0.10.2</reflection.version>
<r2dbc-mysql.version>1.1.3</r2dbc-mysql.version> <r2dbc-mysql.version>0.9.7</r2dbc-mysql.version>
<flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version> <flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version>
</properties> </properties>