要求:使用XML保存图书信息,使用DOM4J操作XML,进行图书的增删改查。
使用技术:XML/DOM4j/集合/对象
部分实现效果如果下:
实现思路
首先需要创建一个图书类(Book类),保存图书的属性(属性和XML文件一致,因为最终修改的是XML文件),将图书对象放到泛型集合<Book>里面去,直接操作集合就可以了,因为需要修改XML文件,每一次对图书的操作都需要保存到XML文件中去,所以可以写一个XmlUtil工具类,专门进行文件的读取和存储,将对文件的操作(增删改查)的方法写一个BookMsg类,最后需要一个测试类,所以这个项目整体需要四个类 ——图书类(Book)、XML文件的读取的和存储(XmlUtil)、XML文件的操作(BookMsg)、测试类(BookText)、XML文件
图书类:
根据项目要求赋予属性,创建构造函数
package com.book;
public class Book {
private Integer id; //图书ID
private String name; //图书名字
private String author; //图书作者
private float price; //图书日租金
private int status; //图书状态(0为未借出,1为借出)
private int count; //图书借出次数
private String times; //借出的日期
public Book() {}
public Book(Integer id, String name, String author, float price, int status, int count, String times) {
this.id = id;
this.name = name;
this.author = author;
this.price = price;
this.status = status;
this.count = count;
this.times = times;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public String getTimes() {
return times;
}
public void setTimes(String times) {
this.times = times;
}
//重写toString
public String toString() {
return "Book [id=" + id + ", name=" + name + ", author=" + author + ", price=" + price + ", status=" + status
+ ", count=" + count + ", times=" + times + "]";
}
//重写equals方法
public boolean equals(Object obj) {
Book ob=(Book) obj;
return this.name.equals(ob.getName());
}
}
XML文件
先根据要求初始化一个XML文件
<?xml version="1.0" encoding="UTF-8"?>
<Books>
<book>
<name>西游记</name>
<author>吴承恩</author>
<times></times>
<count>23</count>
<id>1</id>
<price>45.2</price>
<status>0</status>
</book>
<book>
<name>红楼梦</name>
<author>曹雪芹</author>
<times>2018-5-16</times>
<count>23</count>
<id>2</id>
<price>68.5</price>
<status>1</status>
</book>
<book>
<name>白雪公主</name>
<author>迪士尼</author>
<times></times>
<count>37</count>
<id>3</id>
<price>35.8</price>
<status>0</status>
</book>
<book>
<name>皮皮鸟</name>
<author>zyh</author>
<times></times>
<count>3</count>
<id>4</id>
<price>32.0</price>
<status>0</status>
</book>
</Books>
XmlUtil类
这个类主要实现对XML文件的读取和存储,因为进行操作的时候都需要调用这两个方法,所以可以写为静态方法,而我们读取Xml文件的时候是用集合<Book>去保存的,所以读取方法可以返回一个<Book>集合,保存XML文件的时候也是保存<Book>集合的,所以可以给个集合参数。
难点是我们在BookMsg中写增删改查的方法虽然是用下面写的读取方法qurrybooks()去操作一个<Book>集合,但是我们要清楚这个最终修改的是集合里面的每一个Book对象,所以文件的读取保存也是一样,我们要在集合里面的对象和使用DOM4J拿元素的值和创建元素并赋值的方法中切换,实际上是通过了一个集合的转换,将对象的属性和使用DOM4J结合。
package com.book;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
*
* XML文件读取/保存
*
*/
public class XmlUtil {
/**
* 读取XML、返回一个<Book>集合
*/
public static List<Book>qurrybooks(){
//创建一个泛型集合,保存图书
List<Book> books = new ArrayList<Book>();
//DOM4J读取文件
SAXReader reader = new SAXReader();
try {
Document doc=reader.read(new File("Book.xml"));
Element root=doc.getRootElement();
//将根元素下的所有book元素放到集合eleBooks中去
List <Element> eleBooks=root.elements("book");
//遍历每一个book元素下的所有元素(相当于每一本书),把XML里面每一个元素都放到一个新的Book对象里面去
for (Element elembook : eleBooks) {
Book b =new Book();
b.setName(elembook.elementText("name"));
b.setAuthor(elembook.elementText("author"));
b.setId(Integer.parseInt(elembook.element("id").getText()));
b.setCount(Integer.parseInt(elembook.element("count").getText()));
b.setPrice(Float.parseFloat(elembook.element("price").getText()));
b.setStatus(Integer.parseInt(elembook.element("status").getText()));
b.setTimes(elembook.elementText("times"));
//再把每一个Book对象放到集合中
books.add(b);
}
} catch (DocumentException e) {
e.printStackTrace();
}
//返回一个<Book>的集合
return books;
}
/**
*保存XML文件,传一个<Book>集合,将集合中的Book对象写到XML文件中去
*/
public static boolean SaveXML(List<Book>book) {
SAXReader read=new SAXReader();
//创建一个DOC树,因为XML存文件是存储document树
Document doc=read.getDocumentFactory().createDocument();
//创建根元素
Element root=doc.addElement("Books");
try {
//遍历集合中的所有Book对象,将每一个对象中的属性的值拿出来写到对应XML的属性中去
for (Book b : book) {
//创建book元素,在book元素下再去创建对象相对于的元素并给元素的文本属性赋值
Element elebook=root.addElement("book");
elebook.addElement("name").setText(b.getName());
elebook.addElement("author").setText(b.getAuthor());
elebook.addElement("times").setText(b.getTimes()==null?"":b.getTimes());
elebook.addElement("count").setText(b.getCount()+"");
elebook.addElement("id").setText(b.getId()+"");
elebook.addElement("price").setText(b.getPrice()+"");
elebook.addElement("status").setText(b.getStatus()+"");
}
//DOM4J的写的XMLWriter()方法,前面是路径,后面是按照漂亮格式写出
XMLWriter xmlw = new XMLWriter(new FileOutputStream("book.xml"), OutputFormat.createPrettyPrint());
//将doc树写到xml文件中去
xmlw.write(doc);
xmlw.flush();
xmlw.close();
} catch (UnsupportedEncodingException | FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
return true;
}
}
BookMsg类
图书的 1.查阅图书功能 2.增加图书功能 3.删除图书功能 4.借阅图书功能 5.归还图书功能
package com.book;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class BookMsg {
//将读取到的XML文件返回的集合设置为全局属性,下面所有方法都 可以直接使用集合book
List <Book> book=XmlUtil.qurrybooks();
/**
* 展示所有图书
*/
public void showInfo() {
System.out.println("编号\t状态\t名称\t借出次数\t借出日期");
for (Book b: book) {
//如果图书未借出,借出日期 为空的字符串
if(b.getStatus()==0) {
b.setTimes("");
}
//输出图书状态
System.out.println(b.getId()+"\t"+(b.getStatus()==0?"未借出":"已借出")+"\t"+b.getName()+"\t"+b.getCount()+"\t"+b.getTimes());
}
}
/**
* 增加图书,传一个新的Book对象,直接放到book集合里面去,保存到XML文件中
*/
public void addBook(Book b) {
if(book.size()==0) {
b.setId(1);
}else {
b.setId( book.get(book.size()-1).getId() +1 );
}
book.add(b);
System.out.println("增加成功!");
XmlUtil.SaveXML(book);
}
/**
* 删除图书,将需要删除的Book对象传进来,判断集合中是否有这个对象且不为借出状态就可以删除 contains()
* 删除后保存
*/
public void deleteBook(Book b) {
//判断集合中是否有对象b,且该图书为借出状态时不可被删除
if(book.contains(b)&&b.getStatus()!=1) {
book.remove(b);
XmlUtil.SaveXML(book);
System.out.println("删除成功!");
}else {
System.out.println("图书不存在");
}
}
/**
* 借图书,传进来的Book对象判断一下集合中是否有这本书,要重写 equles方法,存在就修改状态并且改上当前借出时间
* @param b
*/
public void borrowBook(Book b) {
//转换器,设置格式
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
//创建现在的时间
Date nowdate=new Date();
//将现在的时间转为字符串
String nowtime=format.format(nowdate);
boolean f=false;
for (Book book2 : book) {
if(book2.getName().equals(b.getName())&&book2.getStatus()==0) {
f=true;
book2.setStatus(1);
book2.setTimes(nowtime);
XmlUtil.SaveXML(book);
System.out.println("借阅成功!");
}
}
if(!f) {
System.out.println("图书不存在或已被借阅");
}
}
/**
* 归还图书,传进来的Book对象判断一下集合中是否有这本书借出,并修改相对应的属性
*/
public void returnBook(Book b) {
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
boolean f=false;
for (Book book2 : book) {
if(book2.getName().equals(b.getName())&&book2.getStatus()==1) {
f=true;
try {
Date nowdate=new Date();
String nowtime=format.format(nowdate);
//将借出 的时间转换成Date类型 进行计算
Date olddate=format.parse(book2.getTimes());
//计算借出的天数
int date=(int)((nowdate.getTime()-olddate.getTime())/1000/3600/24);
book2.setStatus(0);
book2.setCount(book2.getCount()+1);
XmlUtil.SaveXML(book);
System.out.println("归还成功!");
System.out.println("借出日期为:"+book2.getTimes());
System.out.println("归还日期为:"+nowtime);
System.out.println("应付租金为:"+book2.getPrice()*date);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
if(!f) {
System.out.println("图书不存在或已归还");
}
}
}
Bookmain类
package com.book;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Bookmain {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
BookMsg bsg=new BookMsg();
int type=0;
do {
System.out.println("********************欢迎来到图书馆********************");
System.out.println("1.查阅图书");
System.out.println("2.增加图书");
System.out.println("3.删除图书");
System.out.println("4.借阅图书");
System.out.println("5.归还图书");
System.out.println("6.退出系统");
type=input.nextInt();
switch(type) {
case 1:
bsg.showInfo();
break;
case 2:
Book book=new Book();
System.out.println("请输入图书名字");
book.setName(input.next());
System.out.println("请输入图书作者");
book.setAuthor(input.next());
System.out.println("请输入图书价格");
book.setPrice(input.nextFloat());
bsg.addBook(book);
break;
case 3:
Book b=new Book();
System.out.println("请输入要删除的图书名字");
b.setName(input.next());
bsg.deleteBook(b);
break;
case 4:
System.out.println("请输入要借阅的图书");
Book b2=new Book();
b2.setName(input.next());
bsg.borrowBook(b2);
break;
case 5:
System.out.println("请输入要归还的图书");
Book b3=new Book();
b3.setName(input.next());
bsg.returnBook(b3);
break;
case 6:
System.out.println("系统结束");
return;
}
System.out.println("输入0返回:");
type=input.nextInt();
}while(type==0);
}
}
每一次进行图书的操作(增删改查)的时候,都需要对XML文件进行修改,XmlUtil类 的存在就是为了简化操作的时候每个方法还需要再写一遍对XML文件的读取和写出,而且通过集合的转换也简化了许多操作