我怎样才能在spring jdbcTemplate中实现分页

时间:2017-02-04 18:03:11

标签: java spring pagination jdbctemplate

这是我的以下dao实施

@Override
    public List<UserAddress> getAddresses(int pageid,int total) {

        String sql = "select * FROM user_addresses order by id desc limit "+(pageid-1)+","+total;
        List<UserAddress> userAddresses  = jdbcTemplate.query(sql, new RowMapper<UserAddress>() {
            @Override
            public UserSessionLog mapRow(ResultSet rs, int rowNum) throws SQLException {
                UserAddress userAdd = new UserAddress();
                userAdd.setId(rs.getInt("id"));
                userAdd.setId(rs.getString("city"));
                return userSession;
            }
        });
        return userAddresses;
    }

在上面的dao实现中,我列出了所有用户地址,试图列出限制

@RequestMapping("/userAddresses/{pageid}")
       public ModelAndView userAddresses(@PathVariable int pageid) {
        int total=5;  
        if(pageid==1){}  
        else{  
            pageid=(pageid-1)*total+1;  
        }  
         List<UserAddress> listAddresses = userAddressFacade.getAddresses(pageid,total);
         return new ModelAndView("userAddresses", "listAddresses", listAddresses);
    }

这是我的观点部分,

<table class="table table-condensed">
        <thead>
            <tr>
                <th>Address1</th>
                <th>City</th>
            </tr>
        </thead>
        <tbody>
            <c:if test="${not empty addresses}">
                <c:forEach var="address" items="${addresses}">
                    <tr>
                        <td>${address.address1}</td>
                        <td>${address.city}</td>
                    </tr>
                </c:forEach>
            </c:if>
        </tbody>
    </table>

     <br/>  
   <a href="/pro/userAddress/1">1</a>   
   <a href="/pro/userAddress/2">2</a>   
   <a href="/pro/userAddress/3">3</a>  

我已经对分页部分进行了硬编码,任何人都有想法,如何进行分页。我是java jdbcTemplate的新手,

4 个答案:

答案 0 :(得分:0)

我在寻找其他东西时碰到了这个问题,发现这个问题还没有得到答复,所以我想发布我的2cents。 您可以创建一个包含Pagination对象和pageId的包装(请求)对象。

请求

  • 分页分页
  • int pageId(任何与业务相关的数据/ SQL参数)
  • 任何域对象

分页

  • int start(用于在SQL中设置OFFSET属性)
  • int大小(用于在SQL中设置FETCH NEXT属性)

答案 1 :(得分:0)

只要您的数据库支持LIMIT和OFFSET,就可以完成此操作。给出了一个示例here。关键代码如下所示(您可以忽略流利的builder子句):

package com.domain;

import com.domain.Module;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class DemoRepository {
    private JdbcTemplate jdbcTemplate;

    @Autowired
    public DemoRepository(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public List<Demo> findDemo() {
        String querySql = "SELECT name, action, operator, operated_at " +
                "FROM auditing " +
                "WHERE module = ?";
        return jdbcTemplate.query(querySql, new Object[]{Module.ADMIN_OPERATOR.getModule()}, (rs, rowNum) ->
                Demo.builder()
                        .rowNum(rowNum)
                        .operatedAt(rs.getTimestamp("operated_at").toLocalDateTime())
                        .operator(rs.getString("operator"))
                        .action(rs.getString("action"))
                        .name(rs.getString("name"))
                        .build()
        );
    }

    public Page<Demo> findDemoByPage(Pageable pageable) {
        String rowCountSql = "SELECT count(1) AS row_count " +
                "FROM auditing " +
                "WHERE module = ? ";
        int total =
                jdbcTemplate.queryForObject(
                        rowCountSql,
                        new Object[]{Module.ADMIN_OPERATOR.getModule()}, (rs, rowNum) -> rs.getInt(1)
                );

        String querySql = "SELECT name, action, operator, operated_at " +
                "FROM auditing " +
                "WHERE module = ? " +
                "LIMIT " + pageable.getPageSize() + " " +
                "OFFSET " + pageable.getOffset();
        List<Demo> demos = jdbcTemplate.query(
                querySql,
                new Object[]{Module.ADMIN_OPERATOR.getModule()}, (rs, rowNum) -> Demo.builder()
                        .rowNum(rowNum)
                        .operatedAt(rs.getTimestamp("operated_at").toLocalDateTime())
                        .operator(rs.getString("operator"))
                        .action(rs.getString("action"))
                        .name(rs.getString("name"))
                        .build()
        );

        return new PageImpl<>(demos, pageable, total);
    }
}

答案 2 :(得分:0)

我同意@Erica Kane使用LIMIT和OFFSET。

但是,如果数据库不支持LIMIT和OFFSET,则可以使用ROW_NUMBER()

例如-
SELECT * FROM ( SELECT ROW_NUMBER() OVER(ORDER BY id) as RRN FROM user_addresses as T1 ) WHERE RRN between :start and :end; :start和:end您可以给出希望获取结果的任何数字。 1至100等
如果“行总数”少于结束号,那么它将仅返回存在的所有行。

我发现了一些有关ROW_NUMBER()的最佳链接,其中有很好的解释-

https://blog.sqlauthority.com/2011/08/12/sql-server-tips-from-the-sql-joes-2-pros-development-series-ranking-functions-rank-dense_rank-and-row_number-day-12-of-35/

https://blog.sqlauthority.com/2007/10/09/sql-server-2005-sample-example-of-ranking-functions-row_number-rank-dense_rank-ntile/

https://blog.sqlauthority.com/2008/03/12/sql-server-2005-find-nth-highest-record-from-database-table-using-ranking-function-row_number/

https://blog.sqlauthority.com/2015/09/03/sql-server-whats-the-difference-between-row_number-rank-and-dense_rank-notes-from-the-field-096/

答案 3 :(得分:-2)

您不必为分页创建自己的实现逻辑。使用Spring PagedListHolder,它适合并可配置用于分页目的。

您可以在此处看到示例实现:Spring Pagination Example