【MyBatis】深入解析 MyBatis:关于注解和 XML 的 MyBatis 开发方案下字段名不一致的的查询映射解决方案
注解查询映射
我们再来调用下面的 selectAll() 这个接口,执行的 SQL 是 select* from user_info
,表示全列查询:
运行测试类对应方法,在日志中可以看到,字段名一致,Mybatis 就成功从数据库对应的字段中拿到值,但是字段名不一样,则没有从数据库中获取到值;
因为 Java 和数据库的属性命名规范不同,导致一些字段名称不同;
虽然数据库返回的值是正确的,但是并没有给 Java 中 UserInfo 类对象的各个属性成功赋值;
此时,我们需要一个转换规则,让名称不一样的字段可以对应起来:
通过 as 起别名映射
我们通过 as
关键字来给字段起别名
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 ,岂不是每一个接口方法都要加上:
@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 命名规范字段
的转换:
mybatis:configuration:map-underscore-to-camel-case: true # 开启驼峰命名自动转换
通常数据库列使用蛇形命名法进行命名(下划线分割各个单词),而 Java 属性一般遵循驼峰命名法
约定。
为了在这两种命名方式之间启用自动映射,需要将mapUnderscoreToCamelCase
设置为true。
驼峰命名规则:
abc_xyz
=>abcXyz
- 表中字段名:
abc_xyz
- 类中属性名:
abcXyz
配置好对应 yml 文件后,我们再来执行下列接口对应的测试类方法:
观察打印日志,赋值成功,说明成功映射参数:
XML 查询映射
通过 as 起别名映射
上文提到,我们可以使用 as 对 SQL 中的字段起别名,来解决查询映射的问题;
那么在 XML 开发模式下,又该如何解决该问题呢?我们写出如下 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() 对应的测试类方法,观察打印日志:
开启驼峰命名
mybatis:configuration:map-underscore-to-camel-case: true # 开启驼峰命名自动转换