信手拈来 妙手偶得 » 日志 » [原创]使用XML作为持久存储介质的解决方案续
[原创]使用XML作为持久存储介质的解决方案续
Junglesong 发表于 2007-12-08 12:14:33
本文是"使XML作为持久存储介质的解决方案 "的续文.
上文中对成员的CRUD都采用同步进行资源保护,这种方案实际上是保护过度,带来的消极影响是降低了程序的效率,在下面的例子中,我们应该使用读写锁对资源进行保护.关于读写锁的分析请见"读写锁的OO分析(http://www.blogjava.net/sitinspring/archive/2007/10/21/154652.html)".
下面是代码:
MemberService类:
package com.sitinspring.model.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;

import com.sitinspring.exception.PersistFileReadException;
import com.sitinspring.exception.PersistFileWriteException;
import com.sitinspring.model.domain.Member;
import com.sitinspring.model.domain.MemberFilter;
import com.sitinspring.model.persistence.Db4OPersistence;
import com.sitinspring.model.persistence.HibernatePersistence;
import com.sitinspring.model.persistence.Persistence;
import com.sitinspring.model.persistence.SqlPersistence;
import com.sitinspring.model.persistence.XmlPersistence;
import com.sitinspring.util.ReadWriteLock;

public class MemberService {
private static Logger logger = Logger.getLogger(MemberService.class);
private Persistence persistence;
private Persistence xmlPersistence;
private Persistence sqlPersistence;
private Persistence db4OPersistence;
private Persistence hibernatePersistence;

private Hashtable<String, Member> members;

private ReadWriteLock lock;

public MemberService() {
members = new Hashtable<String, Member>();
lock = new ReadWriteLock();
}
public void setPersistenceType(String type){
logger.info("指定持久层为"+type);
if(type.equals("Xml")){
if(xmlPersistence==null){
try{
xmlPersistence=new XmlPersistence();
}
catch(Exception ex){
logger.error("不能初始化XmlPersistence,原因:"+ex.getMessage());
}
}
persistence=xmlPersistence;
}
else if(type.equals("Sql")){
if(sqlPersistence==null){
try{
sqlPersistence=new SqlPersistence();
}
catch(Exception ex){
logger.error("不能初始化XmlPersistence,原因:"+ex.getMessage());
}
}
persistence=sqlPersistence;
}
else if(type.equals("Hibernate")){
if(hibernatePersistence==null){
try{
hibernatePersistence=new HibernatePersistence();
}
catch(Exception ex){
logger.error("不能初始化XmlPersistence,原因:"+ex.getMessage());
}
}
persistence=hibernatePersistence;
}
else{
if(db4OPersistence==null){
try{
db4OPersistence=new Db4OPersistence();
}
catch(Exception ex){
logger.error("不能初始化XmlPersistence,原因:"+ex.getMessage());
}
}
persistence=db4OPersistence;
}
try{
members.clear();
members=persistence.loadMemberFromPersistence();
}
catch(PersistFileReadException ex){
logger.error("从"+persistence+"中读取失败");
}
}

public boolean hasMember(String name) {
return members.containsKey(name);
}

public boolean hasMember(Member member) {
return hasMember(member.getName());
}

public boolean add(Member member) throws PersistFileWriteException {
if (hasMember(member)) {
System.out.println("Member:" + member.getName()
+ " has been exist!");
return false;
} else {
try {
lock.writeLock();
persistence.add(member);
members.put(member.getName(), member);
return true;
} finally {
lock.writeUnlock();
}
}
}

public boolean update(Member member) throws PersistFileWriteException {
if (hasMember(member)) {
try {
lock.writeLock();

persistence.update(member);

Member oldMember = members.get(member.getName());
oldMember.setTitle(member.getTitle());
oldMember.setAge(member.getAge());

return true;
} finally {
lock.writeUnlock();
}

} else {
System.out.println("Member:" + member.getName()
+ " can't been found!");
return false;
}
}

public boolean saveOrUpdate(Member member) throws PersistFileWriteException {
if (hasMember(member)) {
return update(member);
} else {
return add(member);
}
}

public boolean delete(Member member) throws PersistFileWriteException {
return delete(member.getName());
}
public boolean delete(String memberName) throws PersistFileWriteException {
if (hasMember(memberName)) {
try {
lock.writeLock();
persistence.delete(memberName);
members.remove(memberName);
return true;
} finally {
lock.writeUnlock();
}
} else {
System.out.println("Member:" + memberName
+ " can't been found!");
return false;
}
}

@SuppressWarnings("unchecked")
public List<Member> search(MemberFilter memberFilter) {
List<Member> retval = new ArrayList<Member>();

try {
lock.readLock();

for (Iterator it = members.keySet().iterator(); it.hasNext();) {
String key = (String) it.next();
Member member = members.get(key);

if (memberFilter.match(member)) {
retval.add(member);
}
}
} finally {
lock.readUnlock();
}

Collections.sort(retval);

return retval;
}

public List<Member> getAll() {
MemberFilter filter = new MemberFilter() {
public boolean match(Member member) {
return true;
}
};

return search(filter);
}

public Member getMemberByName(String name) {
try {
lock.readLock();
for (Iterator it = members.keySet().iterator(); it.hasNext();) {
String key = (String) it.next();
Member member = members.get(key);

if (member.getName().equals(name)) {
return member;
}
}
} finally {
lock.readUnlock();
}

return null;
}

}
XmlPersistence类代码:
package com.sitinspring.model.persistence;

