NutzCN Logo
问答 Pager分页结果问题
发布于 2166天前 作者 laizhiming 2951 次浏览 复制 上一个帖子 下一个帖子
标签:

发现一个怪现象,同样的代码,就是切换一个数据源,第一页(首页)都是正常的,但是第二页开始分页效果达不到预期,第二页往后只显示一条数据。
场景是按每页20行数据获取数据
首先,这个在mysql数据库是正常的,生成的sql是第一页

select * from tablename limit 0,20

第二页

select * from tablename limit 20,20

debug跟了返回结果和显示是正常的。
debug跟的:
第一页:
dao.execute(sql)前pager是:size:20, total: 0, page: 1/0 (pageCount=0, pageNumber=1, pageSize=20, recordCount=0)
dao.execute(sql)后pager是:size:20, total: 0, page: 1/0 (pageCount=0, pageNumber=1, pageSize=20, recordCount=0)
第二页:
dao.execute(sql)前pager是:size:20, total: 0, page: 2/0 (pageCount=0, pageNumber=2, pageSize=20, recordCount=0)
dao.execute(sql)后pager是:size:20, total: 0, page: 2/0 (pageCount=0, pageNumber=2, pageSize=20, recordCount=0)
但是切换到hive2,数据表结构一模一样,就是数据源切换了一下,
生成的sql第一页

select * from tablename limit 0,20

第二页

select * from tablename limit 20,20

第一页显示正常,第二页开始往后只第一条,然后单独拿这个sql去手工查询数据库,返回的是20条记录。
debug跟的:
第一页:
dao.execute(sql)前pager是:size:20, total: 0, page: 1/0 (pageCount=0, pageNumber=1, pageSize=20, recordCount=0)
dao.execute(sql)后pager是:size:20, total: 20, page: 1/1 (pageCount=1(红色字体), pageNumber=1, pageSize=20, recordCount=20(红色字体))
第二页:
dao.execute(sql)前pager是:size:20, total: 0, page: 2/0 (pageCount=0, pageNumber=2, pageSize=20, recordCount=0)
dao.execute(sql)后pager是:size:20, total: 20, page: 2/1 (pageCount=1(红色字体), pageNumber=2, pageSize=20, recordCount=20(红色字体))

唯一找到的规律是,mysql的sql执行前后pager对象不变,hive2的sql执行后pager对象属性变了。
因为hive2的基本语法和mysql一样,所以默认用的是mysql的JdbcExpert。

不知道这个怎么修改呢?jdbc驱动包的问题吗?

22 回复

等等呀, pager的count是自行设置的, 用同一个pager查询多少次都不会有区别的

那个count我知道都是自己根据一个count(*)SQL单独跑出来的结果set值,但是奇怪就是mysql数据源的时候execute(sql)后page不变,但是hive数据源的时候execute(sql)后,pager对象属性值变了,第一页结果都是对的,后面的页sql.getList(Record.class)就只能获取到第一条数据了。

这样,你debug一下, 看看啥时候改了count, 只是execute的话, 不应该会改动的

跳到第二页,分页信息没更新?

来自炫酷的 NutzCN

@zozoh 跳到第二页pager是有变化的,就是dao().execute(sql)前后不一样,两个数据源,不清楚怎么回事,打印的sql也是对的。

@wendal @zozoh
debug跟了代码,发现在hive2数据源ResultSetLooping.doLoop(rs, context)方法第93行else if(rs.last())里通过LoopScope.eval(pager, rowCount)调用的pager.setRecordCount(recordCount)方法改变pager对象的pageCount和recordCount属性值的。
而mysql的数据源情况下是进到if(xxxx || (ResultSet.TYPE_FORWARD_ONLY == rs.getType()) == true ||xxxxx)不会进到else if(rs.last())里。

hive2的rs.getType() == ResultSet.TYPE_SCROLL_INSENSITIVE (1004)结果集的游标可以上下移动,当数据库变化时,当前结果集不变。

呀, 想不到是这里

我想想怎么改一下

@wendal 好的,多谢多谢,有劳兽总了,我也想想我们这边有没有临时解决的办法。

我这还没hive2重现, 麻烦debug一下 org.nutz.dao.impl.sql.run.NutDaoExecutor._runSelect(Connection, DaoStatement) 里面的 conn.createStatement, 看看传递的参数是什么

mysql:conn.createStatement(st.getContext().getResultSetType()=1003, ResultSet.CONCUR_READ_ONLY=1007)
hive2:conn.createStatement(st.getContext().getResultSetType()=1003, ResultSet.CONCUR_READ_ONLY=1007)
两者是一样的。

看来这驱动不按套路出牌...

然后我看spark4040控制台还发现,jdbc发送了两条一模一样的sql(select * from xxx limit 20,20)。

要不这样吧,你clone一下nutz的源码下来吧, 直接改改看

综合考虑,还是不能直接用咱们提供的Pager来做分页查询了,因为有些表的行数已经超出int范围了。

嗯, 这也是个办法

只能仿照Pager QueryResult自己简单写一下代码,以满足这边的分页需求。

可以这样, 自定义一个JdbcExpert, 继承MysqlJdbcExpert, 里面的formatQuery方法就是分页的

现在默认用的MysqlJdbcExpert可以满足了,formatQuery这个方法没有问题,主要就是execute(sql)的时候有问题。

@wendal 呃,HiveJdbcExpert拖了两年了。

添加回复
请先登陆
回到顶部