如何通过R2DBC Repository向数据库插入包含内嵌实体的记录
R2DBC 内嵌对象存储方案与关联关系支持说明
一、内嵌对象(值对象)映射实现方案
Spring Data R2DBC 针对你提到的类似JPA @Embedded 的内嵌类场景,有两种可行方案:
方案1:使用原生@Embedded注解(适用Spring Data R2DBC 3.0及以上版本)
3.0及以上版本已经正式支持@Embedded注解,用法和JPA基本一致,直接在实体类的内嵌属性上加注解即可:
@Data @NoArgsConstructor public class Person { @Id private Long id; private String name; // 若内嵌类对应表字段有统一前缀,可加prefix属性,比如prefix = "address_" @Embedded private Address address; } @NoArgsConstructor @Data public class Address { private String city; private String state; }
配置完成后,R2DBC会自动将Address类的属性和表中city、state字段做映射,插入、查询都无需额外处理。
方案2:自定义读写转换器(适用Spring Data R2DBC 3.0以下版本)
低版本不支持@Embedded注解,需要手动实现转换器完成对象和数据库行的互相转换:
- 新增写入转换器(实体转数据库行):
@WritingConverter public class PersonWriteConverter implements Converter<Person, OutboundRow> { @Override public OutboundRow convert(Person source) { OutboundRow row = new OutboundRow(); row.put("id", Parameters.from(source.getId())); row.put("name", Parameters.from(source.getName())); row.put("city", Parameters.from(source.getAddress().getCity())); row.put("state", Parameters.from(source.getAddress().getState())); return row; } }
- 新增读取转换器(数据库行转实体):
@ReadingConverter public class PersonReadConverter implements Converter<Row, Person> { @Override public Person convert(Row source) { Person person = new Person(); person.setId(source.get("id", Long.class)); person.setName(source.get("name", String.class)); Address address = new Address(); address.setCity(source.get("city", String.class)); address.setState(source.get("state", String.class)); person.setAddress(address); return person; } }
- 注册转换器到R2DBC配置:
@Configuration @EnableR2dbcRepositories public class R2dbcConfig extends AbstractR2dbcConfiguration { @Override protected List<Object> getCustomConverters() { return List.of(new PersonReadConverter(), new PersonWriteConverter()); } // 连接工厂等其他配置省略 }
二、关联关系支持情况求证
你看到的博客说法是属实的:
目前所有版本的Spring Data R2DBC 都不支持OneToOne、OneToMany、ManyToOne、ManyToMany这类自动关联映射,也不会自动处理关联查询、级联持久化逻辑。这是R2DBC的设计定位决定的:它是轻量级的响应式数据访问层,避免传统ORM复杂关联逻辑带来的额外性能损耗、非预期阻塞风险。如果需要使用关联能力,需要开发者手动编写SQL、自行组装关联对象。
内容的提问来源于stack exchange,提问作者pratik mhatre
相关产品推荐
相关产品推荐

