Mapper.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分页或收藏我是否缺少某些东西?
答案 0 :(得分:1)
我在您的代码中看到了一些问题:
ORDER BY
添加到SQL中。如果不存在,SQL将以 any 顺序返回行,并且该顺序可能/将随着时间而变化。我认为这是您代码中的严重错误。WHERE 1=1
。如果需要,MyBatis会在运行时自动删除第一个and
。这是您的映射器的修改版本:
<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>
答案 1 :(得分:0)
穿刺器具有有效点数。但它似乎并没有解决问题。
问题可以通过重写sql as discussed by Kazuki Shimizu解决。 基本上你必须限制一些内部/中间表,它们最终将代表从 MyBatis 映射器返回的实际实体。
或者如果您在数据库中没有很多条目,您可以在检索所有(!)项的同时在代码中实现分页。
public List<Item> getItems(Paging paging) {
List<Item> items = itemMapper.selectItems();
if (paging != null) {
items = items.stream()
.skip((long) paging.pageIndex * paging.pageSize)
.limit(paging.pageSize)
.collect(Collectors.toList());
}
return items;
}