Spring - 如何在不加工列名的情况下使用BeanPropertyRowMapper

时间:2012-02-27 17:43:45

标签: java spring

我使用行映射器处理已从纯JDBC转换为Spring模板的应用程序。我遇到的问题是数据库中的列与阻止我轻松使用BeanPropertyRowMapper的属性名称不匹配。

我看到一些关于在查询中使用别名的帖子。这样可行,但却无法进行SELECT *

JPA中BeanPropertyRowMapper的{​​{1}}是否有任何注释可以使用?

2 个答案:

答案 0 :(得分:5)

  

我看到一些关于在查询中使用别名的帖子

这实际上是JavaDocs中建议的一种方法:

  

为了便于在不具有匹配名称的列和字段之间进行映射,请尝试在SQL语句中使用列别名,例如"从客户"中选择fname作为first_name。

来自:BeanPropertyRowMapper

  

不可能做SELECT *

请不要使用SELECT *。这使您容易受到任何数据库架构更改的影响,包括完全向后兼容的更改,如添加或重新排列列。

  

是否有任何可以与BeanPropertyRowMapper一起使用的注释作为JPA的@Column?

是的,它被称为,也许是。说真的,要么使用别名,要么实现自己的RowMapper,Spring不是功能齐全的

答案 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);
  }
}