Maison  >  Article  >  Java  >  Comment utiliser Java pour implémenter la fonction de requête de pagination

Comment utiliser Java pour implémenter la fonction de requête de pagination

PHPz
PHPzavant
2023-05-10 17:40:141473parcourir

Requête de page

La requête de page affiche les énormes données de la base de données en segments. Chaque page affiche un nombre de lignes défini par l'utilisateur pour améliorer l'expérience utilisateur. La chose la plus importante est que toutes les données soient lues à partir du disque du serveur. la mémoire en même temps, Il y a un risque de débordement de mémoire

Paging vraie et fausse

Fausse pagination : Le principe est de lire toutes les données dans la mémoire et de tourner la page pour lire les données de la mémoire. Avantages : Simple. mise en œuvre, hautes performances Inconvénients : si les données sont volumineuses, il est facile de provoquer un débordement de mémoire. Véritable pagination : interrogez les données de la base de données (c'est-à-dire le disque) à chaque fois que la page est tournée. Avantages : Pas facile de provoquer un débordement de mémoire. Inconvénients : complexe. mise en œuvre, performances relativement faibles

Effet de pagination

Les fonctions de pagination générales comprennent : Page d'accueil Page précédente Page suivante Dernière page Quelle est la page actuelle Combien de pages au total Combien de lignes de données au total ? à ? Combien de données par page ? Nous devons interroger ces données et les encapsuler dans un objet, qui incarne l'idée d'encapsulation et économise beaucoup de code complexe

Comment utiliser Java pour implémenter la fonction de requête de pagination

Paramètres qui doivent être transmis. pour la pagination

Paramètres qui doivent être transmis par l'utilisateur :

currentPage : page actuelle, à quelle page accéder, lors de la première visite, nous créons un objet, la valeur par défaut est 1
pageSize : combien de lignes de données sont affichés sur chaque page. Pour la première fois, nous donnerons également une valeur par défaut, telle que 10.

Les données qui doivent être affichées en pagination

1. Quelle page est la page d'accueil

3. Quelle page est la page précédente ? 4. Quelle page est la page suivante ? 5. Combien de pages y a-t-il au total ? La valeur est la même que la dernière page. lignes) de données y a-t-il ? 7. La page actuelle est Quelle page
8. Combien d'informations sont affichées sur chaque page


La source des données qui doivent être affichées dans la pagination


provient du téléchargement de l'utilisateur. : page actuelle, combien de données sont affichées sur chaque page

provient d'une requête de base de données : nombre total de données, Les informations sur le produit qui doivent être affichées sur chaque page

sont calculées sur la base des informations connues ci-dessus : nombre total de pages , page précédente, page suivante

Écrivez l'instruction SQL interrogée à partir de la base de données



La première requête SQL dans la base de données Combien de données y a-t-il Il ne peut y avoir d'espaces après COUNT

SELECT COUNT(*) FROM 表名

La deuxième requête SQL ? page en fonction des paramètres transmis et de l'ensemble de résultats du nombre d'éléments de données sur une page

# 第一个 ?:从哪一个索引的数据开始查询(默认从 0 开始)
# 第二个 ?:查询多少条数据
SELECT * FROM 表名 LIMIT ?, ?
Ensuite, analysez les deux dans la deuxième source SQL Take Value :

Supposons qu'il y ait 21 éléments de données dans la table product ? , et chaque page est divisée en 5 éléments de données :

Interrogez la première page de données : SELECT * FROM product LIMIT 0, 5

Interrogez la deuxième page de données : SELECT * FROM product LIMIT 5, 5

Interrogez les données sur le troisième page : SELECT * FROM product LIMIT 10, 5

Interrogez les données sur la quatrième page : SELECT * FROM product LIMIT 15, 5

Découvrez en recherchant le modèle : La première valeur provient de (currentPage - 1) * pageSize ; la deuxième valeur ? vient de
pageSize, c'est-à-dire qu'elles proviennent toutes des paramètres de pagination transmis par l'utilisateur.


Nombre total de pages, page précédente et page suivante

// 优先计算总页数
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;

Mise en œuvre de la requête de page

Processus d'accès :

Encapsuler les données qui doivent être affichées

Comment utiliser Java pour implémenter la fonction de requête de paginationSi les données ne sont pas encapsulées , chaque donnée doit toutes être stockée dans le scope. Les données sont trop dispersées et peu pratiques pour une gestion unifiée

/**
* 封装结果数据(某一页的数据)
*/
@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;
    }
}

Couche de persistance DAO

La méthode de fonctionnement fournie par Mybatis ne peut transmettre qu'un seul paramètre pour exécuter la tâche SQL, et nous interrogeons maintenant les données d'une certaine page, nous devons connaître les deux paramètres de quelle page il s'agit et combien de données par page, nous devons donc encapsuler ces deux paramètres dans un objet

Écrivez une classe (nommée classe d'objet de requête) pour encapsuler ces données de requête

@Setter
@Getter
/**
* 封装分页查询需要的两个请求传入的分页参数
*/
public class QueryObject {
    private int currentPage = 1; // 当前页码,要跳转到哪一页的页码(需要给默认值)
    private int pageSize = 3; // 每页显示条数(需要给默认值)
}
Ensuite, écrivez l'interface DAO de la couche de persistance et la classe d'implémentation
//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;
}

Modifiez productMapper.xml

<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>

Modifiez QueryObject.java

Ajoutez la méthode getStart à cette classe et renvoyez la ligne à partir de laquelle la taille de chaque page doit être affichée à partir de la base de données en fonction de la page actuelle

