前几天同事遇到一个问题:ORM框架用的mybatisPlus,分页插件也用的mybatisPlus自带的分页插件,业务是分页查询每页展现十条数据,但测试环境每页展现的条数是随机的,第一页一条,第二页三条。。。,总之很诡异,具体页面以下 。看到这个问题感受仍是挺有趣的,但具体代码没有参与开发,也很差去直接帮忙去看,直到他把查询的xml文件发到群里,看了下文件这个查询用到了一对多,一下就知道缘由了(ps 之前踩过的坑啊,因此印象深入)。mysql
不少状况下会遇到列表页须要一对多查询,好比 查询列表页是展现各类手机信息,有一列是要展现这种手机全部的内存,好比华为P30有218G,256G,512G,咱们先重现下上面问题,具体的表结构和实体类以下sql
create table TF_L_PHONE数据库
(数据结构
ID VARCHAR(32) primary key comment 'ID',mybatis
PHONE_BRAND VARCHAR2(60) comment '手机品牌',oracle
PHONE_NAME VARCHAR2(60) comment '手机名称',框架
PHONE_CODE VARCHAR2(60) comment '手机编码',测试
PHONE_DESC VARCHAR2(240) comment '手机描述',编码
MARKET_TIME TIMESTAMP comment '手机上市时间'spa
) comment '手机主表';
create table TF_L_PHONE_RAM
(
ID VARCHAR(32) primary key comment 'ID',
PHONE_ID VARCHAR(32) comment '手机id',
PHONE_RAM number(4) comment '手机内存',
PHONE_FEE number(8) comment '手机价格 单位是分'
) comment '手机内存类型表';
手机主表够构造14条数据,每条手机构造了2-3条不等的内存表数据。xml文件以下,利用swagger作测试,查询第一页,每页查5条,返回的结果应该是total为14,返回数据5条,但结果倒是total为26,数据3条,我说下问题所在:咱们用的分页插件就是在咱们的sql外加上具体数据库对应的分页方式(oracle用 RowNum,mysql 用limit),分页查询的时候把每一条多侧的数据当成一条分页数据,那这样可能查出来的五条都对应同一条主表数据,那这时候映射事后就只有一条数据。记住是先分页查询后映射数据结构。
打出来的 sql SELECT * FROM ( SELECT TMP.*, ROWNUM ROW_ID FROM ( select t.ID, t.PHONE_BRAND, t.PHONE_NAME, t.PHONE_CODE, t.PHONE_DESC, t.MARKET_TIME ,PR.id PR_ID,PR.PHONE_ID PR_PHONE_ID,PHONE_RAM,PHONE_FEE from TF_L_PHONE t left JOIN TF_L_PHONE_RAM PR on t.ID = PR.PHONE_ID ) TMP WHERE ROWNUM <=5) WHERE ROW_ID > 0
{
"respCode": "0000",
"respDesc": "success",
"data": {
"page": 1,
"rows": 5,
"total": 26,
"totalPages": 6,
"results": [
{
"id": "100",
"phoneBrand": "荣耀",
"phoneName": "荣耀10",
"phoneCode": "RY10",
"phoneDesc": "荣耀10就是好",
"marketTime": "2019-09-05 11:11:51",
"phoneRamList": [
{
"id": "100",
"phoneId": 100,
"phoneRam": 124,
"phoneFee": 199900
},
{
"id": "101",
"phoneId": 100,
"phoneRam": 256,
"phoneFee": 199900
}
]
},
{
"id": "101",
"phoneBrand": "荣耀",
"phoneName": "荣耀20",
"phoneCode": "RY20",
"phoneDesc": "荣耀20就是好",
"marketTime": "2019-09-05 11:11:51",
"phoneRamList": [
{
"id": "110",
"phoneId": 101,
"phoneRam": 124,
"phoneFee": 199900
},
{
"id": "111",
"phoneId": 101,
"phoneRam": 256,
"phoneFee": 199900
}
]
},
{
"id": "104",
"phoneBrand": "华为",
"phoneName": "P20",
"phoneCode": "HWP20",
"phoneDesc": "华为P20就是好",
"marketTime": "2019-09-05 11:11:52",
"phoneRamList": [
{
"id": "125",
"phoneId": 104,
"phoneRam": 256,
"phoneFee": 299900
}
]
}
]
},
"extend": null
}
如今咱们知道问题的缘由了,那咱们怎么才能查到正确得一对多的分页结果呢,mybatis提供另外一种方式(我理解是子查询映射)xml文件和结果以下,问题完美解决。
{ "respCode": "0000", "respDesc": "success", "data": { "page": 1, "rows": 5, "total": 14, "totalPages": 3, "results": [ { "id": "100", "phoneBrand": "荣耀", "phoneName": "荣耀10", "phoneCode": "RY10", "phoneDesc": "荣耀10就是好", "marketTime": "2019-09-05 11:11:51", "phoneRamList": [ { "id": "100", "phoneId": 100, "phoneRam": 124, "phoneFee": 199900 }, { "id": "101", "phoneId": 100, "phoneRam": 256, "phoneFee": 199900 } ] }, { "id": "101", "phoneBrand": "荣耀", "phoneName": "荣耀20", "phoneCode": "RY20", "phoneDesc": "荣耀20就是好", "marketTime": "2019-09-05 11:11:51", "phoneRamList": [ { "id": "110", "phoneId": 101, "phoneRam": 124, "phoneFee": 199900 }, { "id": "111", "phoneId": 101, "phoneRam": 256, "phoneFee": 199900 } ] }, { "id": "102", "phoneBrand": "荣耀", "phoneName": "荣耀9", "phoneCode": "RY9", "phoneDesc": "荣耀9就是好", "marketTime": "2019-09-05 11:11:52", "phoneRamList": [ { "id": "120", "phoneId": 102, "phoneRam": 124, "phoneFee": 199900 }, { "id": "121", "phoneId": 102, "phoneRam": 256, "phoneFee": 299900 } ] }, { "id": "103", "phoneBrand": "华为", "phoneName": "P30", "phoneCode": "HWP30", "phoneDesc": "华为P30就是好", "marketTime": "2019-09-05 11:11:52", "phoneRamList": [ { "id": "122", "phoneId": 103, "phoneRam": 124, "phoneFee": 199900 }, { "id": "123", "phoneId": 103, "phoneRam": 256, "phoneFee": 299900 } ] }, { "id": "104", "phoneBrand": "华为", "phoneName": "P20", "phoneCode": "HWP20", "phoneDesc": "华为P20就是好", "marketTime": "2019-09-05 11:11:52", "phoneRamList": [ { "id": "125", "phoneId": 104, "phoneRam": 256, "phoneFee": 299900 } ] } ] }, "extend": null }