- 1. 本文核心内容
- 2. BeanPropertyRowMapper 映射原理
- 1. 变量名与字段名相同(代码演示)
- 2. 驼峰映射方式(错误重现)
- 3. BeanPropertyRowMapper 底层原理
- 1. BeanPropertyRowMapper初始化源码
- 2. BeanPropertyRowMapper映射源码
- 4. 驼峰映射问题解决
- 1. 解释上述(驼峰映射方式)代码 原因
- 2. 解决方法
- 1. 字段取名字规范
- 2. sql语句 使用别名
- 3. 继承BeanPropertyRowMapper,重写里面的underscoreName方法
- 4. 自己实现一个implements RowMapper
- 深入了解BeanPropertyRowMapper为什么可以自动帮我们封装实体类。
- BeanPropertyRowMapper 是怎么识别 成员变量与列字段进行映射的。
- 字段驼峰写法 映射失败 的现象重现以及解决方法。
- 变量名与字段名完全相同,即可自动完成映射。
- 驼峰映射方式。
-
先准备好一张表,如下:
-
实体类代码:
@Data @AllArgsConstructor @NoArgsConstructor public class CfgInfo { private Integer id; private String CFG_NAM; private String CFG_TYP; private String CFG_010; private String CFG_020; } -
代码:
public class demo { public static final String DRIVER = "com.mysql.cj.jdbc.Driver"; public static final String URL = "jdbc:mysql://localhost:3306/test_mysql?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8"; public static final String USERNAME = "root"; public static final String PASSWORD = "xxxxxx"; public static void main(String[] args) { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(DRIVER); dataSource.setUrl(URL); dataSource.setUsername(USERNAME); dataSource.setPassword(PASSWORD); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); CfgInfo cfgInfo = jdbcTemplate.queryForObject("SELECt * FROM CFG_TB", new BeanPropertyRowMapper<>(CfgInfo.class)); System.out.println(cfgInfo); } }
这种情况,怎么样子都可以完美自动映射,不必多说。
-
表与上面相同。
-
实体类改为驼峰写法(除了id):
@Data @AllArgsConstructor @NoArgsConstructor public class CfgInfo { private Integer id; private String cfgNam; private String cfgTyp; private String cfg010; private String cfg020; } -
jdbcTemplate代码不变,重新运行:
我们发现有些映射成功了,有些映射失败了,具体原因,请看下面的底层源码解析:
-
直接点进源码:
插入小知识点:jdbc元数据相关博客:https://blog.csdn.net/xueyijin/article/details/121456405
- 现在来解释一下 上述(驼峰映射方式)代码的问题了,cfg010 与 cfg020 没有办法被映射,
第一,全部变成小写还是 cfg010,cfg020 没有问题吧,
第二,驼峰换下划线,结果这tm数字没办法搞,因此等于没有。
然后字段CFG_010,CFG_020,这边全部去掉空格加变小写,cfg_010,cfg_020 ,这哪里有可以对应上的,所以才映射不上,为null。
- 别取这么奇怪的,还带数字,恶心人啊,规范真正的驼峰。
-
可以重写里面的underscoreName方法,生成mappedFields的key 条件变成个性化。
public class MyBeanPropertyRowMapper
extends BeanPropertyRowMapper { public MyBeanPropertyRowMapper(Class mappedClass) { super(mappedClass); } @Override protected String underscoreName(String name) { // 就在name 中 第四个位置加上 下划线 if (!StringUtils.hasLength(name)) { return ""; } // 写的很不规范 别介意 理解意思就行 // 除掉 id if (name.length() < 3) { return name; } StringBuilder result = new StringBuilder(); result.append(name).insert(3, "_"); return result.toString().toLowerCase(); } }
- 也可以自己实现一个映射关系的mapper,这个就不写代码了(有点麻烦,最简单就是copy BeanPropertyRowMapper源码 改一下),大体意思大家都明白的。
- 有的人问居然是copy BeanPropertyRowMapper源码,干嘛不直接继承它,一开始我也是这样子想的,但是它里面的属性要么就是private,要么就是private,要么就是private,继承没啥作用呢。



