【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  # 开启驼峰命名自动转换

相关推荐
九皇叔叔30 分钟前
Java循环结构全解析:从基础用法到性能优化
java·开发语言·性能优化
流星52112238 分钟前
GC 如何判断对象该回收?从可达性分析到回收时机的关键逻辑
java·jvm·笔记·学习·算法
csdn_aspnet38 分钟前
Java 圆台体积和表面积计算程序(Program for Volume and Surface area of Frustum of Cone)
java
杯莫停丶44 分钟前
设计模式之:外观模式
java·设计模式·外观模式
乐之者v1 小时前
Mac常用软件
java·1024程序员节
TDengine (老段)1 小时前
TDengine 数据函数 ROUND 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·1024程序员节
TDengine (老段)1 小时前
TDengine 数学函数 RAND 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
從南走到北1 小时前
JAVA无人自助共享系统台球室源码自助开台约球交友系统源码小程序
java·微信·微信小程序·小程序·1024程序员节
JH30731 小时前
jvm,tomcat,spring的bean容器,三者的关系
jvm·spring·tomcat
野犬寒鸦1 小时前
从零起步学习MySQL || 第十章:深入了解B+树及B+树的性能优势(结合底层数据结构与数据库设计深度解析)
java·数据库·后端·mysql·1024程序员节