Spring-Boot-Jdbc-AutoRowMapper

本文最后更新于:几秒前

起因

难免会有一些需求需要用到Jdbc, 但是很讨人厌的, 他又要去写 RowMapper , 非常费劲

本着思考, 这TM都 SpringJdbc 了, 他总不会封装了个寂寞吧, 果然, 找到一个名字很奇怪的 RowMapper 实现

8aa4167c-a1de-4014-afc9-a5bb0f978944.png

BeanPropertyRowMapper

描述

/**

  • {@link RowMapper} implementation that converts a row into a new instance
  • of the specified mapped target class. The mapped target class must be a
  • top-level class and it must have a default or no-arg constructor.
  • Column values are mapped based on matching the column name as obtained from result set

  • meta-data to public setters for the corresponding properties. The names are matched either
  • directly or by transforming a name separating the parts with underscores to the same name
  • using “camel” case.
  • Mapping is provided for fields in the target class for many common types, e.g.:

  • String, boolean, Boolean, byte, Byte, short, Short, int, Integer, long, Long,
  • float, Float, double, Double, BigDecimal, {@code java.util.Date}, etc.
  • To facilitate mapping between columns and fields that don't have matching names,

  • try using column aliases in the SQL statement like “select fname as first_name from customer”.
  • For 'null' values read from the database, we will attempt to call the setter, but in the case of

  • Java primitives, this causes a TypeMismatchException. This class can be configured (using the
  • primitivesDefaultedForNullValue property) to trap this exception and use the primitives default value.
  • Be aware that if you use the values from the generated bean to update the database the primitive value
  • will have been set to the primitive’s default value instead of null.
  • Please note that this class is designed to provide convenience rather than high performance.

  • For best performance, consider using a custom {@link RowMapper} implementation.
  • @author Thomas Risberg
  • @author Juergen Hoeller
  • @since 2.5
  • @param the result type
  • @see DataClassRowMapper
    */

解释

大致的意思的就是, 不能是内部类, 需要有无参构造函数(Java类默认会有一个无参构造函数, 你覆盖了要补上)
名称对应就行, 或者 数据库(下划线) -> 实体类(驼峰)
有 String, boolean, Boolean, byte, Byte, short, Short, int, Integer, long, Long, float, Float, double, Double, BigDecimal, {@code java.util.Date}, etc 支持啦
对于 null 值, 会调用 set , 如果希望有基本类型默认值, 可以设置 primitivesDefaultedForNullValue = true, (不过对于这个, 我们好像用的都不是基本类型)
最后就是, 啊巴拉巴拉, 这个不是为了高性能准备的, 如果要高性能你就自己写 RowMapper

高性能

emmmm, 其实大部分场景中, 我们对性能并没有那么那么高, 我记得以前有一个问题说是,

MapStruct vs BeanUtils

厚礼蟹, 这种问题就别问了好吗, 你问我我就是说推荐 MapStruct, 但是我自己偷偷用 BeanUtils, 再说了 别人 BeanUtils 自己也有缓存的

借用一个 压测的结果图
79b99c54-4dc7-49ac-8cd8-6bb380689d2c.png

有这时间优化一下查询, 如果你的是纯内存操作, 那就建议用MapStruct, 早点下班, 摸摸鱼多好

案例

接口

1
2
3
4
@Override
public <T> List<T> query(String sql, RowMapper<T> rowMapper, @Nullable Object... args) throws DataAccessException {
return result(query(sql, args, new RowMapperResultSetExtractor<>(rowMapper)));
}

使用

1
this.jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Booking.class), args);

唉, 其实这段代码很奇怪, 这就是Java的残疾泛型, 如果Java泛型是存在运行期的情况, 下完全可以用

1
this.jdbcTemplate.query(sql, new BeanPropertyRowMapper<Booking>(), args);

总结

用用用, 仅限于基本类型和常用的一些类型, 至于嵌套一些自定义类, 还是自己 RowMapper 或者魔改吧

相关链接

  1. https://github.com/lets-mica/mica-jmh/wiki/BeanCopy

Spring-Boot-Jdbc-AutoRowMapper
https://zhengchalei.github.io/2023/01/11/Spring-Boot-Jdbc-AutoRowMapper/
作者
ZhengChaLei
发布于
2023年1月11日
许可协议