解决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 

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

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


版权声明:本文为H900302原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>