我使用行映射器处理已从纯JDBC转换为Spring模板的应用程序。我遇到的问题是数据库中的列与阻止我轻松使用BeanPropertyRowMapper
的属性名称不匹配。
我看到一些关于在查询中使用别名的帖子。这样可行,但却无法进行SELECT *
JPA中BeanPropertyRowMapper
的{{1}}是否有任何注释可以使用?
答案 0 :(得分:5)
我看到一些关于在查询中使用别名的帖子
这实际上是JavaDocs中建议的一种方法:
为了便于在不具有匹配名称的列和字段之间进行映射,请尝试在SQL语句中使用列别名,例如"从客户"中选择fname作为first_name。
不可能做SELECT *
请不要使用SELECT *
。这使您容易受到任何数据库架构更改的影响,包括完全向后兼容的更改,如添加或重新排列列。
是否有任何可以与BeanPropertyRowMapper一起使用的注释作为JPA的@Column?
是的,它被称为jpa,hibernate,也许是ibatis。说真的,要么使用别名,要么实现自己的RowMapper
,Spring不是功能齐全的orm。
答案 1 :(得分:3)
您可以覆盖BeanPropertyRowMapper.underscoreName
,并获取Column批注的名称,以使用PropertyDescriptor(getter / setter绑定)中的@Column(name = "EXAMPLE_KEY")
映射字段。
@Slf4j
public class ColumnRowMapper<T> extends BeanPropertyRowMapper<T> {
private ColumnRowMapper(final Class<T> mappedClass)
{
super(mappedClass);
}
@Override
protected String underscoreName(final String name)
{
final Column annotation;
final String columnName;
Field declaredField = null;
try
{
declaredField = getMappedClass().getDeclaredField(name);
}
catch (NoSuchFieldException | SecurityException e)
{
log.warn("Ups, field «{}» not found in «{}».", name, getMappedClass());
}
if (declaredField == null || (annotation = declaredField.getAnnotation(Column.class)) == null
|| StringUtils.isEmpty(columnName = annotation.name()))
{
return super.underscoreName(name);
}
return StringUtils.lowerCase(columnName);
}
/**
* New instance.
*
* @param <T> the generic type
* @param mappedClass the mapped class
* @return the bean property row mapper
*/
public static <T> BeanPropertyRowMapper<T> newInstance(final Class<T> mappedClass)
{
return new ColumnRowMapper<>(mappedClass);
}
}