void delete() {
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1/eric", "jlu", "newpasswd");
stmt = conn.createStatement();
String dSQL = "delete from Product where id=" + num.value;
if (stmt.executeUpdate(dSQL) <= 0)
throw new SQLException("資料刪除失敗");
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 下列兩個敘述的順序不可以對調
// 確保刪除的資料也從 box 和 allItems 內消失
allItems.remove(box.getSelectedIndex());
box.removeItemAt(box.getSelectedIndex());
clearData();
}
void clearData(){
// 清除輸入欄位
num.value = null;
name.value = null;
price.value = null;
qty.value = null;
}
從程式碼中,我們可以清楚的看出,資料刪除分成三個動作:第一個動作
就是把使用者選擇的 Product 物件從資料庫中刪除(其中包含資料庫的連結
以及 SQL 的 delete 指令);第二個動作就是把使用者選擇的 Product 物件從
allItems 以及 box 中刪除;刪除的方式是利用 Listbox 物件的 getSelectedIndex()
來決定該物件的索引位置,然後分別利用 remove(索引位置) 和 removeItemAt(索引位置)
把該物件從 allItems 和 box 刪除;第三個動作就是把輸入欄位的值清除,
由於這一段程式碼跟 add() 重複,為了降低維護成本,我們將這個動作的
四個敘述包成一個 clearData() 方法,然後在 delete() 以及 add() 的最後
呼叫該方法。(請記得將 add() 方法做適當的修改)
以下的執行畫面為將之前 ccc 的資料刪除後的結果:
<?xml version="1.0" encoding="Big5"?>
<window title="存貨管理系統" width="640px" border="normal" mode="highlighted">
<zscript>
// 除了方法的部分,其他的部分只會執行一次
import java.sql.*;
import java.util.*;
Statement stmt = null;
Connection conn = null;
List allItems = new ArrayList();
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1/eric", "jlu", "newpasswd");
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from Product");
Product p;
while(rs.next()) {
p = new Product();
p.setId(rs.getInt(1));
p.setName(rs.getString(2));
p.setPrice(rs.getDouble(3));
p.setQty(rs.getInt(4));
allItems.add(p);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 資料新增 ==========================================================
void add() {
// 確保新增的資料也在 allItems 內
Product newp = new Product(num.value.intValue(), name.value,
price.value.doubleValue(), qty.value.intValue());
allItems.add(newp);
// 經資料新增至資料庫
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1/eric", "jlu", "newpasswd");
stmt = conn.createStatement();
String iSQL = "insert into Product values(" + num.value + ",'" +
name.value + "'," + price.value + "," + qty.value + ")";
if (stmt.executeUpdate(iSQL) <= 0)
throw new SQLException("資料新增失敗");
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 將新增資料形成一個 Listitem 物件(或者節點)
Listitem li = new Listitem();
li.setValue(newp); // 在之後的 update, delete 會用到
li.appendChild(new Listcell(num.value.toString()));
li.appendChild(new Listcell(name.value));
li.appendChild(new Listcell(price.value.toString()));
li.appendChild(new Listcell(qty.value.toString()));
// 將 Listitem 物件變成 box 的子節點
// box 是 listbox 的 id 值
box.appendChild(li);
// 清除輸入欄位
clearData();
}
// 資料修改 ==========================================================
void move() {
// 確保修改的資料也在 allItems 內
Product p = (Product) box.selectedItem.value;
num.value = p.getId();
name.value = p.getName();
price.value = new java.math.BigDecimal(p.getPrice());
qty.value = p.getQty();
}
// update()
void update(){
// 修改 box 和 allItems 物件的內容
Product upp = (Product) box.selectedItem.value;
upp.setId(num.value.intValue());
upp.setName(name.value);
upp.setPrice(price.value.doubleValue());
upp.setQty(qty.value.intValue());
allItems.set(box.getSelectedIndex(), upp);
// 修改資料庫的內容
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1/eric", "jlu", "newpasswd");
stmt = conn.createStatement();
String uSQL = "update Product set name='" + name.value + "', price=" + price.value +
", qty=" + qty.value + " where id=" + num.value;
if (stmt.executeUpdate(uSQL) <= 0)
throw new SQLException("資料新增失敗");
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 修改 listbox 的內容
List children = box.selectedItem.children;
((Listcell)children.get(0)).label = num.value.toString();
((Listcell)children.get(1)).label = name.value;
((Listcell)children.get(2)).label = price.doubleValue().toString();
((Listcell)children.get(3)).label = qty.value.toString();
}
// 資料刪除 =========================================================
void delete() {
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1/eric", "jlu", "newpassw");
stmt = conn.createStatement();
String dSQL = "delete from Product where id=" + num.value;
if (stmt.executeUpdate(dSQL) <= 0)
throw new SQLException("資料刪除失敗");
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 下列兩個敘述的順序不可以對調
// 確保刪除的資料也從 allItems 內消失
allItems.remove(box.getSelectedIndex());
box.removeItemAt(box.getSelectedIndex());
clearData();
}
// ==============================================================
void clearData(){
// 清除輸入欄位
num.value = null;
name.value = null;
price.setText("");
qty.value = null;
}
</zscript>
<listbox id="box" multiple="true" rows="4" onSelect="move()">
<listhead>
<listheader label="料號" width="50px" />
<listheader label="品名" />
<listheader align="right" label="價格" width="60px" />
<listheader align="right" label="數量" width="60px" />
</listhead>
<listitem forEach="${allItems}" value="${each}">
<listcell label="${each.id}"/>
<listcell label="${each.name}"/>
<listcell label="${each.price}"/>
<listcell label="${each.qty}"/>
</listitem>
</listbox>
<groupbox>
<caption label="存貨管理"/>
料號: <intbox id="num" cols="5" />
品名: <textbox id="name" cols="25" />
價格: <decimalbox id="price" cols="8" />
數量: <intbox id="qty" cols="8" />
<div>
<button label="新增" width="46px" height="24px" onClick="add()"/>
<button label="修改" width="46px" height="24px" onClick="update()"/>
<button label="刪除" width="46px" height="24px" onClick="delete()"/>
</div>
</groupbox>
</window>
我們的範例程式到此已經介紹完畢,可是我們要提醒讀者:這個系統只是
設計給單一使用者的;也就是說,這個系統的設計是假設一次只有一個使用者
在使用。試試看:打開兩個瀏覽器的視窗,然後分別開啟我們剛剛設計好的系統,
並分別在兩個視窗中新增資料,請觀察新增的資料是否立即反應再另一個視窗中。