首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Java 實現二級聯動下拉選單:數據庫一對多查詢與 Map 數據結構組裝

     編輯:程式設計疑難解答

需求場景

前端兩個 ` SELECT p.id AS parent_id, p.name AS parent_name, c.id AS child_id, c.parent_id, c.name AS child_name FROM category_parent p LEFT JOIN category_child c ON p.id = c.parent_id ORDER BY p.id, c.id // 返回 List>,每行包含父子字段

3. Service 組裝邏輯 (關鍵步驟)

public Map> getChildMapByParentId() {
    List> rows = dao.selectAllWithChildren();
    
    // LinkedHashMap 保持父類順序
    Map> childMap = new LinkedHashMap<>();
    
    for (Map row : rows) {
        Integer parentId = (Integer) row.get("parent_id");
        // 父類可能無子類 (LEFT JOIN 導致 child_id 為 null)
        if (row.get("child_id") == null) {
            childMap.putIfAbsent(parentId, new ArrayList<>()); // 確保父類存在
            continue;
        }
        
        Child child = new Child();
        child.setId((Integer) row.get("child_id"));
        child.setParentId((Integer) row.get("parent_id"));
        child.setName((String) row.get("child_name"));
        
        // 核心:按 parentId 分組裝入 List
        childMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(child);
    }
    return childMap;
}

4. Controller 返回 JSON

@GetMapping("/categories")
public ResponseEntity> getCategories() {
    List parents = parentService.selectAll(); // 只查父類基本信息
    Map> childMap = categoryService.getChildMapByParentId();
    
    // 組裝樹形結構或分離返回 (前端易處理)
    Map result = new HashMap<>();
    result.put("parents", parents);
    result.put("childMap", childMap); // key=parentId, value=List
    return ResponseEntity.ok(result);
}

5. 前端 Vue/JS 渲染邏輯

// 1. 獲取數據
const { parents, childMap } = await api.getCategories();

// 2. 渲染一級下拉
parentSelect.innerHTML = parents.map(p => 
  ``
).join('');

// 3. 一級 change 事件更新二級
parentSelect.addEventListener('change', (e) => {
    const parentId = Number(e.target.value);
    const children = childMap[parentId] || [];
    childSelect.innerHTML = children.map(c => 
      ``
    ).join('');
    // 觸發二級 change 事件 (如有)
    childSelect.dispatchEvent(new Event('change'));
});

// 4. 初始化觸發一次
parentSelect.dispatchEvent(new Event('change'));

進階優化方案

場景優化策略
數據量大 (萬級父類)不組裝全量 Map,改為 按需 AJAX:一級 change 時請求 `/children?parentId=xxx`,後端單表查詢返回子類列表。
數據極少且極少變啟動時加載全量緩存到 Redis/本地內存,接口直接讀緩存,定時刷新。
樹形多級 (>2級)遞歸構建 TreeNode 結構,前端使用遞歸組件渲染 (如 Element UI el-cascader)。
頻繁增刪改引入緩存失效策略:更新 DB 後同步刪除/更新 Redis 中的 childMap。

總結

Java 實現二級聯動的核心是:**SQL 關聯查詢扁平化數據 → 內存中按 parentId 分組組裝 `Map>` → 前端按需篩選渲染**。此方案數據庫圓滾一次、內存組裝 O(n)、前端零延遲響應,適合中小數據量場景。大數據量轉為按需 AJAX 查詢。

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