@Setter
@Getter
/**
* 封装分页查询需要的两个请求传入的分页参数
*/
public class QueryObject {
    private int currentPage = 1; // 当前页码,要跳转到哪一页的页码(需要给默认值)
    private int pageSize = 3; // 每页显示条数(需要给默认值)
    // 用于 Limit 子句第一个 ? 取值
    public int getStart(){
        return (currentPage - 1) * pageSize;
    }
}

Couche métier ProductService

Appelez la couche de persistance DAO pour terminer la requête de données et encapsuler plusieurs données dans un seul objet

//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);
    }
}

Implémentation de la fonction de pagination frontale

1. Les composants de la couche métier doivent être complétés en premier pour garantir la réussite du test backend.

2. Suivez la réflexion MVC.

3. Le navigateur envoie les paramètres de requête de pagination (à quelle page accéder/combien de données par page), reçoit ces paramètres dans le servlet et les encapsule 4 Accédez à l'objet QueryObject et appelez la méthode de requête de pagination. (requête) dans le Service. 5. Partagez l'objet de résultat de requête de pagination obtenu (PageResult) dans la portée de la requête, accédez à JSP et affichez-le.

6. Modifiez la page JSP et écrivez les informations de la barre de pagination (les informations dans la barre de pagination proviennent de l'objet PageResult).



Modifiez ProductServlet.java et affichez jsp


1. Obtenez les paramètres de requête de page, déterminez qu'il s'agit d'une opération de requête, appelez la méthode de requête et obtenez les paramètres de pagination

2. Encapsulez les paramètres dans un objet de requête QueryObject

. 3. Appelez la méthode de la couche métier pour interroger une certaine page de données4. Stockez les résultats de la requête dans la portée5. Transférez vers la page d'affichage jsp

6. Retirez les résultats de la portée dans jsp et répondez au navigateur.

//创建业务层对象
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);
}

Modifiez le fichier jsp et utilisez JSTL+EL pour obtenir les données dans la portée
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
    <head>
        <title>产品列表</title>
        <script type="text/javascript">
            window.onload = function () {
                var trClzs = document.getElementsByClassName("trClassName");
                for(var i = 0; i < trClzs.length; i++){
                    trClzs[i].onmouseover = function () {
                        console.log(1);
                        this.style.backgroundColor = "gray";
                    }
                    trClzs[i].onmouseout = function () {
                        console.log(2);
                        this.style.backgroundColor = "";
                    }
                }
            }
            // 分页 JS
            function changePageSize() {
                document.forms[0].submit();
            }
        </script>
    </head>
    <body>
        <a href="/replaceImg.jsp" rel="external nofollow" ><img src="${USER_IN_SESSION.headImg}" title="更换头
        像"/></a><br/>
        <a href="/product?cmd=input" rel="external nofollow" >添加</a>
        <form action="/product">
            <table border="1" cellspacing="0" cellpadding="0" width="80%">
                <tr>
                    <th>编号</th>
                    <th>货品名</th>
                    <th>分类编号</th>
                    <th>零售价</th>
                    <th>供应商</th>
                    <th>品牌</th>
                    <th>折扣</th>
                    <th>进货价</th>
                    <th>操作</th>
                </tr>
                <c:forEach var="product" items="${pageResult.data}" varStatus="status">
                    <tr class="trClassName">
                        <td>${status.count}</td>
                        <td>${product.productName}</td>
                        <td>${product.dir_id}</td>
                        <td>${product.salePrice}</td>
                        <td>${product.supplier}</td>
                        <td>${product.brand}</td>
                        <td>${product.cutoff}</td>
                        <td>${product.costPrice}</td>
                        <td>
                            <a href="/product?cmd=delete&id=${product.id}" rel="external nofollow" >删除</a>
                            <a href="/product?cmd=input&id=${product.id}" rel="external nofollow" >修改</a>
                        </td>
                    </tr>
                </c:forEach>
                <tr align="center">
                    <td colspan="9">
                        <a href="/product?currentPage=1" rel="external nofollow" >首页</a>
                        <a href="/product?currentPage=${pageResult.prevPage}" rel="external nofollow" >上一页</a>
                        <a href="/product?currentPage=${pageResult.nextPage}" rel="external nofollow" >下一页</a>
                        <a href="/product?currentPage=${pageResult.totalPage}" rel="external nofollow" >尾页</a>
                        当前第 ${pageResult.currentPage} / ${pageResult.totalPage} 页
                        一共 ${pageResult.totalCount} 条数据
                        跳转到<input type="number" onchange="changePageSize()"
                        name="currentPage" value="${pageResult.currentPage}" 页
                        每页显示
                        <select name="pageSize" onchange="changePageSize()">
                            <option value="3" ${pageResult.pageSize == 3 ? &#39;selected&#39; : &#39;&#39;}> 3 </option>
                            <option value="5" ${pageResult.pageSize == 5 ? &#39;selected&#39; : &#39;&#39;}> 5 </option>
                            <option value="8" ${pageResult.pageSize == 8 ? &#39;selected&#39; : &#39;&#39;}> 8 </option>
                        </select>条数据
                    </td>
                </tr>
            </table>
        </form>
    </body>
</html>


FAQ

Si l'opération de tournage de page réussit et que vous ne pouvez pas tourner après quelques pages, vous ne pouvez tourner Tomcat qu'en redémarrant Problème : L'objet SqlSession n'est pas fermé dans DAO

.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer