首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

JavaEE 分頁查詢終極優化:QueryHelper 鏈式構建 HQL,Action 層零 SQL

     編輯:Java 綜合教學

痛點回顧:Action 層寫 HQL 的維護噩夢

上一版優化抽取了頁碼顯示邏輯,但 Action 仍需手拼 HQL:條件查詢時需大量 if (param != null) hql += " and ...",參數位置易錯、可讀性差、擴展性極低。本文引入 QueryHelper,實現「鏈式構建 HQL + 參數自動綁定」,讓 Action 徹底告別 SQL 碎片。

一、前端進一步解耦:Form 替代 JS 跳轉

原頁面每個分頁鏈接需寫 JS 指定 xxx.action,現統一用 <form> 包裹查詢條件與分頁參數,提交即可:

<form id="pageForm" action="user_list.action" method="post">
  <!-- 查詢條件 -->
  <select name="deptId">...</select>
  <input name="name" />
  <input name="account" />
  <!-- 分頁隱藏域 -->
  <input type="hidden" name="page" />
  <input type="hidden" name="rows" />
</form>

// 頁碼鏈接只需設置 page 值並提交 form
<a href="javascript:;" onclick="$('#pageForm').find('[name=page]').val(3); $('#pageForm').submit();">3</a>

二、QueryHelper 核心設計:三段式 HQL + 參數列表

public class QueryHelper {
    private String fromClause;      // 必填:from User u
    private String whereClause = ""; // 選填:where u.dept.id = ? and u.name like ?
    private String orderByClause = ""; // 選填:order by u.createTime desc
    private List parameters = new ArrayList<>(); // 參數值列表,順序對應 ?

    // 構造器:傳入 from 子句
    public QueryHelper(String fromClause) { this.fromClause = fromClause; }

    // 鏈式添加 where 條件(自動處理 and/or)
    public QueryHelper addWhere(String condition, Object... params) {
        if (whereClause.isEmpty()) whereClause = " where " + condition;
        else whereClause += " and " + condition;
        Collections.addAll(parameters, params);
        return this; // 支持鏈式調用
    }

    // 條件式添加:參數為空/零/假時自動跳過,Action 層無需 if 判斷
    public QueryHelper addWhereIf(boolean condition, String hqlFragment, Object... params) {
        if (condition) addWhere(hqlFragment, params);
        return this;
    }

    // 同理 orderBy
    public QueryHelper addOrderBy(String orderBy) { ... }

    // 獲取完整查詢 HQL
    public String getQueryHql() { return fromClause + whereClause + orderByClause; }

    // 獲取統計總記錄 HQL(自動轉為 select count(*))
    public String getCountHql() { return "select count(*) " + fromClause + whereClause; }

    public List getParameters() { return parameters; }
}

三、Action 層極簡調用:一氣呵成

public class UserAction extends BaseAction {
    // 接收查詢條件(Struts2 自動注入)
    private String name;
    private String account;
    private Long deptId;
    // getter/setter 省略

    public String list() {
        QueryHelper qh = new QueryHelper("from User u")
            .addWhereIf(deptId != null, "u.dept.id = ?", deptId)
            .addWhereIf(StringUtils.isNotBlank(name), "u.name like ?", "%" + name + "%")
            .addWhereIf(StringUtils.isNotBlank(account), "u.account like ?", "%" + account + "%")
            .addOrderBy("u.createTime desc");

        // 一行代碼完成分頁查詢並壓入值棧
        pageBean = userService.getPageBean(page, rows, qh);
        return "list";
    }
}

四、極致封裝:QueryHelper 內建 Service 調用

連 service.getPageBean() 都可內移至 QueryHelper,Action 僅剩一行:

// QueryHelper 新增方法
public PageBean getPageBean(Service service, int page, int rows) {
    PageBean pb = service.getPageBean(page, rows, this);
    ActionContext.getContext().getValueStack().push(pb);
    return pb;
}

// Action 終極形態
public String list() {
    new QueryHelper("from User u")
        .addWhereIf(deptId != null, "u.dept.id = ?", deptId)
        .addWhereIf(StringUtils.isNotBlank(name), "u.name like ?", "%" + name + "%")
        .addWhereIf(StringUtils.isNotBlank(account), "u.account like ?", "%" + account + "%")
        .addOrderBy("u.createTime desc")
        .getPageBean(userService, page, rows);
    return "list";
}

五、總結:分頁優化演進路線圖

階段核心改進Action 代碼量適用場景
初版PageBean 封裝分頁數據手寫 HQL + 參數列表單一無條件查詢
中版抽取頁碼顯示標籤/JS手寫 HQL + 參數列表固定條件查詢
終極版(本文)QueryHelper 鏈式構建 + 條件式添加 + 內建 Service 調用極簡聲明式,零 SQL 碎片任意複雜條件/排序/多表關聯

至此,分頁查詢代碼結構清晰、擴展性強、極難出錯,新增列表頁面僅需關注「實體類、查詢條件、排序規則」三要素,真正實現「寫一次框架,處處復用」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved