針對中小型應用、桌面程式或輕量 Web 系統,傳統關聯式資料庫過重、OODB 學習曲線陡峭。XML 檔案作為持久介質具備:人類可讀、跨平台、無需額外安裝、版本控管友善等優勢。
Hashtable<String, Member> 做身分識別快取add/update/delete) 採用 synchronized(lockObj) 確保執行緒安全<members/>XmlFileReadException、XmlFileWriteExceptionpublic boolean add(Member member) {
if (hasMember(member)) return false;
synchronized (lockObj) {
try {
memberPersistence.add(member); // 先持久化
members.put(member.getId(), member); // 再更新快取
return true;
} catch (XmlFileWriteException ex) {
logError("add", member.getId(), ex);
return false;
}
}
}
public boolean update(Member member) {
if (!hasMember(member)) return false;
synchronized (lockObj) {
try {
memberPersistence.update(member);
Member cached = members.get(member.getId());
cached.setName(member.getName());
cached.setAge(member.getAge());
return true;
} catch (XmlFileWriteException ex) {
logError("update", member.getId(), ex);
return false;
}
}
}
public boolean delete(Member member) {
if (!hasMember(member)) return false;
synchronized (lockObj) {
try {
memberPersistence.delete(member.getId());
members.remove(member.getId());
return true;
} catch (XmlFileWriteException ex) {
logError("delete", member.getId(), ex);
return false;
}
}
}
// 新增
public boolean add(Member member) throws XmlFileWriteException {
Element root = document.getRootElement();
Element memberElm = root.addElement("member").addAttribute("id", member.getId());
memberElm.addElement("name").setText(member.getName());
memberElm.addElement("age").setText(String.valueOf(member.getAge()));
writeDocumentToFile();
return true;
}
// 更新
public boolean update(Member member) throws XmlFileWriteException {
for (Element elm : (List<Element>) root.elements("member")) {
if (elm.attributeValue("id").equals(member.getId())) {
elm.element("name").setText(member.getName());
elm.element("age").setText(String.valueOf(member.getAge()));
break;
}
}
writeDocumentToFile();
return true;
}
// 刪除
public boolean delete(String id) throws XmlFileWriteException {
for (Element elm : (List<Element>) root.elements("member")) {
if (elm.attributeValue("id").equals(id)) {
root.remove(elm);
break;
}
}
writeDocumentToFile();
return true;
}
// 載入快取
public Hashtable<String, Member> loadMemberFromFile() {
Hashtable<String, Member> map = new Hashtable<>();
for (Element elm : (List<Element>) document.getRootElement().elements("member")) {
Member m = new Member(
elm.attributeValue("id"),
elm.elementText("name"),
Integer.parseInt(elm.elementText("age"))
);
map.put(m.getId(), m);
}
return map;
}
<?xml version="1.0" encoding="UTF-8"?>
<members>
<member id="M001">
<name>王小明</name>
<age>28</age>
</member>
<member id="M002">
<name>李大華</name>
<age>35</age>
</member>
</members>
| 特性 | 實作方式 | 擴充方向 |
|---|---|---|
| 執行緒安全 | 單一鎖物件同步寫入 | 改用 ReadWriteLock 提升讀取並發 |
| 快取一致性 | 寫入成功才更新快取 | 加入版本號/時間戳支援樂觀鎖 |
| 查詢彈性 | Strategy 模式:MemberFilter 介面 | 整合 XPath/XQuery 複雜查詢 |
| 資料完整性 | ID 唯一性檢查、例外封裝 | 加入 XML Schema 驗證 |
| 效能優化 | 啟動載入全量快取 | 大量資料分頁載入、引入索引機制 |