페이지 쿼리는 데이터베이스의 방대한 데이터를 세그먼트로 표시합니다. 각 페이지는 사용자 경험을 향상시키기 위해 사용자가 정의한 수의 행을 표시합니다. 가장 중요한 것은 모든 데이터를 서버 디스크에서 읽어온다는 것입니다. 메모리가 한 번에 저장되면 메모리 오버플로의 위험이 있습니다
False 페이징: 모든 데이터를 메모리로 읽어들이고 페이지를 넘겨서 메모리에서 데이터를 읽는 것이 원칙입니다. 구현, 고성능 단점: 데이터가 크면 메모리 오버플로가 발생하기 쉽습니다
트루 페이징: 페이지를 넘길 때마다 데이터베이스(즉, 디스크)에서 데이터를 쿼리합니다. 장점: 메모리 오버플로가 발생하기 쉽지 않습니다. 단점: 복잡합니다. 구현, 상대적으로 낮은 성능
일반 페이징 기능은 다음과 같습니다. 홈 페이지 이전 페이지 다음 페이지 마지막 페이지 현재 페이지는 총 몇 페이지입니까? 데이터가 몇 행으로 이동합니까? 페이지당 데이터 조각 수는 얼마입니까? 이 데이터를 쿼리하여 객체로 캡슐화해야 합니다. 이는 캡슐화 아이디어를 구현하고 전달해야 하는 매개변수를 많이 절약합니다. 페이지 매김
사용자가 전달해야 하는 매개변수:
currentPage: 현재 페이지, 이동할 페이지, 첫 번째 방문, 객체 생성, 기본값은 1pageSize: 데이터 행 수 처음에는 10과 같은 기본값도 제공합니다.
페이징에 표시해야 하는 데이터
1. 현재 페이지의 상품 정보
8. 각 페이지에 몇 개의 정보가 표시되는지
페이징에 표시해야 하는 데이터의 소스는
사용자 업로드: 현재 페이지, 각 페이지에 표시되는 데이터 수
데이터베이스 쿼리에서 가져옴: 총 데이터 수, 각 페이지에 표시되어야 하는 제품 정보
는 위에서 알려진 정보를 기반으로 계산됩니다: 총 수 페이지, 이전 페이지, 다음 페이지
데이터베이스에서 쿼리한 SQL 문을 작성하세요
데이터베이스의 첫 번째 SQL 쿼리 COUNT 뒤에 공백이 있으면 안 됩니다
SELECT COUNT(*) FROM 表名두 번째 SQL 전달된 매개변수를 기반으로 어떤 페이지가 있는지, 한 페이지에 몇 개의 데이터가 있는지 쿼리한 다음, 두 번째 SQL에서 두 개를 분석해 보겠습니다. Take Value 소스:
제품 테이블에 21개의 데이터가 있고 각 데이터는 다음과 같습니다. 페이지는 5개의 데이터로 나뉩니다.
첫 번째 데이터 페이지 쿼리: SELECT * FROM product LIMIT 0, 5
두 번째 데이터 페이지 쿼리: SELECT * FROM product LIMIT 5, 5
네 번째 페이지의 데이터 쿼리: SELECT * FROM product LIMIT 15, 5 패턴을 찾아 발견: 첫 번째? 값은 (currentPage - 1) * pageSize에서 나옵니다. 값은 pageSize에서 가져옵니다. 즉, 모두 사용자가 전달한 페이징 매개변수에서 가져옵니다.
총 페이지 수, 이전 페이지 및 다음 페이지# 第一个 ?:从哪一个索引的数据开始查询(默认从 0 开始) # 第二个 ?:查询多少条数据 SELECT * FROM 表名 LIMIT ?, ?
페이지 쿼리 구현
액세스 프로세스:
표시해야 하는 데이터를 캡슐화합니다
데이터가 캡슐화되지 않은 경우 , 각 데이터를 모두 범위에 저장해야 합니다. 데이터가 너무 분산되어 통합 관리가 불편합니다// 优先计算总页数
int totalPage = rows % pageSize == 0 ? rows / pageSize : rows / pageSize + 1;
//上一页等于当前页-1,但不能超过1页界限
int prevPage = currentPage - 1 >= 1 ? currentPage - 1 : 1;
//下一页等于当前页+1,但不能超过总页数界限
int nextPage = currentPage + 1 <= totalPage ? currentPage + 1 : totalPage;
Mybatis에서 제공하는 작업 방법은 SQL 작업을 실행하기 위해 하나의 매개 변수만 전달하면 됩니다. 이제 특정 페이지의 데이터를 쿼리하고 있습니다. 어떤 페이지인지, 페이지당 데이터 조각 수를 알아야 합니다. 따라서 이 두 매개변수를 객체에 캡슐화해야 합니다. 쿼리 개체 클래스)를 사용하여 이러한 쿼리 데이터를 캡슐화합니다
/** * 封装结果数据(某一页的数据) */ @Getter public class PageResult<T> { // 两个用户的输入 private int currentPage; // 当前页码 private int pageSize; // 每页显示的条数 // 两条 SQL 语句执行的结果 private int totalCount; // 总条数 private List<T> data; // 当前页结果集数据 // 三个程序计算的数据 private int prevPage; // 上一页页码 private int nextPage; // 下一页页码 private int totalPage; // 总页数/末页页码 // 分页数据通过下面构造期封装好 public PageResult(int currentPage, int pageSize, int totalCount, List<T> data) { this.currentPage = currentPage; this.pageSize = pageSize; this.totalCount = totalCount; this.data = data; // 计算三个数据 this.totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1; this.prevPage = currentPage - 1 >= 1 ? currentPage - 1 : 1; this.nextPage = currentPage + 1 <= this.totalPage ? currentPage + 1 : this.totalPage; } }그런 다음 지속성 레이어 DAO 인터페이스 및 구현 클래스를 작성합니다
@Setter @Getter /** * 封装分页查询需要的两个请求传入的分页参数 */ public class QueryObject { private int currentPage = 1; // 当前页码,要跳转到哪一页的页码(需要给默认值) private int pageSize = 3; // 每页显示条数(需要给默认值) }Modify productMapper.xml
//DAO接口提供两个根据查询对象的查询方法 int queryForCount(); List<Product> queryForList(QueryObject qo); //DAO实现类 @Override //查询数据库总数据条数 public int queryForCount() { SqlSession session = MyBatisUtil.getSession(); int totalCount = session.selectOne("cn.xxx.mapper.ProductMapper.queryForCount"); session.close(); return totalCount; } @Override //查询某一页的结果集 public List<Product> queryForList(QueryObject qo) { SqlSession session = MyBatisUtil.getSession(); List<Product> products = session.selectList("cn.xxx.mapper.ProductMapper.queryForList",qo); session.close(); return products; }Modify QueryObject.java이 클래스에 getStart 메서드를 추가하고 행을 반환합니다. 현재 페이지를 기준으로 데이터베이스에서 페이지 크기를 표시해야 하는 경우
<select id="queryForCount" resultType="int"> SELECT COUNT(*) FROM product </select> <select id="queryForList" resultType="cn.xxx.domain.Product"> SELECT * FROM product LIMIT #{start}, #{pageSize} </select>비즈니스 레이어 ProductService
지속성 레이어 DAO를 호출하여 데이터 쿼리를 완료하고 여러 데이터를 하나의 개체로 캡슐화합니다
@Setter @Getter /** * 封装分页查询需要的两个请求传入的分页参数 */ public class QueryObject { private int currentPage = 1; // 当前页码,要跳转到哪一页的页码(需要给默认值) private int pageSize = 3; // 每页显示条数(需要给默认值) // 用于 Limit 子句第一个 ? 取值 public int getStart(){ return (currentPage - 1) * pageSize; } }Front- 최종 페이징 기능 구현
1. 백엔드 테스트를 통과하려면 먼저 비즈니스 계층 구성 요소를 완료해야 합니다.
2. MVC 사고방식을 따르세요.3. 브라우저는 페이징 요청 매개변수(이동할 페이지/페이지당 데이터 수)를 보내고 이 매개변수를 서블릿에서 수신하여 캡슐화합니다.
4. QueryObject 개체로 이동하여 페이징 쿼리 메서드를 호출합니다. (쿼리) 서비스에서.5. 획득한 페이징 쿼리 결과 객체(PageResult)를 요청 범위에서 공유하고 JSP로 점프하여 표시합니다. 6. JSP 페이지를 수정하고 페이징 바 정보를 작성합니다(페이징 바의 정보는 PageResult 객체에서 옵니다).
ProductServlet.java를 수정하고 jsp
1을 표시하고, 쿼리 작업인지 확인하고, 쿼리 메서드를 호출하고, 페이징 매개변수를 가져옵니다2. 매개변수를 쿼리 개체로 캡슐화합니다. 3. 데이터의 특정 페이지를 쿼리하는 비즈니스 레이어 메소드를 호출합니다
4. 쿼리 결과를 범위에 저장합니다5. 표시 페이지 jsp
6으로 결과를 가져오고 브라우저에 응답합니다.
//IProductService接口 public interface IProductService { /** * 完成查询某一页的业务逻辑功能 */ PageResult<Product> query(QueryObject qo); } //Service实现类 public class ProductServiceImpl implements IProductService { private IProductDAO productDAO = new ProductDAOImpl(); @Override public PageResult<Product> query(QueryObject qo) { // 调用 DAO 查询数据数量 int totalCount = productDAO.queryForCount(); // 为了性能加入判断,若查询的数据数量为 0,说明没有数据,返回返回空集合,即集合中没有 元素 if(totalCount == 0){ return new PageResult(qo.getCurrentPage(), qo.getPageSize(), totalCount, Collections.emptyList()); } // 执行到这里代表有数据,查询当前页的结果数据 List<Product> products = productDAO.queryForList(qo); return new PageResult(qo.getCurrentPage(), qo.getPageSize(), totalCount, products); } }
//创建业务层对象 private IProductService productService = new ProductServiceImpl(); protected void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { QueryObject qo = new QueryObject(); // 获取请求参数 currentPage,并转型封装 String currentPage = req.getParameter("currentPage"); if(StringUtil.hasLength(currentPage)) { qo.setCurrentPage(Integer.valueOf(currentPage)); } // 获取请求参数 pageSize,并转型封装 String pageSize = req.getParameter("pageSize"); if(StringUtil.hasLength(pageSize)) { qo.setPageSize(Integer.valueOf(pageSize)); } // 调用业务层方法来处理请求查询某一页数据 PageResult<Product> pageResult = productService.query(qo); // 把数据共享给 list.jsp req.setAttribute("pageResult", pageResult); // 控制跳转到 list.jsp 页面 req.getRequestDispatcher("/WEB-INF/views/product/list.jsp").forward(req, resp); }
페이지 넘김 작업이 성공하고 몇 페이지 후에 넘길 수 없으면 다시 시작해야만 Tomcat을 넘길 수 있습니다. 문제: SqlSession 개체가 DAO에서 닫히지 않습니다
위 내용은 Java를 사용하여 페이징 쿼리 기능을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!