我目前正在尝试在 Spring Boot 中为已经处于开发阶段的应用程序实现 R2DBC - 不幸的是,这意味着我们的 DDL 不灵活,因为其他微服务依赖于此,反之亦然。R2DBC 的一个重要限制是不支持嵌套类。此外,它不支持 JPA,因为这会破坏全面非阻塞的目的。因此,所有这些有用的注释也不在表中。
我正在处理的类看起来像这样:
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Stats {
@Id
StatsPK statsPK
@Column(stat_name)
String stat;
...
@Data
@AllArgsConstructor
@NoArgsConstructor
@Embeddable
public static class StatsPK implements Serializable {
@Column("store_id")
private Integer storeId;
@Column("empl_id")
private String emplId;
@Column("app_version")
private String appVersion;
}
}
Run Code Online (Sandbox Code Playgroud)
在研究了我的问题后,我找到了很多方法来计算复合键,包括上面示例中已经显示的内容(使用 @Embeddable 注释),使用自定义 PK 对象(类似,但会有使用为此目的设计的类的选项,例如 CompositeKeyHolder)、JPA @TableId(TableId.class) 注释,以及其他一些似乎不太有希望的注释。
所有这些选项似乎都在使用 JPA 或使用嵌套对象,这是我做不到的。我真的想不出绕过这些限制的方法。但由于我是初学者,我决定询问是否有人以前处理过这个问题。感谢任何反馈。
我尝试将 Spring Data R2DBC 与 postgres 一起使用。
我知道一些 url、用户名、密码的配置。
spring.r2dbc.url
spring.r2dbc.username
spring.r2dbc.password
Run Code Online (Sandbox Code Playgroud)
模式有什么东西吗?任何可用的设置列表?
我在搜索反应性关系数据库驱动程序时找到了R2DBC,但找不到任何Oracle DB驱动程序。是否有人提供是否提供支持的信息?
我试图品尝 R2dbc 并使用嵌入式 H2,例如:
public ConnectionFactory connectionFactory() {
//ConnectionFactory factory = ConnectionFactories.get("r2dbc:h2:mem:///test?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");
return new H2ConnectionFactory(
H2ConnectionConfiguration.builder()
//.inMemory("testdb")
.file("./testdb")
.username("user")
.password("password").build()
);
}
Run Code Online (Sandbox Code Playgroud)
我定义了一个 bean 来创建表和初始化数据。
@Bean
public ConnectionFactoryInitializer initializer(ConnectionFactory connectionFactory) {
ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
initializer.setConnectionFactory(connectionFactory);
CompositeDatabasePopulator populator = new CompositeDatabasePopulator();
populator.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("schema.sql")));
populator.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("data.sql")));
initializer.setDatabasePopulator(populator);
return initializer;
}
Run Code Online (Sandbox Code Playgroud)
而且我还定义了另一个组件来通过java代码设置数据。
@Component
@Slf4j
class DataInitializer {
private final DatabaseClient databaseClient;
public DataInitializer(DatabaseClient databaseClient) {
this.databaseClient = databaseClient;
}
@EventListener(value = ContextRefreshedEvent.class)
public void init() {
log.info("start data initialization …
Run Code Online (Sandbox Code Playgroud) spring-boot project-reactor spring-webflux spring-data-r2dbc r2dbc
我是反应式编程的新手。我必须开发一个简单的 Spring Boot 应用程序来返回 json 响应,其中包含公司详细信息及其所有子公司和员工
创建了一个 Spring Boot 应用程序(Spring Webflux + Spring data r2dbc )
使用下面的数据库表来表示公司和子公司以及员工关系(这是公司和子公司的层次关系,其中一个公司可以有N个子公司,每个子公司可以有另外N个子公司等等)
以下是代表上述表格的 java 模型类
公司.java
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Company implements Serializable {
private int id;
private String name;
private String address;
@With
@Transient
private List<Company> subCompanies;
@With
@Transient
private List<Employee> employees;
}
Run Code Online (Sandbox Code Playgroud)
员工.java
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Employee implements Serializable {
@Id
private int id; …
Run Code Online (Sandbox Code Playgroud) 我在 postgresql 数据库中有一些限制(唯一的、外键...)。
我使用 spring data r2dbc 存储库:ReactiveCrudRepository
我想将DataIntegrityViolationException
存储库的抛出转换为基于 的constraintName
inErrorDetails
字段的自定义异常PostgresqlDataIntegrityViolationException
。
但ExceptionFactory
包含该类的类PostgresqlDataIntegrityViolationException
是包私有的。所以我无法投射DataIntegrityViolationException
to的原因异常PostgresqlDataIntegrityViolationException
。
constraintName
当我捕获 时,访问 的最干净的方法是什么DataIntegrityViolationException
?
(比解析异常消息更好的事情^^)
编辑 :
我以这个解决方案结束:
val DataIntegrityViolationException.pgErrorDetails: ErrorDetails
get() = when(val cause = this.cause) {
null -> error("cause should not be null")
else -> cause.javaClass
.getDeclaredField("errorDetails")
.apply { isAccessible = true }
.let { it.get(cause) as ErrorDetails }
}
Run Code Online (Sandbox Code Playgroud) 我正在使用 Spring data r2dbc,它不支持多对多映射。
表格:-
user
user_role
user_role_mapping
Run Code Online (Sandbox Code Playgroud)
像往常一样,一个用户可以有多个映射。
sql查询,
select * from user u, user_role_mapping urm, user_role ur 其中 u.user_id = :userId 和 u.org_id = :orgId 和 u.user_id = urm.user_id 和 ur.role_id = urm.role_id
在这里,我有一个模型对象,其中包含所有 3 个类的所有属性。在这里,由于用户具有多个角色,因此我获取多个记录,然后使用用户详细信息和角色列表构建单个记录。
型号类,
class User {
private long userId;
private String userName;
private List<String> roles;
}
Run Code Online (Sandbox Code Playgroud)
Spring r2dbc 是否有任何开箱即用的支持,它返回一个包含用户详细信息和List<String>
角色的用户对象。
图书馆:
\n问题:\n我尝试使用 R2DBC (PostgreSQL) 批量插入,代码如下:
\n@Override\npublic Flux<Long> test(List<User> users) {\n return Mono.from(connectionFactory.create())\n .flatMapMany(c -> Mono.from(c.beginTransaction())\n .thenMany(Flux.fromIterable(users)\n .map(u -> {\n return Flux.from(c.createStatement("INSERT INTO public.users(name, age, salary) VALUES ($1, $2, $3)").returnGeneratedValues("id")\n .bind(0, u.getName())\n .bind(1, u.getAge())\n .bind(2, u.getSalary()).execute());\n })\n .flatMap(result -> result)\n .map(result -> result.map((row, meta) -> {\n return row.get("id", Long.class);\n }))\n .flatMap(Flux::from)\n .delayUntil(r -> c.commitTransaction())\n .doFinally((st) -> c.close())));\n}\n
Run Code Online (Sandbox Code Playgroud)\n该代码将执行语句将用户插入数据库,然后获取生成的用户 ID。如果用户列表小于或等于 255,以上代码将按预期工作。当用户列表大于 255(256~)时,会出现以下异常:
\n[5b38a8c6-2] There was an …
Run Code Online (Sandbox Code Playgroud) postgresql spring-webflux spring-data-r2dbc r2dbc r2dbc-postgresql
由于 R2DBC 是反应式且非阻塞的,我想了解在简单的 RESTful CRUD 服务中使用 R2DBC 的好处
假设 Spring Boot 应用程序使用下面的存储库公开 RESTful 服务
public interface CustomerRepository extends ReactiveCrudRepository<Customer, Long> {
@Query("SELECT * FROM customer WHERE last_name = :lastname")
Flux<Customer> findByLastName(String lastName);
}
Run Code Online (Sandbox Code Playgroud)
该存储库是从服务调用的,结果需要在服务中进行转换,然后再返回到控制器。
Flux<Customer> customers = repository.findAll();
Run Code Online (Sandbox Code Playgroud)
为了访问完整的客户列表,我需要调用blockLast()
Flux,这会使其阻塞并违背使用反应式组件的目的。
这是否意味着在这个简单的示例中使用 R2DBC 没有任何好处?我错过了什么吗?
Flux 是否只能用于异步订阅(其中 Flux 集合的处理发生在不同的线程中)?
2020Enum
年 8 月15 日更新:似乎在 6 月 16日添加了支持。R2DBC 提交。
H2DBC 是否支持 PostgreSQL 枚举?我检查了他们的git page但它没有提到任何关于它的内容。如果是这样,如何使用枚举(插入、选择)?
让我们说 PostgreSQL 枚举
CREATE TYPE mood AS ENUM ('UNKNOWN', 'HAPPY', 'SAD', ...);
Run Code Online (Sandbox Code Playgroud)
Java类
@Data
public class Person {
private String name;
private Mood mood;
// ...
enum Mood{ UNKNOWN, HAPPY, SAD, ...}
}
Run Code Online (Sandbox Code Playgroud)
我试过:
// insert
var person = ...;
client.insert()
.table("people")
.using(person)
.then()
.subscribe(System.out::println);
// select
var query = "SELECT * FROM people";
client.execute(query)
.as(Person.class)
.fetch().all() …
Run Code Online (Sandbox Code Playgroud) r2dbc ×10
postgresql ×3
spring-data ×3
java ×2
asynchronous ×1
enums ×1
oracle ×1
pojo ×1
spring ×1
spring-boot ×1