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

如何将数据库查询得到的Billing对象转换为Record对象并添加至List<Record>集合?

解决Billing对象转Record对象并添加到列表的问题

嘿,这个问题其实是Java强类型特性导致的——Billing和Record是完全不同的类,所以不能直接把Billing对象塞进List<Record>里。我们需要把Billing的属性映射到Record对象中,创建一个符合要求的Record实例再添加进去。下面分几种方式来实现,从最基础的手动映射开始,帮你理解原理:

1. 手动属性映射(最直观,适合理解原理)

这是最基础的方式,你可以清晰看到每一个属性是如何从Billing转移到Record的:

public List<Record> getRecord(List<Request> requests) {
    List<Record> records = new ArrayList<>();
    for (Request request : requests) {
        Billing billing = billingRepository
                .findByBillingCycleAndStartDateAndEndDate(
                        request.getBillingCycle() ,
                        request.getStartDate() ,
                        request.getEndDate());
        if (billing != null) {
            // 1. 创建一个空的Record对象
            Record record = new Record();
            
            // 2. 映射两个类共有的属性
            record.setBillingCycle(billing.getBillingCycle());
            record.setStartDate(billing.getStartDate());
            record.setEndDate(billing.getEndDate());
            record.setAmount(billing.getAmount());
            
            // 3. 映射关联的Account属性(注意空指针判断!)
            Account account = billing.getAccountId();
            if (account != null) {
                record.setAccountName(account.getAccountName()); // 假设Account类有对应getter
                record.setFirstName(account.getFirstName());     // 假设Account类有对应getter
                record.setLastname(account.getLastname());       // 假设Account类有对应getter
            }
            
            // 4. 将转换后的Record添加到列表
            records.add(record);
        }
    }
    return records;
}

原理说明:

Java是强类型语言,集合List<Record>只能存储Record类型的对象。我们通过手动读取Billing对象的属性值,调用Record的setter方法把值赋值进去,生成一个全新的Record实例,这样就符合集合的类型要求了。

另外要注意billing.getAccountId()可能为null,所以一定要加空判断,避免NullPointerException。

2. 封装转换逻辑(代码更整洁,复用性强)

如果这个转换逻辑在多个地方用到,我们可以把转换逻辑封装到Record类里,比如添加一个静态工厂方法或者构造器:

方式2.1:添加静态工厂方法到Record类

public class Record {
    // 原有的属性、构造器、getter/setter保持不变
    
    // 新增静态方法,接收Billing对象返回Record实例
    public static Record fromBilling(Billing billing) {
        if (billing == null) {
            return null;
        }
        Record record = new Record();
        record.setBillingCycle(billing.getBillingCycle());
        record.setStartDate(billing.getStartDate());
        record.setEndDate(billing.getEndDate());
        record.setAmount(billing.getAmount());
        
        Account account = billing.getAccountId();
        if (account != null) {
            record.setAccountName(account.getAccountName());
            record.setFirstName(account.getFirstName());
            record.setLastname(account.getLastname());
        }
        return record;
    }
}

然后在你的业务方法里就可以简化成:

if (billing != null) {
    records.add(Record.fromBilling(billing));
}

方式2.2:添加接收Billing的构造器

public class Record {
    // 原有的属性、无参构造器、getter/setter保持不变
    
    // 新增接收Billing的构造器
    public Record(Billing billing) {
        if (billing == null) {
            return;
        }
        this.billingCycle = billing.getBillingCycle();
        this.startDate = billing.getStartDate();
        this.endDate = billing.getEndDate();
        this.amount = billing.getAmount();
        
        Account account = billing.getAccountId();
        if (account != null) {
            this.accountName = account.getAccountName();
            this.firstName = account.getFirstName();
            this.lastname = account.getLastname();
        }
    }
}

业务方法里的调用就变成:

if (billing != null) {
    records.add(new Record(billing));
}

原理说明:

把转换逻辑封装到目标类(Record)中,符合单一职责原则,同时让业务代码更简洁,也方便后续修改转换规则时只需要改一处地方。

3. 进阶:使用对象映射工具(减少重复代码)

如果你的项目中有很多类似的对象转换需求,可以使用像ModelMapper这样的工具库,它能自动匹配同名属性进行映射,减少手动写setter的工作量。

步骤:

  1. 先在项目中引入ModelMapper依赖(比如Maven):
<dependency>
    <groupId>org.modelmapper</groupId>
    <artifactId>modelmapper</artifactId>
    <version>3.1.1</version>
</dependency>
  1. 配置ModelMapper(可以定义为Spring Bean,或者直接创建实例):
ModelMapper modelMapper = new ModelMapper();
// 对于不同名的属性或者关联对象,可以配置映射规则
modelMapper.typeMap(Billing.class, Record.class)
    .addMapping(Billing::getAccountId, (dest, value) -> {
        Account account = (Account) value;
        if (account != null) {
            dest.setAccountName(account.getAccountName());
            dest.setFirstName(account.getFirstName());
            dest.setLastname(account.getLastname());
        }
    });
  1. 业务方法中使用:
if (billing != null) {
    Record record = modelMapper.map(billing, Record.class);
    records.add(record);
}

原理说明:

对象映射工具通过反射机制读取源对象的属性,自动匹配目标对象的同名属性进行赋值,对于特殊的映射规则(比如关联对象、不同名属性)可以通过配置来定义,大大减少了手动编写转换代码的工作量,适合大型项目使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 19:24:05