以XML为一个小的数据库,写一个小练习,命令式菜单,练习java解析xml--dom方式的增删改查。

下面是项目分包:注意xml文件跟src是并列的。

xml 小练习_java

一开始Contact.xml文档如下图:

xml 小练习_System_02

写一个工具类生产uuid:

package cn.hncu.contact.util;

import java.util.UUID;

public class IDGenerator {
private IDGenerator(){

}

public static String getId(){
String uuid=UUID.randomUUID().toString();
uuid=uuid.replaceAll("-", "");
return uuid;
}
}

重点:因为是多用户,虽然是单机版,但这里要用到单例!!!

生成单例的代码如下,写一个工厂类:

package cn.hncu.contact.common;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;


public class DocumentFactory {
private static Document dom;
private static File file;
static{
try {
file = new File("./xml/Contact.xml");
if(!file.exists()){
throw new Exception("数据库不存在!");
}
DocumentBuilder db=DocumentBuilderFactory.newInstance().newDocumentBuilder();
dom = db.parse(file);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

public static Document getDocument(){
return dom;
}

public static void save(){
try {
Transformer trans=TransformerFactory.newInstance().newTransformer();
trans.transform(new DOMSource(dom), new StreamResult(file));
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}

}
}

然后写一个测试类 :测试一下工具类:

package cn.hncu.testContact;

import org.junit.Test;
import org.w3c.dom.Document;

import cn.hncu.contact.common.DocumentFactory;
import cn.hncu.contact.util.IDGenerator;

public class ContactTest {
@Test
public void testGetId(){
String id = IDGenerator.getId();
System.out.println(id);
System.out.println(IDGenerator.getId());
System.out.println(IDGenerator.getId());
}


@Test
public void testGetDom(){
Document dom1 = DocumentFactory.getDocument();
Document dom2 = DocumentFactory.getDocument();
System.out.println(dom1.hashCode());
System.out.println(dom2.hashCode());
}
}

结果如下: 

第一个是生成的单例的hashCode,一样说明,是单例! 第二个是随机生成的UUID

接下来写Dao层,接口,工厂,实现类:

package cn.hncu.contact.dao;

import java.util.List;
import java.util.Map;

public interface ContactDAO {
public boolean login(String name,String pwd);
public void reg(String name,String pwd);
public boolean add(String name, String tel, String sex);
public List<Map<String, String>> queryAllContacts();
public String del(String id);
public boolean upd(String id,String name,String tel,String sex,String target);
}
package cn.hncu.contact.dao.factory;

import cn.hncu.contact.dao.ContactDAO;
import cn.hncu.contact.dao.impl.ContactDaoImpl;

public class ContactDAOFactory {
private ContactDAOFactory(){

}
public static ContactDAO getContactDao(){
return new ContactDaoImpl();
}
}
package cn.hncu.contact.dao.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import cn.hncu.contact.common.DocumentFactory;
import cn.hncu.contact.dao.ContactDAO;
import cn.hncu.contact.util.IDGenerator;

public class ContactDaoImpl implements ContactDAO {

private Element eCurrentUser = null; // 当前用户

@Override
public boolean login(String name, String pwd) {
Document dom = DocumentFactory.getDocument();
Element root = (Element) dom.getFirstChild();
NodeList eUserList = root.getElementsByTagName("user");
for (int i = 0; i < eUserList.getLength(); i++) {
Element eUser = (Element) eUserList.item(i);
if (eUser.getAttribute("name").equalsIgnoreCase(name)
&& eUser.getAttribute("pwd").equals(pwd)) {
eCurrentUser = eUser; // 把当前登录成功的用户保存到类成员变量eCurrentUser,供其它业务方法使用
return true;
}
}

return false;
}

@Override
public void reg(String name, String pwd) {
Document dom = DocumentFactory.getDocument();
// 把新用户节点添加到dom中
Element root = (Element) dom.getFirstChild();

// 创建一个新的用户节点 eNewUser
Element eNewUser = dom.createElement("user");
eNewUser.setAttribute("name", name);
eNewUser.setAttribute("pwd", pwd);
// 把eNewUser添加为root的孩子
root.appendChild(eNewUser);

// 保存
DocumentFactory.save();
}

@Override
public boolean add(String name, String tel, String sex) {
Document dom = DocumentFactory.getDocument();
// 创建一个新的联系人节点<contact>, eNewContact对象
Element eNewContact = dom.createElement("contact");
eNewContact.setAttribute("id", IDGenerator.getId());

// 创建一个<name>元素对应的 eName,并把它添加成eNewContact的孩子
Element eName = dom.createElement("name");
eName.setTextContent(name);
eNewContact.appendChild(eName);

// 创建一个<tel>元素对应的 eTel,并把它添加成eNewContact的孩子
Element eTel = dom.createElement("tel");
eTel.setTextContent(tel);
eNewContact.appendChild(eTel);

// 创建一个<sex>元素对应的 eSex,并把它添加成eNewContact的孩子
Element eSex = dom.createElement("sex");
eSex.setTextContent(sex);
eNewContact.appendChild(eSex);

// 把上面组装好的eNewContact添加成eCurrentUser的孩子
eCurrentUser.appendChild(eNewContact);

// 序列化
DocumentFactory.save();
return false;
}

@Override
public List<Map<String, String>> queryAllContacts() {
List<Map<String, String>> resultList = new ArrayList<Map<String, String>>();
if (eCurrentUser == null) {
return resultList;
}
NodeList eContactList = eCurrentUser.getElementsByTagName("contact");
for (int i = 0; i < eContactList.getLength(); i++) {
Element eContact = (Element) eContactList.item(i);
// 把每一个eContact中的信息封装成一个map
Map<String, String> map = new HashMap<String, String>();
map.put("id", eContact.getAttribute("id"));// id
map.put("name", eContact.getElementsByTagName("name").item(0)
.getTextContent());// name
map.put("sex", eContact.getElementsByTagName("sex").item(0)
.getTextContent());// sex
map.put("tel", eContact.getElementsByTagName("tel").item(0)
.getTextContent());// tel

// 把map添加到resultList中
resultList.add(map);
}
return resultList;
}

@Override
public String del(String id) {
NodeList eContactList = eCurrentUser.getElementsByTagName("contact");
for (int i = 0; i < eContactList.getLength(); i++) {
Element eContact = (Element) eContactList.item(i);
String iid = eContact.getAttribute("id");
if (id.equals(iid)) {
// 先保存要返回的数据
String name = eContact.getElementsByTagName("name").item(0)
.getTextContent();
eContact.getParentNode().removeChild(eContact);
DocumentFactory.save();

return name;
}
}
return null;

}

@Override
public boolean upd(String id, String name, String tel, String sex,String target) {
NodeList eContactList = eCurrentUser.getElementsByTagName("contact");
boolean boo = false;
for (int i = 0; i < eContactList.getLength(); i++) {
Element eContact = (Element) eContactList.item(i);
String iid = eContact.getAttribute("id");
if (id.equals(iid)) {
if ("0".equals(target)) {
tel = eContact.getElementsByTagName("tel").item(0)
.getTextContent();
sex = eContact.getElementsByTagName("sex").item(0)
.getTextContent();
Element eName = (Element) eContact.getElementsByTagName(
"name").item(0);
eName.setTextContent(name);
boo = true;
} else if ("1".equals(target)) {
sex = eContact.getElementsByTagName("sex").item(0)
.getTextContent();
name = eContact.getElementsByTagName("name").item(0)
.getTextContent();
Element eTel = (Element) eContact.getElementsByTagName(
"tel").item(0);
eTel.setTextContent(tel);
boo = true;
} else if ("2".equals(target)) {
tel = eContact.getElementsByTagName("tel").item(0)
.getTextContent();
name = eContact.getElementsByTagName("name").item(0)
.getTextContent();
Element eSex = (Element) eContact.getElementsByTagName(
"sex").item(0);
eSex.setTextContent(sex);
boo = true;
} else {
boo = false;
}

}
DocumentFactory.save();
}
return boo;
}

}

最后是表现层:

package cn.hncu.contact.cmd;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

import cn.hncu.contact.dao.ContactDAO;
import cn.hncu.contact.dao.factory.ContactDAOFactory;

public class ContactAction {
private Scanner sc = null;
// 声明一个联系人id集合---存放序号与id对应关系的hashMap
// 在每次显示所有联系人时重新存入,在删除与修改时读取
Map<Integer, String> idMap = null;
// 注入dao
private ContactDAO dao = ContactDAOFactory.getContactDao();

public ContactAction() {
sc = new Scanner(System.in);
System.out.println("※※警告用户:非GBK编码时,MyEclipse控制台中不支持中文输入!※※");
System.out
.println("---------------------------------------------------");

while (true) {
// 软件的主界面显示
System.out.println("1:登录");
System.out.println("2:注册");
System.out.println("0:退出");

String op = sc.nextLine();
if ("1".equals(op)) {
login();
} else if ("2".equals(op)) {
reg();
} else if ("0".equals(op)) {
System.out.println("程序马上退出....");
break;
}

}
}

private void reg() {
System.out.println("*********************");
System.out.println("* 用户注册 *");
System.out.println("*********************");
System.out.println("请输入用户名:");
String name = sc.nextLine();
System.out.println("请输入密码:");
String pwd = sc.nextLine();
System.out.println("请再次输入密码:");
String pwd2 = sc.nextLine();
if (name.trim().length() > 0) {
if (pwd.equals(pwd2)) {
// 调用dao层进行注册
dao.reg(name, pwd);
System.out.println("恭喜,注册成功!");
} else {
System.out.println("两次密码不一致,请重新注册!");
reg();
}
} else {
System.out.println("姓名不能为空字符");
reg();
}

}

private void login() {
System.out.println("*********************");
System.out.println("* 用户登录 *");
System.out.println("*********************");
System.out.println("请输入用户名:");
String name = sc.nextLine();
System.out.println("请输入密码:");
String pwd = sc.nextLine();
boolean boo = dao.login(name, pwd);
if (boo) {
System.out.println("恭喜,登录成功,请选择下一步操作!");
operation();
} else {
System.out.println("登录失败!!!!");
}
}

private void operation() {
System.out.println("1:显示所有联系人");
System.out.println("2:添加联系人");
System.out.println("3:删除联系人");
System.out.println("4:修改联系人");
System.out.println("0:返回到软件主界面");

String sel = sc.nextLine();
if ("1".equals(sel)) {// 显示所有联系人
queryAll();
} else if ("2".equals(sel)) {// 添加联系人
addContact();
} else if ("3".equals(sel)) {// 删除联系人
delContact();
} else if ("4".equals(sel)) {// 修改联系人
updContact();
} else if ("0".equals(sel)) {// 退回到上一级菜单
return;
}
operation();
}

private void queryAll() {
List<Map<String, String>> list = dao.queryAllContacts();
System.out.println("序号\t姓名\t电话\t性别");
System.out.println("-------------------------------");
idMap = new HashMap<Integer, String>();
int i = 1;
for (Map<String, String> map : list) {
String id = map.get("id");
idMap.put(i, id); // 为以后的删除与修改做存储

String name = map.get("name");
String tel = map.get("tel");
String sex = map.get("sex");
if ("0".equals(sex)) {
sex = "男";
} else {
sex = "女";
}
System.out.println((i++) + "\t" + name + "\t" + tel + "\t"
+ sex);
}

}

private void updContact() {
queryAll();
String name=null;
String sex=null;
String tel=null;
boolean boo=false;
System.out.println("请输入要修改联系人的序号");
int num = sc.nextInt();
sc.nextLine();//吸掉多余的换行符
String id = idMap.get(num);
System.out.println("请输入要修改的属性:0-姓名 1-电话 2-性别");
String target=sc.nextLine();
if ("0".equals(target)) {
System.out.println("请输入要修改姓名的内容:");
name=sc.nextLine();
boo=dao.upd(id, name, tel, sex,target);
}else if("1".equals(target)){
System.out.println("请输入要修改电话的内容:");
tel=sc.nextLine();
boo=dao.upd(id, name, tel, sex,target);
}else if("2".equals(target)){
System.out.println("请输入要修改性别的内容:");
sex=sc.nextLine();
boo=dao.upd(id, name, tel, sex,target);
}
if(boo){
System.out.println("修改成功~~");
queryAll();
}else{
System.out.println("修改失败!!");
}
}

private void delContact() {
queryAll();
System.out.println("请输入要删除联系人的序号");
int num = sc.nextInt();
sc.nextLine();//吸掉多余的换行符
String id = idMap.get(num);
String name = dao.del(id);
if(name!=null){
System.out.println("已经删除联系人:"+name);
queryAll();
}else{
System.out.println("不存在该联系人");
}
}

private void addContact() {
System.out.println("请输入联系人的信息");
System.out.println("姓名:");
String name = sc.nextLine();
System.out.println("电话:");
String tel = sc.nextLine();
System.out.println("性别:");
String sex = sc.nextLine();

dao.add(name,tel,sex);
}

public static void main(String[] args) {
new ContactAction();
}

}

xml 小练习_List_03

最后的XML文件是:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><contacts>
<user name="1234" pwd="1234">
<contact id="2eaa2dbb32064cf0afd6a5e1013a6cbf">
<name>simons</name>
<tel>88888</tel>
<sex>0</sex>
</contact>
<contact id="7fe2cf73804645f0abbca1303b78ec9a">
<name>james</name>
<tel>99999</tel>
<sex>0</sex>
</contact>
<contact id="f49e5457dc144ca483fbbf82667cf7d3"><name>111</name><tel>56666</tel><sex>0</sex></contact></user>
<user name="tom" pwd="1111">
<contact id="688f0e262e5841ba8d6ceceffa9f9f4d">
<name>lx</name>
<tel>12333</tel>
<sex>1</sex>
</contact>
</user>
</contacts>