论坛首页 Java版 iBATIS

spring、ibatis控制oracle分页的问题

浏览 6979 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
时间:2006-08-30
开发采用spring+ibatis,数据库用oracle,数据量有几千万以上,而且还要不断的增多,用了三层子查询实现分页控制

下面都只是举的例子

[code:1]
<sqlMap namespace="Y_wjlx">

<resultMap class="com.ctgusec.model.Y_wjlx" id="y_wjlx">
<result property="wjbh" column="wjbh" />
<result property="wjmc" column="wjmc" />
</resultMap>
<select id="getAllY_wjlx" resultMap="y_wjlx">
<![CDATA[
SELECT wjbh,wjmc FROM (SELECT row_.*, rownum rownum_ FROM (select wjbh,wjmc,rownum rn from y_wjlx) row_ WHERE rownum <= #end#) WHERE rownum_ > #start#
]]>
</select>

</sqlMap>
[/code:1]

用了个模型基类存储分页参数,模型类可以继承此类

[code:1]
public class BaseModel {

private Integer start = 0;

private Integer end = 30;

private Integer size = 30;

private Integer currentPage;

private Integer priviousPage;

private Integer nextPage;

public BaseModel() {

}
public BaseModel(Integer currentPage) {
if (currentPage > 0) {
this.currentPage = currentPage;
this.priviousPage = currentPage - 1;
this.nextPage = currentPage + 1;
this.start = priviousPage * size;
this.end = currentPage * size;
}
}

//省略geter、serter方法
}
[/code:1]

dao层:

[code:1]
public class SqlY_wjlxDao extends SqlMapClientDaoSupport implements IY_wjlxDao {

public List getAllY_wjlx(Y_wjlx y_wjlx) {

return this.getSqlMapClientTemplate().queryForList("getAllY_wjlx", y_wjlx);
}
}
[/code:1]

控制层:spring控制类实现分页

[code:1]
public class Y_wjlxListAllController extends AbstractController {

Integer currentPage ;

//y_wjlx类继承BaseModel类
Y_wjlx y_wjlx;

@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String page = request.getParameter("page");
if (page == null || page.equals("head")) {
currentPage=1;
y_wjlx = new Y_wjlx(currentPage);
request.getSession().setAttribute("currentPage", currentPage);
}
if ("privious".equals(page)) {
currentPage = (Integer) request.getSession().getAttribute("currentPage");
if(currentPage>1) currentPage -= 1;
y_wjlx = new Y_wjlx(currentPage);
request.getSession().setAttribute("currentPage", currentPage);
} else if ("next".equals(page)) {
currentPage = (Integer) request.getSession().getAttribute("currentPage");
currentPage += 1;
y_wjlx = new Y_wjlx(currentPage);
request.getSession().setAttribute("currentPage", currentPage);
}
List list = this.drv_Manager.getAllY_wjlx(y_wjlx);
return new ModelAndView("y_wjlxList", "list", list);
}

private IDrv_Manager drv_Manager;

public void setDrv_Manager(IDrv_Manager drv_Manager) {
this.drv_Manager = drv_Manager;
}
}[/code:1]

jsp页面分页调用
[code:1]
<button onclick="location.href = 'y_wjlxList.shtml?page=head'">首&&页</button>
&&
<button onclick="location.href = 'y_wjlxList.shtml?page=privious'">上一页</button>
&&
<button onclick="location.href='y_wjlxList.shtml?page=next'">下一页</button>
[/code:1]


实现了分页,而且前面的数据查询翻页效率很高,但是越到后面越慢(这个好象是没有办法的)

现在的问题是:
1、spring控制类太累赘,好象做了它不该做的事情,翻页控制有没有比较好的办法抽到服务层?
2、翻页也只有:首页、上页、下页;想把最后一页也弄出来,但是担心效率太低,首先要统计数据总数,还有就是三层子查询到了几千万数据后效率就慢了。
有没有比较好的解决办法?
   
时间:2006-08-30
这个帖子不知道发到哪个模块,斑竹觉得不适合在这里,请转到合适的模块,谢谢哈
   
