如何用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
相关产品推荐
相关产品推荐

