`
xugq035
  • 浏览: 36034 次
社区版块
存档分类
最新评论

一个通用分页查询方法

    博客分类:
  • J2EE
 
阅读更多
为了简化开发人员的代码,想写一个通用的分页查询方法,为了提交效率,其中有一段是分解hql语句,组成查询总数的hql语句,实现如下:
	public PaginationSupport findPageByQuery(final String hsql,final Object[] values,
			final int pageSize, final int startIndex) {
		return (PaginationSupport) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						String totalSql=null;
						if(hsql.toUpperCase().indexOf("SELECT")==-1)
							totalSql="SELECT COUNT(*) "+hsql.split("order by")[0].split("ORDER BY")[0];
						else if(hsql.toUpperCase().split("SELECT").length==2){
							totalSql=hsql.split("order by")[0].split("ORDER BY")[0];
							String[] tt=totalSql.split(" ");
							String colStr="",subStr="";int flag=1;
							for(int i=0;i<tt.length;i++){
								if(tt[i].equalsIgnoreCase("select"))continue;
								else if(tt[i].equalsIgnoreCase("from")){flag=2; continue;}
								else if(flag==1)colStr+=" "+tt[i];
								else subStr+=" "+tt[i];
							}
							totalSql="SELECT COUNT("+colStr.split(",")[0]+") FROM "+subStr;
						}
						Query totalQuery=null;
						if(totalSql!=null){
							totalQuery=session.createQuery(totalSql);
						}
						Query query = session.createQuery(hsql);
						if (values != null) {
	                        for (int i = 0; i < values.length; i++) {
	                        	if(totalQuery!=null) totalQuery.setParameter(i, values[i]);	                        	query.setParameter(i, values[i]);
	                        }
	                    }
						int totalCount=-1;
						if(totalQuery==null){
							if(pageSize>0)totalCount=query.list().size();
						}else{
							Object o=totalQuery.list().get(0);
							totalCount = (o==null?0:Integer.parseInt(o+""));
						}						if(startIndex>0) query.setFirstResult(startIndex);
						if(pageSize>0) query.setMaxResults(pageSize);

						List items = query.list();
						if(totalCount==-1) totalCount=items.size();
						PaginationSupport ps = new PaginationSupport(items,
								totalCount, pageSize, startIndex);
						return ps;

					}
				}, true);
	}



但是,在这个统计总数的hql会有问题,当数据表的主键包含多个字段的时候,最后生成的sql会变成count(pid,did),这样就会导致错误,如果有distinct时会更复杂,count(distinct pid,did),现在我只能添加个try,出现异常时调用query.list().size()去获取总数
对于通用的分页查询方法各位有什么好办法?
分享到:
评论
21 楼 sp42 2015-05-18  
douban
20 楼 xugq035 2009-08-17  
h521999 写道
建议lZ看看springside,学习一下SpringSide的分页方法吧.


多谢,以下是springside的源码。本质是一样,只是代码的优雅程度和处理方式有差别
    /**
     * HQL分页查询,可以指定具体的模式,
     * 采用getCount方式,须在此层完成hsql的转换与查询。
     * 注意参数Object...args的应用,可以在查询的设置查询条件用的(JDK5.0语法)
     */
    public Page pagedQuery(String hql, int pageNo, int pageSize, Object... args) {
        Assert.hasText(hql);
        Query query = getSession().createQuery(hql);
        for (int i = 0; i < args.length; i++) {
            query.setParameter(i, args[i]);
        }
            String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));
            List countlist = getHibernateTemplate().find(countQueryString, args);
            int totalCount = (Integer) countlist.get(0);
            return HqlPage.getPageInstanceByCount(query, pageNo, pageSize, totalCount);
    }

    /**
     * 去除select 子句,未考虑union的情况
     */
    private static String removeSelect(String hql) {
        Assert.hasText(hql);
        int beginPos = hql.toLowerCase().indexOf("from");
        Assert.isTrue(beginPos != -1, " hql : " + hql + " must has a keyword 'from'");
        return hql.substring(beginPos);
    }

    /**
     * 去除orderby 子句
     */
    private static String removeOrders(String hql) {
        Assert.hasText(hql);
        Pattern p = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*", Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(hql);
        StringBuffer sb = new StringBuffer();
        while (m.find()) {
            m.appendReplacement(sb, "");
        }
        m.appendTail(sb);
        return sb.toString();
    }
19 楼 xugq035 2009-08-17  
kjj 写道
感觉是把简单的事情复杂化!!!


这里的封装是复杂了,为的是给其他开发人员方便调用
18 楼 xugq035 2009-08-17  
grave 写道
xugq035 写道
jltest 写道
既然用hql还分解什么hql语句。明明就有现成的方法


可能你没看清我的主题,我的目的是“为了简化开发人员的代码”

也就是说开发人员作查询时只需要编写:
PaginationSupport findUser(){
  return findPageByQuery("from user",null,20,0);
}

就可以了,返回的是 PaginationSupport,里面封装了分页需要的数据,其中一项就是数据总数,所以要求对输入的hql语句作拆分

不得不说还是用criteria api吧


criteria我也封装了一个,这个处理好点,用rowCount()).uniqueResult()即可得到总数

	public PaginationSupport findPageByCriteria(
			final DetachedCriteria detachedCriteria, final int pageSize,
			final int startIndex) {
		return (PaginationSupport) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException {
						Criteria criteria = detachedCriteria
								.getExecutableCriteria(session);
						int totalCount = ((Integer) criteria.setProjection(
								Projections.rowCount()).uniqueResult())
								.intValue();
						criteria.setProjection(null);
						List items = criteria.setFirstResult(startIndex)
								.setMaxResults(pageSize).list();
						PaginationSupport ps = new PaginationSupport(items,
								totalCount, pageSize, startIndex);
						return ps;
					}
				}, true);
	}
17 楼 src_bord 2009-08-17  
   这种做法挺好的 呵呵~把分页的变量多封装在一个pages类里边  这一来在页面就要省好多事了~
16 楼 grave 2009-08-16  
xugq035 写道
jltest 写道
既然用hql还分解什么hql语句。明明就有现成的方法


可能你没看清我的主题,我的目的是“为了简化开发人员的代码”

也就是说开发人员作查询时只需要编写:
PaginationSupport findUser(){
  return findPageByQuery("from user",null,20,0);
}

就可以了,返回的是 PaginationSupport,里面封装了分页需要的数据,其中一项就是数据总数,所以要求对输入的hql语句作拆分

不得不说还是用criteria api吧
15 楼 inputer 2009-08-16  
这样的代码懒散的我,没办法看下去了.
14 楼 h521999 2009-08-16  
建议lZ看看springside,学习一下SpringSide的分页方法吧.
13 楼 kjj 2009-08-16  
感觉是把简单的事情复杂化!!!
12 楼 xugq035 2009-08-16  
我举的这个例子findUser返回的是一个PaginationSupport对象,里面封装了总数、数据、开始记录、每页记录数等。可能改称findUserList这样会容易看一些
至于这个代码不好看,现在我想到的只有拆hql语句的办法,开这个贴就是为了把需求提出来探讨一下有哪些更好的方法
11 楼 dch1287 2009-08-16  
findUser 返回的不是 User or Users ?

代码写的 真的不好看 。。

hql分页怎么会封装得如此 。。

为什么同样的回复要submit这么多次 ?
10 楼 xugq035 2009-08-15  
myworkfirst 写道
  hq 还要自己写分页吗? 都提供了分页机制。


我这里就是利用了分页机制封装了一下,方便下面的程序员调用

也就是说开发人员作查询时只需要编写:
PaginationSupport findUser(){
  return findPageByQuery("from user",null,20,0);
}
返回的是 PaginationSupport,里面封装了分页需要的数据,其中一项就是数据总数
9 楼 xugq035 2009-08-15  
317082755 写道
这样的分页没必要写啊


可能你没看清我的主题,我的目的是“为了简化开发人员的代码”

也就是说开发人员作查询时只需要编写:
PaginationSupport findUser(){
  return findPageByQuery("from user",null,20,0);
}
就可以了,返回的是 PaginationSupport,里面封装了分页需要的数据,其中一项就是数据总数,所以要求对输入的hql语句作拆分
8 楼 xugq035 2009-08-15  
sjynt131 写道
统一取list.size()吧


从后台输出的sql语句看这样其实是作了一次查询所有记录的操作,比较耗资源;我的想法是改为count效率会高很多
7 楼 xugq035 2009-08-15  
flysunsystem 写道
浪费手续。就这样个方法还通用?个人认为最好的办法就是建立一个Page对象。有不明白的可以问。


可能你没看清我的主题,我的目的是“为了简化开发人员的代码”

也就是说开发人员作查询时只需要编写:
PaginationSupport findUser(){
  return findPageByQuery("from user",null,20,0);
}

就可以了,返回的是 PaginationSupport就是你说的一个Page对象,里面封装了分页需要的数据,其中一项就是数据总数,所以要求对输入的hql语句作拆分

另外,应该你有不明白的可以问~~
6 楼 xugq035 2009-08-15  
jltest 写道
既然用hql还分解什么hql语句。明明就有现成的方法


可能你没看清我的主题,我的目的是“为了简化开发人员的代码”

也就是说开发人员作查询时只需要编写:
PaginationSupport findUser(){
  return findPageByQuery("from user",null,20,0);
}

就可以了,返回的是 PaginationSupport,里面封装了分页需要的数据,其中一项就是数据总数,所以要求对输入的hql语句作拆分
5 楼 myworkfirst 2009-08-11  
  hq 还要自己写分页吗? 都提供了分页机制。
4 楼 317082755 2009-08-11  
这样的分页没必要写啊
3 楼 sjynt131 2009-08-10  
统一取list.size()吧
2 楼 flysunsystem 2009-08-10  
浪费手续。就这样个方法还通用?个人认为最好的办法就是建立一个Page对象。有不明白的可以问。

相关推荐

    java一个通用的分页方法

    下面,我们将深入探讨一个Java通用分页方法的实现细节,以及如何在实际项目中运用这一技术。 #### 分页类`Pager`详解 `Pager`类是整个分页逻辑的核心。它包含了分页所需的所有属性和方法,如总行数、每页显示的...

    java 通用分页 java 通用分页

    在本文中,我们使用了一个名为GetRecordFromPage的存储过程,这个存储过程可以根据需要进行分页处理。 4. 存储过程GetRecordFromPage GetRecordFromPage存储过程是我们实现分页处理的核心部分。这个存储过程接受多...

    通用分页方法

    在上面的代码中,我们创建了一个名为`PagingDal`的类,其中有一个方法`GetPagedData`,它接受页码和每页大小作为输入,然后使用ADO.NET连接到数据库,执行存储过程并返回结果。注意,`YourDataType`应替换为实际数据...

    使用SQL语句实现通用分页查询

    使用SQL语句实现通用分页查询,支持模糊查询等。

    超强php分页打包 通用分页 万能分页 ajax分页 google分页

    通用分页则是指设计一个可以适应多种场景的分页组件,它可能包含以下特性: 1. 参数化配置:允许用户自定义每页显示的记录数。 2. URL路由处理:支持参数传递,如通过`?page=2`来表示第2页。 3. 多种样式支持:提供...

    java通用分页代码实例.rar

    一个通用的分页组件可能包含以下几个关键部分: - 分页参数:存储每页大小、当前页码等信息。 - 分页查询接口:定义分页查询的方法,接受分页参数并返回分页结果。 - 数据源适配器:根据不同的数据库实现具体的...

    通用分页方法接口.rar

    通用分页方法接口的设计旨在提供一种标准化的、可复用的解决方案,使得不同的数据访问层(如数据库查询、API调用等)都能够方便地进行数据分页操作。下面我们将详细探讨这个主题。 一、分页的基本概念 分页是指将...

    JAVA写的通用分页

    本文将详细探讨"JAVA写的通用分页"这一主题,结合描述中的"通用高效分页存储过程实现",我们将深入理解Java分页的原理、实现方式以及优化策略。 首先,分页的基本概念是将大量数据分块展示,而不是一次性加载所有...

    asp.net通用分页类

    在实际使用中,这个分页类可以作为一个独立的服务或者工具类,接收数据源(如SQL查询、EF实体查询等)和分页参数,返回分页后的数据和相关信息,例如当前页、总页数等。这样,无论在哪个页面需要分页,只需调用此...

    sql Server 通用分页存储过程

    sql Server 通用分页存储过程 sql Server 通用分页存储过程 sql Server 通用分页存储过程 sql Server 通用分页存储过程

    Mybatis通用分页插件

    Mybatis通用分页插件通过自动处理分页参数,极大地简化了这一过程。 该插件的核心功能包括: 1. **智能分页**:根据不同的数据库(如MySQL、Oracle、SQL Server等)自动生成对应的分页SQL,无需手动编写LIMIT或...

    通用分页的使用方法以及原理

    在具体实现中,PageMethod类通常会有一个方法用于获取当前页的数据,该方法可能调用存储过程以提高效率。存储过程接收表名、查询条件等参数,返回符合要求的分页数据。同时,PageMethod还有一个方法用于计算数据库表...

    hibernate通用分页

    总的来说,"hibernate通用分页"是一个提高开发效率的实用工具,它封装了分页查询的逻辑,使得开发者能更专注于业务逻辑,同时保持代码的整洁和可维护性。通过`Pagehelp`和`Page`类的设计,可以轻松地在不同的查询...

    sturts +hernate+ spring分页通用方法

    一个通用的SSH分页方法通常包含以下步骤: 1. **前端请求**:用户在页面上进行分页操作,如点击页码或设置每页显示数量,这些参数通过HTTP请求发送到服务器。 2. **Struts接收与处理**:在Struts的Action中,解析...

    springmvc+mybatis通用分页

    7. **通用分页**:为了实现通用性,我们可以创建一个基类,包含分页参数,然后让所有需要分页的Service继承这个基类。这样,我们只需要在Controller中传入分页参数,Service层就可以自动处理分页逻辑。 8. **返回...

    SSH通用分页组件 SSH分页

    SSH分页 分页 通用分页 struts2分页

    SSM 实现通用分页

    在Service层,我们可以创建一个通用的分页方法,接受页码和每页大小作为参数,然后调用MyBatis的Mapper进行分页查询。返回的Page对象则可以通过Struts2的Action传递给前端展示。 前端页面上,用户可以通过导航按钮...

    java 通用数字分页

    本主题主要讲解如何在Struts2中实现一个通用的数字分页功能。 首先,我们要理解分页的基本概念。分页是将大量数据分成若干页进行显示,用户可以通过点击页码或使用导航按钮来切换不同页。分页通常涉及两个关键参数...

    通用的CUDR及通用分页

    1. **连接管理**:通用DAO会提供一个接口或方法,如`setConn(Connection conn)`,用于设置数据库连接。这允许开发者根据实际项目需求,使用自定义的DBHelper(数据库帮助类)来获取数据库连接。 2. **CRUD操作**:...

    jsp通用分页

    总结来说,`jsp通用分页`的核心是利用JDBC的滚动结果集和数据库的分页特性,结合适当的接口设计,实现一个跨数据库的分页机制。这既要求对JDBC和数据库有深入理解,也需要考虑代码的灵活性和性能优化。

Global site tag (gtag.js) - Google Analytics