ホームページ  >  記事  >  Java  >  Javaを使用してページングクエリ機能を実装する方法

Javaを使用してページングクエリ機能を実装する方法

PHPz
PHPz転載
2023-05-10 17:40:141473ブラウズ

ページング クエリ

ページング クエリは、データベース内の膨大なデータをセグメントに表示します。ユーザー エクスペリエンスを向上させるために、各ページにはユーザー定義の行数が表示されます。最も重要なことは、データが読み取られたかどうかです。すべてのデータをサーバー ディスクに一度に出力します。メモリ オーバーフローの危険があります。

True および False ページング

False ページング: 原理は、すべてのデータをサーバー ディスクに読み込むことです。メモリを使用し、ページをめくってメモリからデータを読み取ります。 長所: シンプルな実装、高いパフォーマンス 短所: データが大きい場合、メモリ オーバーフローが発生しやすいです。
真のページング: データベース (つまり、ディスク) からデータをクエリします。ページをめくるたびに、利点: メモリ オーバーフローを引き起こすのは簡単ではありません。欠点: 実装が複雑で、パフォーマンスが比較的低いです。いくつかの

ページング効果

一般的なページング関数には次のようなものがあります。 ホーム ページ 前のページ 次のページページ 最後のページ 現在のページ数 合計ページ数 合計行数 データは何ページにジャンプしますか? 1 ページあたりのページ数 このデータをクエリして、アイデアを具体化するオブジェクトにカプセル化する必要があります。カプセル化を強化し、多くの複雑なコードを節約します

Javaを使用してページングクエリ機能を実装する方法

##ページングに渡す必要があるパラメータ##必要なパラメータユーザーによって渡されます:

currentPage: 現在のページ、どのページにジャンプするか、最初にアクセスするときにオブジェクトを作成します、デフォルト値は 1

pageSize: each 表示されるデータの行数

各ページに表示するデータ

1. の製品情報現在のページ

2. ホームページはどのページですか?

3. 前のページはどのページですか?
4. 次のページは何ページですか?
5. 合計ページは何ページありますか? ? 最後のページの値は同じです
6. データは全部で何個 (行) ありますか?
7. 現在のページは何ページですか?
8. データは何個ありますか?情報は各ページに表示されますか?

ページングに表示する必要があるデータのソース

ユーザーのアップロードから取得: 現在のページ、データの数

各ページに表示されるデータの総数、各ページに表示される製品情報

データベースクエリから取得:データの総数、各ページに表示される製品情報
上記の既知の情報の計算に基づいて取得:総ページ数、前ページ、次ページ

データベースからクエリする SQL ステートメントを作成します

データベース内の最初の SQL クエリデータはいくつありますか?COUNT の後にスペースを入れることはできません

SELECT COUNT(*) FROM 表名

2 番目の SQL は、渡されたパラメータと、1 ページに含まれるデータの数の結果セットに基づいてページをクエリします。

# 第一个 ?:从哪一个索引的数据开始查询(默认从 0 开始)
# 第二个 ?:查询多少条数据
SELECT * FROM 表名 LIMIT ?, ?

次にページを分析します。2 つの SQL のうち 2 つ? 値ソース:

product テーブルに 21 個のデータがあり、各ページが 5 つのデータに分割されているとします。
データの最初のページをクエリします: SELECT * FROM product LIMIT 0, 5
2 ページ目のデータのクエリ: SELECT * FROM product LIMIT 5, 5
3 ページ目のデータのクエリ: SELECT * FROM product LIMIT 10, 5
4 ページ目のデータのクエリ: SELECT * FROM product LIMIT 15, 5
ルールを検索すると、最初の? 値は (currentPage - 1) * pageSize から取得され、2 番目の? 値は
pageSize から取得されます。つまり、それらはすべてページングから取得されます。ユーザーによって渡されたパラメータ。

前ページと次ページの合計ページ数

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

ページング クエリの実装

アクセス プロセス:

Javaを使用してページングクエリ機能を実装する方法

#表示する必要があるデータをカプセル化する

データがカプセル化されていない場合は、各データをスコープに格納する必要があります。データが分散しすぎて一元管理するには不便です

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

Mybatisが提供する操作メソッドはパラメータを1つだけ渡してSQLを実行することができます。タスクを実行し、現在特定のページのデータをクエリしています。そのページがどのページであるか、およびページあたりのデータの数の 2 つのパラメータを知る必要があるため、これら 2 つのパラメータをオブジェクトにカプセル化する必要があります

Writeこれらのクエリ データをカプセル化するクラス (クエリ オブジェクト クラスという名前)

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

次に、永続層 DAO インターフェイスと実装クラスを記述します

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

Modify QueryObject .java

getStart メソッドをこのクラスに追加し、現在のページに基づいてデータベースから表示する必要がある各ページの行サイズを返します。

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

ビジネス レイヤー ProductService

永続層 DAO を呼び出してデータ クエリを完了し、複数のデータを 1 つのオブジェクトにカプセル化します

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

フロントエンド ページング関数の実装

1. バックグラウンド テストに合格するためには、最初にビジネス層コンポーネントを完了する必要があります。

2. MVC の考え方に従います。

3. ブラウザはページング リクエスト パラメータ (どのページに移動するか/ページあたりのデータの数) を送信し、これらのパラメータをサーブレットで受け取り、カプセル化します
4. QueryObject オブジェクトに対して、サービスのページング クエリ メソッド (クエリ)。
5. 取得したページングクエリ結果オブジェクト(PageResult)をリクエストスコープ内で共有し、JSPにジャンプして表示します。
6. JSP ページを変更し、ページング バーの情報を書き出します (ページング バーの情報は PageResult オブジェクトから取得されます)。

ProductServlet.java を変更し、jsp

1 を表示します。ページ リクエスト パラメータを取得し、クエリ操作であることを判断し、クエリ メソッドを呼び出し、ページング パラメータを取得します。

2. パラメータは QueryObject にカプセル化されます

3. ビジネス レイヤー メソッドを呼び出してデータの特定のページをクエリします
4. クエリ結果をスコープに保存します
5. 表示ページに転送しますjsp
6. jsp のスコープから結果を取得し、ブラウザに応答します

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

jsp ファイルを変更し、JSTL EL を使用してスコープ内のデータを取得します

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

# ##よくある質問#### ##

ページめくり操作は成功したが、数ページ後にめくれなくなった場合は、Tomcat を再起動することによってのみめくることができます。問題: SqlSession オブジェクトが DAO で閉じられていません

以上がJavaを使用してページングクエリ機能を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。