Mybatis中多表关联时,怎么利用association优雅写resultMap来映射vo

前言#

有好一阵没碰mybatis了,这次的项目基于性能考虑,选了mybatis,写着写着,发现有下面的需求,比如两表联查,取其中各一部分字段,怎么更方便地用vo来接,这里犯了难;

我想的是,因为这个sql联查的vo,能不能直接使用两个表的po来接呢,比如下面这种:

Copy
UsersSeatInformation都是对应了数据库两张表的po @Data public class UserSeatUnionQueryVO { private Users users; private SeatInformation seatInformation; }

折腾了2个小时,网上各种找不到类似需求,终于搞出来了,还是值得记录和分享。

一、两表关联,映射到如下类型vo(拷贝单表po属性,组合另一单表的po),怎么写#

sql:

Copy
<select id="selectOnlineUserBySeatState" resultMap="UserSeatUnionQueryVOResultMap"> SELECT u.`user_id`,u.`account_status`,s.* FROM users u, seat_information s WHERE u.`user_id` = s.`user_id` AND u.`account_status` = 1 AND u.`delete_status` = 1 AND u.`center_id` = 0 AND s.`token` IS NOT NULL AND s.`seat_state` = 1 AND s.delete_status = 1 </select>

假设我想映射的vo如下:

Copy
@Data public class UserSeatUnionQueryVO { /** * 用户Id */ @ApiModelProperty(value = "用户Id") @TableId(value = "user_id", type = IdType.ID_WORKER) private Long userId; /** * 账号状态,-1停用,1启用 */ @ApiModelProperty(value = "账号状态,-1停用,1启用") private Integer accountStatus; /** * 这里的SeatInformation是表seat_information对应的po */ private SeatInformation seatInformation; }

则mapper中应该这样写:

Copy
UsersMapper.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.foo.cad.mapper.UsersMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.foo.cad.model.Users"> <id column="user_id" property="userId" /> <result column="account_status" property="accountStatus" /> </resultMap> <resultMap id="UserSeatUnionQueryVOResultMap" type="com.foo.cad.service.UserSeatUnionQueryVO"> <id column="user_id" property="userId" /> <result column="account_status" property="accountStatus" /> <association property="seatInformation" javaType="com.foo.cad.model.SeatInformation" resultMap="com.foo.cad.mapper.SeatInformationMapper.BaseResultMap"> </association> </resultMap> <select id="selectOnlineUserBySeatState" resultMap="UserSeatUnionQueryVOResultMap"> SELECT u.`user_id`,u.`account_status`,s.* FROM users u, seat_information s WHERE u.`user_id` = s.`user_id` AND u.`account_status` = 1 AND u.`delete_status` = 1 AND u.`center_id` = 0 AND s.`token` IS NOT NULL AND s.`seat_state` = 1 AND s.delete_status = 1 </select> </mapper>
Copy
SeatInformationMapper.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.foo.cad.mapper.SeatInformationMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.foo.cad.model.SeatInformation"> <id column="seat_information_id" property="seatInformationId" /> //省略无关代码 </resultMap> </mapper>

二、两表关联,映射到如下类型vo(组合两表po),怎么写#

上面的方案呢,假设A关联B,在vo里,相当于是把B组合进了A;我想的是,能不能新建一个vo,同时组合A和B呢,比如下面这样:

Copy
@Data public class UserSeatUnionQueryVO { private Users users; private SeatInformation seatInformation; }

sql:

和方案一一样。

UsersMapper.xml:

Copy
<resultMap id="UserSeatUnionQueryVOResultMap" type="com.foo.cad.service.UserSeatUnionQueryVO"> <association property="users" javaType="com.foo.cad.model.Users" resultMap="com.foo.cad.mapper.UsersMapper.BaseResultMap"> </association> <association property="seatInformation" javaType="com.foo.cad.model.SeatInformation" resultMap="com.foo.cad.mapper.SeatInformationMapper.BaseResultMap"> </association> </resultMap>

注意这里的 association元素中的resultMap字段,引用了其他Mapper文件的BaseResultMap

格式是:其他Mapper文件的namespace,加上resultMap的名字。

这里附上SeatInformationMapper.xml的内容:

Copy
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.foo.cad.mapper.SeatInformationMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.foo.cad.model.SeatInformation"> <id column="seat_information_id" property="seatInformationId" /> //省略无关 </resultMap> </mapper>

下面附上完整的usersMapper.xml的内容:

Copy
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.foo.cad.mapper.UsersMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.foo.cad.model.Users"> <id column="user_id" property="userId" /> <result column="account_status" property="accountStatus" /> </resultMap> <resultMap id="UserSeatUnionQueryVOResultMap" type="com.foo.cad.service.UserSeatUnionQueryVO"> <association property="users" javaType="com.foo.cad.model.Users" resultMap="com.foo.cad.mapper.UsersMapper.BaseResultMap"> </association> <association property="seatInformation" javaType="com.foo.cad.model.SeatInformation" resultMap="com.foo.cad.mapper.SeatInformationMapper.BaseResultMap"> </association> </resultMap> <select id="selectOnlineUserBySeatState" resultMap="UserSeatUnionQueryVOResultMap"> SELECT u.*,s.* FROM users u, seat_information s WHERE u.`user_id` = s.`user_id` AND u.`account_status` = 1 AND u.`delete_status` = 1 AND u.`center_id` = 0 AND s.`token` IS NOT NULL AND s.`seat_state` = 1 AND s.delete_status = 1 </select> </mapper>

展示下效果:

可以看到,最后这种,这么写没问题。

三、官网文档#

我在官网看了半天,后来才找到类似的例子:

https://mybatis.org/mybatis-3/sqlmap-xml.html

因为文档很长,上面这个图,大家可以通过打开上面的网址后,搜索 Multiple ResultSets for Association到达该位置。




posted @   三国梦回  阅读(4500)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示
CONTENTS