用Coldfusion分页

时间:2010-07-29 16:42:25

标签: mysql coldfusion pagination paginate

是否可以仅使用一个查询对Coldfusion中的页面进行分页和显示?

我的理解是你可以用一个查询进行分页,但是你需要一个额外的查询来创建页面。这是为了计算结果总数。

(currentPage - 1) * resultsPerPage = Offset in MySQL查询。这个逻辑足以创建next / prev按钮。但是为了知道页面数量,我们不需要知道使用单独查询的结果总数,然后查询数据查询吗?

9 个答案:

答案 0 :(得分:3)

在MS SQL中,使用CTE:

接收参数@startRow和@endRow以及你需要的参数

WITH qTemp AS (
   select *
   ,   count(*) as totCnt
   ,   rowNum = ROW_NUMBER() OVER(ORDER BY myIndex ASC)
   from myTable
   where (my where clause)
)
SELECT * FROM qTemp
WHERE rowNum BETWEEN @startRow AND @endRow

答案 1 :(得分:2)

是的,典型的基于mysql的方法需要两个查询:一个使用select count(*) from table,第二个使用select a, b, c from table limit x,y,其中x和y是根据当前页面和所需的偏移量构建的。

使用单个查询,您需要选择所有记录,这在大多数案例中效率较低。

答案 2 :(得分:2)

我对MySQL并不熟悉,但我知道在MS SQL中,存储过程可以返回多个结果集。

如果你不能这样做,你提出了两种方法,但第二种方法可以优化。

首先,运行两个查询。一个用于获取当前显示页面的数据,一个用于获取结果集的总大小。如果数据频繁更改,或者通常不显示多个页面,我会这样做。这需要两次db调用,但会减少返回的总大小。如果您没有频繁更改数据,但每个查询很少使用多个页面,您还可以缓存总结果计数。

第二种是在一个大查询中返回所有结果,并且只显示相应的页面。您不需要在此查询查询,因为使用cfloop和cfoutput的查询循环可以指定开始和结束查询行。如果你这样做,我会缓存查询。这会占用更多内存,第一页加载速度会变慢,但后续页面上的页面加载速度很快。

答案 3 :(得分:2)

您只需使用CFGrid即可显示整个结果集。分页被烘焙。以下是文档的链接:http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7baf.html

答案 4 :(得分:2)

我所做的是做“大”查询并将结果存储在SESSION范围内,然后对每个页面进行查询查询。对数据库的调用较少,这通常是瓶颈所在。

答案 5 :(得分:2)

这通常是我如何做到的。您可以通过执行子选择并对其进行别名来选择表的计数。您可以将其视为此查询中的第三个列。如果您愿意,这可以用于从另一个表中获取数据。它确实会导致MySQL在查询过程中启动另一个查询来汇总数据,但是coldfusion只需要询问数据库一次,使其比2次单独查询更快。

    <cfquery name="SomeQry" datasource="YourDatabase">
    SELECT 
    col1, 
    col2,
    (SELECT COUNT(*) FROM MyTable) as mycount
     FROM MyTable
     LIMIT #(CurrentPage * 20) - 20#, 20
</cfquery>

         <cfset start = CurrentPage - 5>
         <cfset Max = CurrentPage + 5>

        <cfoutput>
           <ul class="pagination">
               <cfloop from=#start# to=#Max# index="page">
                     <li><a href="/search?q=#querystring#&page=#page#">#page#</a></li>
            </cfloop>
          </ul>
        </cfoutput>

答案 6 :(得分:1)

我相信你可以做到:

SET @myCount = (SELECT COUNT(*) FROM tblName);

SELECT col1, col2, @myCount as 'total'
FROM tblName

在第二个查询中使用适当的分页内容。您将获得所返回集合中每条记录的计数,但这并不是什么大不了的事。我没有测试过这个,我没有MySQL。

答案 7 :(得分:1)

虽然这不是最好的方法,但这是旧学校的方式。

您可以使用cfoutput来完成此任务。

<cfquery name="q" dsn="#application.dsn">
SELECT
  firstname,
  lastname
FROM
  mytable
WHERE
  <some conditions>
</cfquery>

<cfparam name="url.maxrows" default="50">
<cfset url.maxrows = fix(val(url.maxrows))>
<cfparam name="url.startrow" default="1">
<cfset url.startrow = fix(val(url.startrow))>
<cfif url.startrow lte 0>
  <cfset url.startrow = 1>
</cfif>
<cfif url.startrow gte q.recordcount>
  <cfset url.startrow = q.recordcount>
</cfif>

<cfoutput>Total Records: #q.recordcount#/<cfoutput>

<cfoutput query="q" maxrows="#url.maxrows#" startrow="#url.startrow#">
  #firstname#<br/>#lastname#
</cfoutput>

<p>Page: 
<cfloop from="1" to="#q.recordcount#" step="#url.maxrows#" index="i">
  <a href="#cgi.script_name#?startrow=#i#&maxrows=#url.maxrows">#(i / url.maxrows)#</a>
</cfloop>
</p>

现在说实话......这个方法很糟糕,对于大型查询来说真的很慢。我个人使用CFWheels拥有所有这些东西built into it's ORM

答案 8 :(得分:1)

在MySQL中使用SQL_CALC_FOUND_ROWS。例如:

SELECT SQL_CALC_FOUND_ROWS * FROM tbl WHERE x = y LIMIT s,m

在您的查询后再次查询:

SELECT FOUND_ROWS() AS TotalRows

使用指令SQL_CALC_FOUND_ROWS会导致MySQL在应用限制和范围之前存储上次查询的总行数。这与在同一查询上执行Count()而不需要实际计算,然后查询,限制查询的开销相同。

在事务中包装两个db调用以确保它们连续执行。您可能还会考虑将查询抽象为一个函数,该函数将执行这两个操作并返回带有结果键和总行键的单个结构。使用上面引用的结果生成您认为合适的分页链接。