【MyBatis】深入解析 MyBatis:关于注解和 XML 的 MyBatis 开发方案下字段名不一致的的查询映射解决方案


注解查询映射


我们再来调用下面的 selectAll() 这个接口,执行的 SQL 是 select* from user_info,表示全列查询:


运行测试类对应方法,在日志中可以看到,字段名一致,Mybatis 就成功从数据库对应的字段中拿到值,但是字段名不一样,则没有从数据库中获取到值;

因为 Java 和数据库的属性命名规范不同,导致一些字段名称不同;

虽然数据库返回的值是正确的,但是并没有给 Java 中 UserInfo 类对象的各个属性成功赋值;


此时,我们需要一个转换规则,让名称不一样的字段可以对应起来:


通过as起别名映射


我们通过 as 关键字来给字段起别名

sql 复制代码
select id , username, `password`, age, gender, phone, delete_flag as deleteFlag, create_time as createTime, update_time as updateTime from user_info;

验证 SQL 语句是否可以被成功执行:


接下来,我们将起好别名的 SQL 语句用 Mybatis 执行:


执行对应测试类方法,观察打印日志:


通过**@Results****进行结构映射映射**


但是上面的方式还是比较麻烦的,我们可以通过注解 @Results 来绑定参数:


我们再继续点 Result [ ] 查看源码:


光从源码,我们还是无法知道 @Results 注解是如何使用的;

下面是 @Results 注解的使用,用于对应名称不一样的数据库字段和 java 属性:


我们重新执行对应的测试类方法,观察打印日志:


通过**@ResultsMap复用@Results**


但是如果后续还要执行关于 select 的 SQL ,岂不是每一个接口方法都要加上:

java 复制代码
    @Results({
            @Result(column = "delete_flag" , property = "deleteFlag"),
            @Result(column = "create_time" , property = "createTime"),
            @Result(column = "update_time" , property = "updateTime")
    })

还是有些麻烦了,是否有更简单的工具,可以帮我们对应上名称不一样的字段呢?

我们再来查看 @Results 注解的源码,源码不单单只有 Result[ ],还有 id;

这个 id 属性可以帮我们标识一条 @Result 注解对应的名字:


通过上面的方式,我们就给这条注解起好了名字,后续如果还要使用 @Results 映射刚刚的字段,只需要使用 @ResultMap 注解来映射 @Results 即可


执行 selectAllById 接口对应的测试类方法,观察日志,成功给后面三个字段赋值,说明映射成功:


开启驼峰命名


但但但但但是,上面的两种方式还是太吃操作了,煮啵煮啵,有没有更简单快捷的映射方法推荐一下?

有的兄弟,有的!!!

接下来这款操作,不需要修改老长的 SQL 语句,也不需要使用复杂的 @Results、@Result、@ResultMap 注解;

我们只需要赋值下面的代码到配置文件中,即可实现从数据库命名规范字段 Java 命名规范字段的转换:

yaml 复制代码
mybatis:
  configuration:
    map-underscore-to-camel-case: true  # 开启驼峰命名自动转换

通常数据库列使用蛇形命名法进行命名(下划线分割各个单词),而 Java 属性一般遵循驼峰命名法约定。

为了在这两种命名方式之间启用自动映射,需要将mapUnderscoreToCamelCase设置为true。


驼峰命名规则:abc_xyz => abcXyz

  • 表中字段名:abc_xyz
  • 类中属性名:abcXyz

配置好对应 yml 文件后,我们再来执行下列接口对应的测试类方法:


观察打印日志,赋值成功,说明成功映射参数:


XML****查询映射


通过as起别名映射


上文提到,我们可以使用 as 对 SQL 中的字段起别名,来解决查询映射的问题;

那么在 XML 开发模式下,又该如何解决该问题呢?我们写出如下 SQL:

sql 复制代码
select id , username, `password`, age, gender, phone, delete_flag as deleteFlag, create_time as createTime, update_time as updateTime from user_info;

值得一提,XML 文件中的 SQL 语句换行没有意义,依旧代表一个完整的字符串,但是在 java 文件中,SQL 语句换行是需要带上 + 加号的;


我们执行对应的测试类方法:


查看打印日志,可以发现,不同名的对应属性通过起别名的方式,依旧可以成功映射:


结果映射


我们重新添加一个方法,来讲解结果映射:


<resultsMap>


此时,我们需要使用 <resultMap> </resultMap> 标签来进行结果映射



其实<resultsMap>标签和 @Result 注解源码是类似的,需要写的字段一样,知识写法不同:


@Results 的写法如下:


我们可以类比 <resultsMap> 的写法:


不过,如果使用这种方法来映射属性,就要把对象中的所有属性的映射都写全;

因为在别的 XML 文件中,依旧可以引入这个映射,特定场景下,如果这个映射没有写入全部对象属性,则可能会映射不上;




生成测试语句,调用 selectAll2() 对应的测试类方法,观察打印日志:


开启驼峰命名


yaml 复制代码
mybatis:
  configuration:
    map-underscore-to-camel-case: true  # 开启驼峰命名自动转换

相关推荐
高山流水&上善10 分钟前
医药档案区块链系统
java·springboot
南汐以墨37 分钟前
探秘JVM内部
java·jvm
Craaaayon39 分钟前
Java八股文-List集合
java·开发语言·数据结构·list
信徒_1 小时前
Spring 怎么解决循环依赖问题?
java·后端·spring
2301_794461571 小时前
多线程编程中的锁策略
java·开发语言
老华带你飞1 小时前
木里风景文化|基于Java+vue的木里风景文化管理平台的设计与实现(源码+数据库+文档)
java·数据库·vue.js·毕业设计·论文·风景·木里风景文化管理平台
SofterICer1 小时前
Eclipse Leshan 常见问题解答 (FAQ) 笔记
java·笔记·eclipse
liang89991 小时前
Shiro学习(四):Shiro对Session的处理和缓存
java·学习·缓存
苏格拉没有底_coder2 小时前
【Easylive】saveVideoInfo 方法详细解析
java
小杨4042 小时前
springboot框架项目实践应用十五(扩展sentinel区分来源)
spring boot·后端·spring cloud