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

如何用BeanPropertyRowMapper映射属性名与不同数据库列名

问题描述

我正尝试将数据类映射到JdbcTemplate的结果集。属性名与列名匹配的字段可正常映射,但不匹配的字段无法映射。请问是否有注解可实现此类映射?Funding类并非实体类。

代码示例

@Data
public class Funding {

    private Long loanId; // 数据库列名为LOAN_ID - 映射正常
    private String sellerLoanId;// 数据库列名为L_SELLER_LOAN_ID - 映射失败
}

mapper = BeanPropertyRowMapper.newInstance(Funding.class);
List<Funding> fundingValues = this.jdbcTemplate.query(sql, mapper);

我尝试过如下注解:

@Column(name = "L_SELLER_LOAN_ID")

解决方案

默认的BeanPropertyRowMapper并不支持JPA的@Column注解,它仅通过驼峰-下划线自动转换匹配属性和列名(比如loanId对应LOAN_ID),但你的sellerLoanId对应的自动转换列名是SELLER_LOAN_ID,和实际的L_SELLER_LOAN_ID不匹配,所以映射失败。以下是几种可行的解决方式:

方式一:SQL语句中添加列别名(最简单)

直接在查询SQL里给目标列设置和属性名一致的别名,让BeanPropertyRowMapper自动匹配:

SELECT LOAN_ID, L_SELLER_LOAN_ID AS sellerLoanId FROM your_table

这种方式无需修改Java代码,快速生效。

方式二:自定义RowMapper手动映射

如果不想修改SQL,可以手动实现RowMapper接口,精准控制每个字段的映射逻辑:

List<Funding> fundingValues = this.jdbcTemplate.query(sql, (ResultSet rs, int rowNum) -> {
    Funding funding = new Funding();
    funding.setLoanId(rs.getLong("LOAN_ID"));
    funding.setSellerLoanId(rs.getString("L_SELLER_LOAN_ID"));
    return funding;
});

方式三:扩展BeanPropertyRowMapper支持@Column注解

如果希望通过注解来统一管理列名映射,可以自定义BeanPropertyRowMapper的子类,解析@Column注解的列名:

1. 自定义映射器类

import org.springframework.jdbc.core.BeanPropertyRowMapper;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.persistence.Column;

public class AnnotationSupportRowMapper<T> extends BeanPropertyRowMapper<T> {

    private final Class<T> mappedClass;

    public AnnotationSupportRowMapper(Class<T> mappedClass) {
        super(mappedClass);
        this.mappedClass = mappedClass;
    }

    public static <T> AnnotationSupportRowMapper<T> newInstance(Class<T> mappedClass) {
        return new AnnotationSupportRowMapper<>(mappedClass);
    }

    @Override
    protected Object getColumnValue(ResultSet rs, int index, PropertyDescriptor pd) throws SQLException {
        // 尝试获取属性对应的字段上的@Column注解
        try {
            Field field = mappedClass.getDeclaredField(pd.getName());
            Column column = field.getAnnotation(Column.class);
            if (column != null && !column.name().trim().isEmpty()) {
                // 如果注解存在,直接使用注解指定的列名取值
                return rs.getObject(column.name(), pd.getPropertyType());
            }
        } catch (NoSuchFieldException e) {
            // 找不到字段时,回退到默认的驼峰转换逻辑
        }
        return super.getColumnValue(rs, index, pd);
    }
}

2. 使用自定义映射器

给Funding类的字段加上@Column注解后,替换原来的BeanPropertyRowMapper:

@Data
public class Funding {
    private Long loanId; // 数据库列名为LOAN_ID - 映射正常
    
    @Column(name = "L_SELLER_LOAN_ID")
    private String sellerLoanId;// 数据库列名为L_SELLER_LOAN_ID - 现在可正常映射
}

// 使用自定义映射器
mapper = AnnotationSupportRowMapper.newInstance(Funding.class);
List<Funding> fundingValues = this.jdbcTemplate.query(sql, mapper);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 08:40:37