You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中如何扁平化存储嵌套POJO数据?

问题描述

我有一个接收POJO的REST接口用于存储数据,相关代码如下:

@Service
public class CassandraService {

    @Autowired MyReactiveCassandraRepository cassandraRepository;

    public Mono<String> save(Pojo pojo) {
        return cassandraRepository.save(pojo);
    }
    
}
@Repository
public interface MyReactiveCassandraRepository extends ReactiveCrudRepository<Pojo, String> {
}
@Table
public class Pojo {

    @PrimaryKey
    private String id;

    private String foo;

    private InnerPojo innerPojo;
}
public class InnerPojo {

    String aaa;

    String bbb;
}

我希望将数据扁平化存储(而非保留嵌套结构),预期的Cassandra表结构如下:

idfooaaabbb

目前我是通过复制一个FlattenPojo类并手动编写转换代码来实现,但想知道Spring Boot里有没有更优雅的方式?


解决方案

1. 直接利用Spring Data Cassandra的字段映射(无需额外POJO)

无需创建新类,直接在原Pojo上通过注解指定嵌套属性的列名,让Spring Data自动处理扁平化存储:

修改Pojo类:

@Table
public class Pojo {

    @PrimaryKey
    private String id;

    private String foo;

    // 映射嵌套属性到扁平列
    @Column("aaa")
    public String getAaa() {
        return innerPojo != null ? innerPojo.getAaa() : null;
    }

    @Column("bbb")
    public String getBbb() {
        return innerPojo != null ? innerPojo.getBbb() : null;
    }

    // 保留原嵌套字段,用于接收REST接口的嵌套数据
    private InnerPojo innerPojo;

    // 省略所有字段的getter/setter
}

这种方式下,Spring Data Cassandra会自动将innerPojo的属性映射到Cassandra的扁平列中,同时原Pojo仍能正常接收接口传入的嵌套数据。

2. 实现自定义类型转换器

通过Spring的Converter接口,让框架自动处理Pojo与扁平存储实体的转换,避免手动编写重复代码:

第一步:定义内部存储用的扁平实体

// 仅作为Cassandra存储载体,无需对外暴露
public class FlattenedPojoEntity {
    @PrimaryKey
    private String id;
    private String foo;
    private String aaa;
    private String bbb;

    // 省略构造器、getter/setter
}

第二步:编写转换逻辑

@Component
public class PojoToFlattenedEntityConverter implements Converter<Pojo, FlattenedPojoEntity> {

    @Override
    public FlattenedPojoEntity convert(Pojo source) {
        FlattenedPojoEntity entity = new FlattenedPojoEntity();
        entity.setId(source.getId());
        entity.setFoo(source.getFoo());
        if (source.getInnerPojo() != null) {
            entity.setAaa(source.getInnerPojo().getAaa());
            entity.setBbb(source.getInnerPojo().getBbb());
        }
        return entity;
    }
}

// 如需查询后转换回原Pojo,添加反向转换器
@Component
public class FlattenedEntityToPojoConverter implements Converter<FlattenedPojoEntity, Pojo> {

    @Override
    public Pojo convert(FlattenedPojoEntity source) {
        Pojo pojo = new Pojo();
        pojo.setId(source.getId());
        pojo.setFoo(source.getFoo());
        InnerPojo inner = new InnerPojo();
        inner.setAaa(source.getAaa());
        inner.setBbb(source.getBbb());
        pojo.setInnerPojo(inner);
        return pojo;
    }
}

第三步:修改Repository与Service

@Repository
public interface FlattenedPojoRepository extends ReactiveCrudRepository<FlattenedPojoEntity, String> {
}
@Service
public class CassandraService {

    @Autowired FlattenedPojoRepository repository;

    public Mono<String> save(Pojo pojo) {
        return repository.save(pojo)
                .map(FlattenedPojoEntity::getId);
    }
}

Spring会自动识别并触发转换器,无需手动调用转换方法。

3. 用ModelMapper简化对象转换

如果必须保留原POJO与扁平类的分离(比如原POJO需严格匹配接口契约),可以用ModelMapper自动处理属性映射:

第一步:引入依赖(Maven)

<dependency>
    <groupId>org.modelmapper</groupId>
    <artifactId>modelmapper</artifactId>
    <version>3.1.1</version>
</dependency>

第二步:配置ModelMapper

@Configuration
public class ModelMapperConfig {
    @Bean
    public ModelMapper modelMapper() {
        ModelMapper mapper = new ModelMapper();
        // 配置嵌套属性到扁平字段的映射规则
        mapper.typeMap(Pojo.class, FlattenPojo.class)
                .addMapping(p -> p.getInnerPojo().getAaa(), FlattenPojo::setAaa)
                .addMapping(p -> p.getInnerPojo().getBbb(), FlattenPojo::setBbb);
        return mapper;
    }
}

第三步:在Service中使用

@Service
public class CassandraService {

    @Autowired MyReactiveCassandraRepository repository;
    @Autowired ModelMapper modelMapper;

    public Mono<String> save(Pojo pojo) {
        FlattenPojo flattened = modelMapper.map(pojo, FlattenPojo.class);
        return repository.save(flattened);
    }
}

内容的提问来源于stack exchange,提问作者PatPanda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 10:25:20