0 请登录后投票
时间:2006-08-30
不知道偶是否有 没有说清楚的地方?

ps:不要转到回收站了哈
   
0 请登录后投票
时间:2006-08-30
这不是前台的问题,是数据库的SQL查询导致的。
你的SQL写的就是越往后查,第一个查询就返回越多的结果,可以找找网上Oracle的分页SQL代码。

不过记得也是差不多,最好可能只是利存储过程针对某些页(如:最前,最后)作了些逻辑判断的优化。
   
0 请登录后投票
时间:2006-08-30
liuyxit 写道
这不是前台的问题,是数据库的SQL查询导致的。
你的SQL写的就是越往后查,第一个查询就返回越多的结果,可以找找网上Oracle的分页SQL代码。

不过记得也是差不多,最好可能只是利存储过程针对某些页(如:最前,最后)作了些逻辑判断的优化。


谢谢您的回复

我知道查询速度不是前台的问题

我是想问能否把控制的业务逻辑抽象到业务层,使控制器只完成简单的控制转向并传送数据的任务
   
0 请登录后投票
时间:2006-08-30
Sorry,之前可能看漏了。

1.可以建一个Page类,大约是:
[code:1]public class Page {
private Integer currentPage;

private Integer priviousPage;

private Integer nextPage;

private Integer totalPage;

public Page(Integer currentPage) {
this.currentPage = currentPage;
this.priviousPage = currentPage - 1;
this.nextPage = currentPage + 1;

//省略其它逻辑...
}

//省略setter,getter...
}[/code:1]
在类中,处理分页的逻辑。

在DAO类中传入Page实例来构建查询条件。这样可以不涉及到模型层。

2.要有总页数,count是难免的,所以只有自己权衡是否有需要。一但有总记录数,分页就可以做到很灵活,比如自由设定一页的记录数和跳到第几页。
   
0 请登录后投票
时间:2006-08-30
liuyxit 写道

1.可以建一个Page类,大约是:
[code:1]public class Page {
private Integer currentPage;

private Integer priviousPage;

private Integer nextPage;

private Integer totalPage;

public Page(Integer currentPage) {
this.currentPage = currentPage;
this.priviousPage = currentPage - 1;
this.nextPage = currentPage + 1;

//省略其它逻辑...
}

//省略setter,getter...
}[/code:1]
在类中,处理分页的逻辑。
在DAO类中传入Page实例来构建查询条件。这样可以不涉及到模型层。


我试着改了下,您再看下,但是感觉非得在控制层保留session才可以,控制层还是很累赘。在DAO类中传入Page实例来构建查询条件好象也不能避免在控制层使用session,能提供点具体的么?
   
0 请登录后投票
时间:2006-08-30
控制层不用保留session吧!?就算要保留也不应该是因为分页的原因啊。

你只要在控制层把页面传过来的查询的页号(也可以说是当前页号)传到业务层就好了,其余的在业务层做。

逻辑代码是必定存在的,只是你想把它放到那里。我的意思是统一放到Page类中。
   
0 请登录后投票
时间:2006-08-30
liuyxit 写道
控制层不用保留session吧!?就算要保留也不应该是因为分页的原因啊。

你只要在控制层把页面传过来的查询的页号(也可以说是当前页号)传到业务层就好了,其余的在业务层做。

逻辑代码是必定存在的,只是你想把它放到那里。我的意思是统一放到Page类中。


我在页面不传入查询的页面参数,只传入一个标识参数page

也就是只能判断上下页,不能判断是第几页

每次请求都要调用wjlxListAllController , 初始化了模型类Y_wjlx

如果不保留Session就不能记忆点了多少个"下一页"了

您能否讲明白点?
   
0 请登录后投票
时间:2006-08-31
这种方式在每个sql语句中还是会出现rownum这个关键字,其实,rownum本生与业务没有关系的,这个问题应该由ibatis框架去解决,不知道为什么他不解决这个问题。如果能象hibernate一样,自动增加分页就好了。呵呵,估计得要改ibatis代码。。。
   
0 请登录后投票
论坛首页 Java版 iBATIS

跳转论坛:
JavaEye推荐