<script>
$(function(){
$('#dg').datagrid({
url: 'category_queryJoinAccount.action',
singleSelect: false, // 允許多選,支援批量刪除
pagination: true,
pageSize: 5,
pageList: [5,10,15,20],
idField: 'id',
toolbar: [
{iconCls:'icon-add', text:'添加分類', handler: addCategory},
'-',
{iconCls:'icon-edit', text:'更新分類', handler: editCategory},
'-',
{iconCls:'icon-remove', text:'刪除分類', handler: deleteCategories},
'-',
{text: "<input id='ss' name='search' />"} // 嵌入搜索框
]
});
// 初始化搜索框
$('#ss').searchbox({
searcher: function(value, name){
$('#dg').datagrid('load', {type: value}); // 重新加載第一頁
},
prompt: '請輸入搜索關鍵字'
});
});
</script>
function deleteCategories() {
var rows = $('#dg').datagrid('getSelections');
if (rows.length === 0) {
$.messager.show({title:'錯誤提示', msg:'至少選擇一筆記錄', timeout:2000, showType:'slide'});
return;
}
$.messager.confirm('刪除確認', '確定要刪除選中項嗎?', function(r){
if (!r) return;
// 拼接 IDs: "1,2,3"
var ids = rows.map(function(row){ return row.id; }).join(',');
$.post('category_deleteByIds.action', {ids: ids}, function(result){
if (result === "true") {
$('#dg').datagrid('uncheckAll'); // 清除選中狀態
$('#dg').datagrid('reload'); // 刷新當前頁
} else {
$.messager.show({title:'刪除異常', msg:'刪除失敗,請檢查操作', timeout:2000, showType:'slide'});
}
}, 'text');
});
}
public interface CategoryService extends BaseService {
List queryJoinAccount(String type, int page, int size);
Long getCount(String type);
void deleteByIds(String ids); // 核心方法
}
@Service("categoryService")
public class CategoryServiceImpl extends BaseServiceImpl implements CategoryService {
@Override
public void deleteByIds(String ids) {
// HQL 批量刪除,單條 SQL 執行
String hql = "delete from Category c where c.id in (" + ids + ")";
getSession().createQuery(hql).executeUpdate();
}
// 其他方法省略...
}
@Controller("categoryAction")
@Scope("prototype")
public class CategoryAction extends BaseAction {
@Resource CategoryService categoryService;
public String deleteByIds() {
categoryService.deleteByIds(ids); // ids 由 BaseAction 接收
// 返回純文本 "true" 給前端
inputStream = new ByteArrayInputStream("true".getBytes(StandardCharsets.UTF_8));
return "stream";
}
}
<package name="shop" extends="json-default">
<action name="category_*" class="categoryAction" method="{1}">
<result name="jsonMap" type="json"></result>
<result name="stream" type="stream">
<param name="inputName">inputStream</param>
</result>
</action>
</package>
@Controller("baseAction")
@Scope("prototype")
public class BaseAction extends ActionSupport implements ModelDriven, RequestAware, SessionAware, ApplicationAware {
protected String ids; // 接收前端拼接的 IDs
protected InputStream inputStream; // 流式響應輸出
// getter/setter 省略...
}
// 前端 searcher 回調
searcher: function(value, name) {
$('#dg').datagrid('load', {type: value}); // 參數自動合併到 queryParams
}
// 後端 Service
public List queryJoinAccount(String type, int page, int size) {
String hql = "from Category c left join fetch c.account where 1=1";
if (StringUtils.isNotBlank(type)) hql += " and c.type like :type";
Query query = getSession().createQuery(hql);
if (StringUtils.isNotBlank(type)) query.setParameter("type", "%" + type + "%");
query.setFirstResult((page-1)*size).setMaxResults(size);
return query.list();
}
| 環節 | 關鍵點 |
|---|---|
| 前端多選 | singleSelect: false + idField: 'id' + getSelections() |
| 批量刪除參數 | 前端拼接字串 "1,2,3",後端 HQL IN 子句 |
| 流式響應 | Action 返回 InputStream,Struts type="stream" 輸出 |
| 刷新策略 | reload() 保持當前頁,load() 重置第一頁 |
| 用戶體驗 | $.messager.confirm 二次確認 + uncheckAll 清除選中態 |
ids 直接拼接 SQL,生產環境必須校驗格式 (純數字+逗號) 或使用參數綁定 in (:ids) (需動態拼接佔位符)。IN 子句限制 1000 個表達式,需分批處理。@Transactional 保證原子性。cascade,否則拋異常。ByteArrayInputStream("true".getBytes("UTF-8")) 顯式指定編碼。DELETE /categories/batch?ids=1,2,3 + @DeleteMappingResult<Boolean> JSON 格式,棄用 stream 結果類型本文基於 SSH + EasyUI 技術棧,完整演示了 DataGrid 分類管理的查詢與批量刪除功能:前端工具欄配置、搜索框綁定、多選刪除確認流程、AJAX 异步调用、后端 HQL 批量删除、Struts 流式响应返回结果。掌握「前端選中行獲取 → ID 拼接 → 後端 IN 查詢 → 流式響應 → 前端刷新」這條核心鏈路,即可靈活應用於各類表格批量操作場景。建議新項目採用現代化技術棧重構,提升開發效率與維護性。