java - Mybatis RowBounds 与 resultMap 内的集合不返回预期结果
问题描述
映射器.xml
<resultMap id="resultMap" type="dBWrapper">
<result property="id" column="id" />
<result property="code" column="code" />
<result property="description" column="description" />
<collection property="orderIds" ofType="java.lang.Long" >
<result column="orderId" />
</collection>
</resultMap>
<select id="selectAllProducts" resultMap="resultMap" parameterType="dBWrapper">
SELECT product.id, product.code, product.description, provider.providerName, order.orderId
FROM Product product
LEFT JOIN Order order on product.id = order.productId
WHERE 1=1
<if orderSearchId != ''>
and order.orderId = #{orderSearchId}
</if>
</select>
为检索分页列表而编写的 Java 代码:
productList = productMapper.selectAllProducts(searchObj, new RowBounds((searchObj.getPage() - 1) * searchObj.getTotal(), searchObj.getTotal()));
这样对于具有 3 条记录的第 1 页,使用 RowBounds(0, 3) 调用它。对于第 2 页,它使用 RowBounds(3, 3) 调用,对于第 3 页 RowBounds(6, 3)。
mybatis日志中对上述函数的SQL查询返回如下
id code description orderId
-------------------------------------------
1 101 Samolina 200
1 101 Samolina 201
2 102 Trampoline 300
2 102 Trampoline 301
2 102 Trampoline 302
2 102 Trampoline 303
3 103 Pajar 401
3 103 Pajar 402
4 104 Tramtor 500
4 104 Tramtor 501
4 104 Tramtor 502
5 105 Wadnor 600
5 105 Wadnor 601
5 105 Wadnor 602
5 105 Wadnor 603
6 106 Bramget 701
6 106 Bramget 702
但是mybatis在应用分页和收集的时候,在第一页就看到了下面的记录(没问题)。
id code description orderIds
-------------------------------------------
1 101 Samolina (200,201)
2 102 Trampoline (300,301,302,303)
3 103 Pajar (401,402)
因此对于第二页,记录应该从 id = 4 开始。但是,这是 mybatis 为第二页返回的内容。
id code description orderIds
-------------------------------------------
2 102 Trampoline (301,302,303)
3 103 Pajar (401,402)
4 104 Tramtor (500,501,502)
现在,如果您查看实际查询返回的数据库,第 4 条记录如下。这就是第二页真正开始的地方。请注意第 2 页的第一条记录中缺少 300 的 orderId。这是因为 orderId = 300 是实际查询中的第三条记录,因此不包括在内。
id code description orderId
-------------------------------------------
2 102 Trampoline 301
关于 mybatis 分页或集合,我有什么遗漏吗?
解决方案
我在您的代码中看到了一些问题:
- 如果您使用分页,则需要添加
ORDER BY
到您的 SQL。当不存在时,SQL 以任何顺序返回行,并且该顺序可能/将随时间改变。我认为这是您的代码中的一个严重错误。 - 此外,强烈建议在封闭实体的某些属性上指定 <id> 标记。否则它会变得非常缓慢。
- 此外,使用 < where > 子句代替
WHERE 1=1
.and
如果需要,MyBatis 会在运行时自动删除第一个。
这是您的映射器的修改版本:
<resultMap id="resultMap" type="dBWrapper">
<id property="id" column="id" /> <!-- I used ID here -->
<result property="code" column="code" />
<result property="description" column="description" />
<collection property="orderIds" ofType="java.lang.Long" >
<result column="orderId" />
</collection>
</resultMap>
<select id="selectAllProducts" resultMap="resultMap" parameterType="dBWrapper">
SELECT product.id, product.code, product.description,
provider.providerName, order.orderId
FROM Product product
LEFT JOIN Order order on product.id = order.productId
<where>
<if test="orderSearchId != null">
and order.orderId = #{orderSearchId}
</if>
</where>
ORDER BY product.id, order.id
</select>
推荐阅读
- python - 树莓派 4 上的 Waveshare PN532 NFC 帽子
- mysql - mysql不允许在插入查询中使用转义字符
- html - 如何在 vue js 中添加 css 和 html 就像在单独的文件中添加角度 css、html 和 typescript
- sql-server - 在 SQL 中检查 NULL 值
- heremaps-android-sdk - HERE Maps(Android)如何使路线可选择?
- postgresql - 自定义序列 - Postgres
- angular - ng2 google chart - 当我将鼠标悬停时,注释标签从图表的底部移动到中心
- mysql - sql中REPLACE语句和主键的问题
- postgresql - 如何将 Kind 中的 pod 与本地数据库连接
- css - 为什么从桌面更改为移动大小时我的导航栏会短暂显示?