解决N+1问题的另一种方法 - 关联的多结果集ResultSet

如果我的博客对你有帮助,欢迎进行评论✏️✏️、点赞👍👍、收藏⭐️⭐️,满足一下我的虚荣心💖🙏🙏🙏 。

从版本 3.2.3 开始,MyBatis 提供了另一种解决 N+1 查询问题的方法--关联的多结果集(ResultSet)
某些数据库允许存储过程返回多个结果集,或一次性执行多个语句,每个语句返回一个结果集。 我们可以利用这个特性,在不使用连接的情况下,只访问数据库一次就能获得相关数据。

先介绍下它的属性:

column:当使用多个结果集时,该属性指定结果集中用于与 foreignColumn 匹配的列(多个列名以逗号隔开),以识别关系中的父类型与子类型。
foreignColumn:指定外键对应的列名,指定的列将与父类型中 column 的给出的列进行匹配。
resultSet:指定用于加载复杂类型的结果集名字。

首先新建一个简单的存储过程,存储过程执行两个查询语句返回两个结果集。第一个结果集会返回User的结果,第二个则返回Wife的结果,如下:

DELIMITER $$
CREATE PROCEDURE `uwife`(IN `userId` INT)
BEGIN
	SELECT * FROM mybatis_user WHERE id = userId;
	SELECT * FROM mybatis_wife WHERE user_id = userId;
END $$

在映射语句中,必须通过 resultSets 属性为每个结果集指定一个名字,多个名字使用逗号隔开。

<select id="selectByResultSet" resultSets="uresult,wresult" 
    resultMap="userResultByResultSet" statementType="CALLABLE">
        {call uwife(#{userId,jdbcType=INTEGER,mode=IN})}
    </select>

现在我们可以指定使用 “wresult” 结果集的数据来填充 “wife” 关联:

<resultMap id="userResultByResultSet" type="User">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="sex" column="sex"/>
        <result property="age" column="age"/>
        <result property="province" column="province"/>
        <result property="city" column="city"/>
        <result property="createdTime" column="created_time"/>
        <result property="createdBy" column="created_by"/>
        <result property="updatedTime" column="updated_time"/>
        <result property="updatedBy" column="updated_by"/>
        <association property="wife" javaType="Wife" resultSet="wresult" column="id" foreignColumn="user_id">
            <id property="wifeId" column="wife_id"/>
            <result property="userId" column="user_id"/>
            <result property="wifeName" column="wife_name"/>
        </association>
    </resultMap>

完成!

补充一下:

上面xml文件中有一个statementType,它是用来标记在mapper文件中使用什么的对象操作SQL语句。 
要实现动态传入表名、列名,需要做如下修改 ,添加属性statementType=”STATEMENT” ,同时sql里的属有变量取值都改成${xxxx},而不是#{xxx}
取值说明: 
1、STATEMENT:直接操作sql,不进行预编译,获取数据:$—Statement 
2、PREPARED:预处理,参数,进行预编译,获取数据:#—–PreparedStatement:默认 
3、CALLABLE:执行存储过程————CallableStatement 

具体的使用网上自行查阅。

如果我的博客对你有帮助,欢迎进行评论✏️✏️、点赞👍👍、收藏⭐️⭐️,满足一下我的虚荣心💖🙏🙏🙏 。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值