基於 Struts2 + Spring + Hibernate(SSH)架構的電商後台,實現商品分類與管理員的級聯查詢及分頁展示。
CREATE TABLE category (
id INT PRIMARY KEY AUTO_INCREMENT,
type VARCHAR(20), -- 分類名稱
hot BOOLEAN DEFAULT FALSE, -- 是否熱門
account_id INT, -- 關聯管理員
CONSTRAINT fk_account FOREIGN KEY (account_id) REFERENCES account(id)
);
關係:Category 多對一 Account(一個分類屬於一個管理員)
// Category.java
@ManyToOne(fetch = FetchType.EAGER) // 級聯查詢時立即加載
@JoinColumn(name = "account_id")
public Account getAccount() { return account; }
// Account.java
@OneToMany(mappedBy = "account", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
public Set<Category> getCategories() { return categories; }
String hql = "from Category c where c.type like :type";
// 執行 1 條查分類 + N 條查管理員
@Override
public List<Category> queryJoinAccount(String type, int page, int size) {
String hql = "from Category c left join fetch c.account where c.type like :type";
return getSession().createQuery(hql)
.setString("type", "%" + type + "%")
.setFirstResult((page - 1) * size) // 起始行
.setMaxResults(size) // 頁大小
.list();
}
關鍵點:left join fetch 同時查詢關聯對象並填充到 Category.account,避免延遲加載產生額外 SQL。
setFirstResult((page-1)*size):跳過前 (page-1)*size 條記錄setMaxResults(size):最多返回 size 條記錄LIMIT/OFFSET 或 ROW_NUMBER()@Test
public void testQueryJoinAccount() {
List<Category> list = categoryService.queryJoinAccount("", 1, 2); // 第 1 頁,每頁 2 條
for (Category c : list) {
System.out.println(c + " -> " + c.getAccount()); // 直接訪問不觸發額外 SQL
}
}
ScrollableResults 流式處理