承接前篇「在 Visual Web 應用中使用 JPA」,本文擴展 UserController 類別,新增 addUser、removeUser、updateUser 三個方法,並改造 Page1 頁面實現完整 CRUD 交互。
public boolean addUser(Users user) {
EntityManager em = getEntityManager();
try {
em.getTransaction().begin();
em.persist(user); // 使實體變為持久狀態
em.getTransaction().commit(); // 提交事務,寫入資料庫
return true;
} catch (Exception e) {
if (em.getTransaction().isActive()) em.getTransaction().rollback();
return false;
} finally {
em.close();
}
}
public boolean removeUser(Users user) {
EntityManager em = getEntityManager();
try {
em.getTransaction().begin();
Users managed = em.find(Users.class, user.getUserId()); // 依主鍵查找受管實體
if (managed != null) em.remove(managed);
em.getTransaction().commit();
return true;
} catch (Exception e) {
if (em.getTransaction().isActive()) em.getTransaction().rollback();
return false;
} finally {
em.close();
}
}
public boolean updateUser(Users user) {
EntityManager em = getEntityManager();
try {
em.getTransaction().begin();
Users managed = em.find(Users.class, user.getUserId());
if (managed != null) {
managed.setUsername(user.getUsername());
managed.setPassword(user.getPassword());
managed.setEmailAddress(user.getEmailAddress());
// 無需顯式 merge,受管實體修改自動同步
}
em.getTransaction().commit();
return true;
} catch (Exception e) {
if (em.getTransaction().isActive()) em.getTransaction().rollback();
return false;
} finally {
em.close();
}
}
關鍵點:事務邊界明確(begin/commit/rollback)、使用 find() 獲取受管實體、finally 區塊關閉 EntityManager。
mainContainer:頁面根容器,包含表格區與操作區。buttonPanel(3 欄):新增、刪除、修改按鈕。addUpdatePanel(2 欄):輸入欄位(用戶名、密碼、Email)+ 操作按鈕面板。addUpdateButtonPanel(2 欄):新增記錄/更新記錄按鈕。Table Layout 對話框新增欄位,類型選 Radio Button,表頭留白。radioButton1 的 selected、selectedValue、name 屬性至 Page1 Bean 對應屬性。tableColumn5.onClick = setTimeout('initAllRows()',0)、selectId = #{Page1.radioButton1.id}。tableRowGroup1.selected = #{Page1.selectedState} 同步選中狀態。<script>
function initAllRows() {
var table = document.getElementById("form1:table1");
table.initAllRows(); // 初始化所有行的單選按鈕狀態
}
</script>
private TableSelectPhaseListener tablePhaseListener = new TableSelectPhaseListener();
public void setSelected(Object obj) {
RowKey rk = (RowKey) getValue("#{currentRow.tableRow}");
if (rk != null) tablePhaseListener.setSelected(rk, obj);
}
public Object getSelected() { ... }
public Object getSelectedValue() { ... }
public boolean getSelectedState() { ... }
// 新增按鈕:顯示輸入面板
public String addButton_action() { addRequest = true; return null; }
// 修改按鈕:顯示輸入面板並預填資料
public String updateButton_action() { updateRequest = true; return null; }
// 刪除按鈕:直接刪除選中行
public String deleteButton_action() {
if (getTableRowGroup1().getSelectedRowsCount() > 0) {
RowKey[] keys = getTableRowGroup1().getSelectedRowKeys();
Users[] users = getSessionBean1().getUsers();
int rowId = Integer.parseInt(keys[0].getRowId());
new UserController().removeUser(users[rowId]);
}
return null;
}
// 新增記錄確認
public String addRecordButton_action() {
Users u = new Users();
u.setUsername((String) userNameField.getText());
u.setPassword((String) passwordField.getText());
u.setEmailAddress((String) emailAddressField.getText());
new UserController().addUser(u);
updateRequest = false;
return null;
}
// 更新記錄確認
public String updateRecordButton_action() {
RowKey[] keys = getTableRowGroup1().getSelectedRowKeys();
Users[] users = getSessionBean1().getUsers();
int rowId = Integer.parseInt(keys[0].getRowId());
Users u = users[rowId];
u.setUsername((String) userNameField.getText());
u.setPassword((String) passwordField.getText());
u.setEmailAddress((String) emailAddressField.getText());
new UserController().updateUser(u);
addRequest = false;
return null;
}
public void prerender() {
if (addRequest) {
showAddPanel();
} else if (updateRequest) {
if (hasSelection()) {
populateFieldsFromSelection();
showUpdatePanel();
}
} else {
addUpdatePanel.setRendered(false);
}
// 刷新 SessionBean 數據陣列,讓表格反映最新變更
getSessionBean1().updateUsers();
}
private void showAddPanel() {
addUpdatePanel.setRendered(true);
addRecordButton.setRendered(true);
updateRecordButton.setRendered(false);
clearFields();
}
private void showUpdatePanel() {
addUpdatePanel.setRendered(true);
addRecordButton.setRendered(false);
updateRecordButton.setRendered(true);
}
啟動專案後,頁面呈現專業級資料管理介面:
完整原始碼與截圖請參考 NetBeans 官方教學系列第二部分。