import java.io.File;
import java.io.FileWriter;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import com.sitinspring.exception.PersistFileReadException;
import com.sitinspring.exception.PersistFileWriteException;
import com.sitinspring.model.domain.Member;
import com.sitinspring.util.FileDirUtil;

public class XmlPersistence extends Persistence {
private Document document;

public XmlPersistence() throws PersistFileReadException,
PersistFileWriteException {
filePos = "member.xml";

if (FileDirUtil.isFileExist(filePos) == false) {
// Create document when file not exist
createDocument();
return;


上文中对成员的CRUD都采用同步进行资源保护,这种方案实际上是保护过度,带来的消极影响是降低了程序的效率,在下面的例子中,我们应该使用读写锁对资源进行保护.关于读写锁的分析请见"读写锁的OO分析(http://www.blogjava.net/sitinspring/archive/2007/10/21/154652.html)".
下面是代码:
MemberService类:
package com.sitinspring.model.service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import com.sitinspring.exception.PersistFileReadException;
import com.sitinspring.exception.PersistFileWriteException;
import com.sitinspring.model.domain.Member;
import com.sitinspring.model.domain.MemberFilter;
import com.sitinspring.model.persistence.Db4OPersistence;
import com.sitinspring.model.persistence.HibernatePersistence;
import com.sitinspring.model.persistence.Persistence;
import com.sitinspring.model.persistence.SqlPersistence;
import com.sitinspring.model.persistence.XmlPersistence;
import com.sitinspring.util.ReadWriteLock;
public class MemberService {
private static Logger logger = Logger.getLogger(MemberService.class);
private Persistence persistence;
private Persistence xmlPersistence;
private Persistence sqlPersistence;
private Persistence db4OPersistence;
private Persistence hibernatePersistence;
private Hashtable<String, Member> members;
private ReadWriteLock lock;
public MemberService() {
members = new Hashtable<String, Member>();
lock = new ReadWriteLock();
}
public void setPersistenceType(String type){
logger.info("指定持久层为"+type);
if(type.equals("Xml")){
if(xmlPersistence==null){
try{
xmlPersistence=new XmlPersistence();
}
catch(Exception ex){
logger.error("不能初始化XmlPersistence,原因:"+ex.getMessage());
}
}
persistence=xmlPersistence;
}
else if(type.equals("Sql")){
if(sqlPersistence==null){
try{
sqlPersistence=new SqlPersistence();
}
catch(Exception ex){
logger.error("不能初始化XmlPersistence,原因:"+ex.getMessage());
}
}
persistence=sqlPersistence;
}
else if(type.equals("Hibernate")){
if(hibernatePersistence==null){
try{
hibernatePersistence=new HibernatePersistence();
}
catch(Exception ex){
logger.error("不能初始化XmlPersistence,原因:"+ex.getMessage());
}
}
persistence=hibernatePersistence;
}
else{
if(db4OPersistence==null){
try{
db4OPersistence=new Db4OPersistence();
}
catch(Exception ex){
logger.error("不能初始化XmlPersistence,原因:"+ex.getMessage());
}
}
persistence=db4OPersistence;
}
try{
members.clear();
members=persistence.loadMemberFromPersistence();
}
catch(PersistFileReadException ex){
logger.error("从"+persistence+"中读取失败");
}
}
public boolean hasMember(String name) {
return members.containsKey(name);
}
public boolean hasMember(Member member) {
return hasMember(member.getName());
}
public boolean add(Member member) throws PersistFileWriteException {
if (hasMember(member)) {
System.out.println("Member:" + member.getName()
+ " has been exist!");
return false;
} else {
try {
lock.writeLock();
persistence.add(member);
members.put(member.getName(), member);
return true;
} finally {
lock.writeUnlock();
}
}
}
public boolean update(Member member) throws PersistFileWriteException {
if (hasMember(member)) {
try {
lock.writeLock();
persistence.update(member);
Member oldMember = members.get(member.getName());
oldMember.setTitle(member.getTitle());
oldMember.setAge(member.getAge());
return true;
} finally {
lock.writeUnlock();
}
} else {
System.out.println("Member:" + member.getName()
+ " can't been found!");
return false;
}
}
public boolean saveOrUpdate(Member member) throws PersistFileWriteException {
if (hasMember(member)) {
return update(member);
} else {
return add(member);
}
}
public boolean delete(Member member) throws PersistFileWriteException {
return delete(member.getName());
}
public boolean delete(String memberName) throws PersistFileWriteException {
if (hasMember(memberName)) {
try {
lock.writeLock();
persistence.delete(memberName);
members.remove(memberName);
return true;
} finally {
lock.writeUnlock();
}
} else {
System.out.println("Member:" + memberName
+ " can't been found!");
return false;
}
}
@SuppressWarnings("unchecked")
public List<Member> search(MemberFilter memberFilter) {
List<Member> retval = new ArrayList<Member>();
try {
lock.readLock();
for (Iterator it = members.keySet().iterator(); it.hasNext();) {
String key = (String) it.next();
Member member = members.get(key);
if (memberFilter.match(member)) {
retval.add(member);
}
}
} finally {
lock.readUnlock();
}
Collections.sort(retval);
return retval;
}
public List<Member> getAll() {
MemberFilter filter = new MemberFilter() {
public boolean match(Member member) {
return true;
}
};
return search(filter);
}
public Member getMemberByName(String name) {
try {
lock.readLock();
for (Iterator it = members.keySet().iterator(); it.hasNext();) {
String key = (String) it.next();
Member member = members.get(key);
if (member.getName().equals(name)) {
return member;
}
}
} finally {
lock.readUnlock();
}
return null;
}
}XmlPersistence类代码:
package com.sitinspring.model.persistence;
import java.io.File;
import java.io.FileWriter;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import com.sitinspring.exception.PersistFileReadException;
import com.sitinspring.exception.PersistFileWriteException;
import com.sitinspring.model.domain.Member;
import com.sitinspring.util.FileDirUtil;
public class XmlPersistence extends Persistence {
private Document document;
public XmlPersistence() throws PersistFileReadException,
PersistFileWriteException {
filePos = "member.xml";
if (FileDirUtil.isFileExist(filePos) == false) {
// Create document when file not exist
createDocument();
return;



