在涉及到关系型数据库增删查改的业务时,我比较喜欢用 MyBatis-Plus ,开发效率极高。具体的使用可以参考官网,或者自己上手摸索感受一下。
下面简单总结一下在 MyBatis-Plus 中如何使用 ResultMap 。
先看个例子:
有如下两张表:
其中, tb_hero 中的 bid 关联 tb_book 表的 id 。
下面先看 Hero 实体类的代码,如下:
注意了,我特地把 tb_hero 表中的 bid 字段映射成实体类 Hero 中的 bookId 属性。
MyBatis-Plus 打印出的 SQL 为:
没毛病, MyBatis-Plus 会根据 @TableField 指定的映射关系,生成对应的 SQL 。
MyBatis-Plus 打印出的 SQL 为:
也没毛病,可以看到生成的 SELECT 中把 bid 做了别名 bookId 。
比如现在我想连接 tb_hero 与 tb_book 这两张表,如下:
查询 MyBatis-Plus 打印出的 SQL 为:
SQL没啥问题,过滤与分页也都正常,但是此时你会发现 bookId 属性为 null ,如下:
为什么呢?
调用 BaseMapper 中内置的 selectById() 方法并没有出现这种情况啊???
回过头来再对比一下在 HeroMapper 中自己定义的查询与 MyBatis-Plus 自带的 selectById() 有啥不同,还记得上面的刚刚的测试吗,生成的SQL有啥不同?
原来, MyBatis-Plus 为 BaseMapper 中内置的方法生成SQL时,会把 SELECT 子句中 bid 做别名 bookId ,而自己写的查询 MyBatis-Plus 并不会帮你修改 SELECT 子句,也就导致 bookId 属性为 null 。
在这里就是 tb_hero 表中的 bid 字段映射成实体类 Hero 中的 bid 属性。这样当然可以解决问题,但不是本篇讲的重点。
在 @TableName 设置 autoResultMap = true
然后在自定义查询中添加 @ResultMap 注解,如下:
这样,也能解决问题。
下面简单看下源码, @ResultMap("mybatis-plus_实体类名") 怎么来的。
详情见:告拆 com.baomidou.mybatisplus.core.metadata.TableInfo#initResultMapIfNeed()
注意看上面的字符串 id 的构成,你应该可以明白。
思考: 这种方式的 ResultMap 默认是强绑在一个 @TableName 上的,如果是某个聚合查询或者查询的结果并非对应一个真实的表怎么办呢?有没有更优雅的方式?
基于上面的袜仔枣思考,我做了下面简单的实现:
关键代码其实没有几行,耐心看下应该不难懂。
还是用例子来说明更直观。
下面是一个聚合查询:戚兆
其中 BookAgg 的定义如下,在实体类上使用了 @AutoResultMap 注解:
resultType="java.lang.Integer"
Integer如果一条都没有是会返回null的指斗,所以不会报错,而用int的话没有会返回0
MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap,resultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用,但是resultType跟resultMap不能同时存在。
扩展资料:注意事项
一、若<sql/>查询语句中配置的是resultType=“实体类/DTO”,则从mybatis返回的键值对结帆唤果集(Map)会直接赋值给该DTO(根据set()/get()方法,因此该DTO属性名要与表字段名一致,若不一致,可再sql查询语句中用as更换查出来表字段名)中相映射的属性值,而与该mappper.xml文件配置<mapper/>里的<resultMap />无关。
二、若<sql/>查询语句中配置的是resultMap=“<mapper/>中配置的<resultMap />”,态逗凯则从mybatis返回的键值对结果集(Map)会根据该<resultMap />配置中(column-property)的相应属性赋值。
命名规则就是: mybatis-plus_{实体类名}
MyBatis Plus本身并不是一个动态的ORM,而只是在mybatis初始化的时候握配,为mybatis提供常用的SQL语句,resultMap设置,并不段含指会改变MyBatis本身的行为老判
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)