知识点:工厂模式,MVC模式,xml文件解析存取,反射
jar包:lombok,JUnit 4,dom4j
项目结构图:
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans >
<bean id="dao" class="cn.kgc.tangcco.chengxiangjian.dao.impl.BookDaoImp"></bean>
<bean id="ser" class="cn.kgc.tangcco.chengxiangjian.service.impl.BookServiceImp"></bean>
</beans>
books.txt
100001:《Java与模式》 作者张三 出版社:电子工业出版社 价格:97.0 出版时间:2012-03-05
100003:《Java编程思想》 作者王五 出版社:机械工业出版社 价格:75.0 出版时间:2003-01-18
books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book bookId="100001">
<bookName>Java与模式</bookName>
<bookAuthor>张三</bookAuthor>
<bookPublish>电子工业出版社</bookPublish>
<bookPrice>97.0</bookPrice>
<publishDate>2012-03-05</publishDate>
</book>
<book bookId="100002">
<bookName>TCP/IP详解</bookName>
<bookAuthor>李四</bookAuthor>
<bookPublish>机械工业出版社</bookPublish>
<bookPrice>90.2</bookPrice>
<publishDate>2012-10-05</publishDate>
</book>
<book bookId="100003">
<bookName>Java编程思想</bookName>
<bookAuthor>王五</bookAuthor>
<bookPublish>机械工业出版社</bookPublish>
<bookPrice>75.0</bookPrice>
<publishDate>2003-01-18</publishDate>
</book>
<book bookId="100005">
<bookName>b</bookName>
<bookAuthor>b</bookAuthor>
<bookPublish>b</bookPublish>
<bookPrice>2.0</bookPrice>
<publishDate>2019-05-17</publishDate>
</book>
</books>
Book
package cn.kgc.tangcco.chengxiangjian.entity;
import java.util.Date;
import cn.kgc.tangcco.chengxiangjian.common.Utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book implements Comparable<Book> {
private String BookId;// 图书编号
private String bookName;// 图书名称
private String bookAuthor;// 图书作者
private String bookPublish;// 图书出版社
private float bookPrice;// 图书价格
private Date publishDate;// 出版时间
@Override
// 比较器,出版时间升序
public int compareTo(Book o) {
// return结果前面加-号,可反转排序
return this.getPublishDate().compareTo(o.getPublishDate());
}
/*
* 重写toString
*/
@Override
public String toString() {
return getBookId() + ":《" + getBookName() + "》" + "\t作者" + getBookAuthor() + " 出版社:" + getBookPublish()
+ "\t价格:" + getBookPrice() + "\t出版时间:" + Utils.dateTostr(getPublishDate());
}
}
BookDaoImp
package cn.kgc.tangcco.chengxiangjian.dao.impl;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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;
import cn.kgc.tangcco.chengxiangjian.common.Utils;
import cn.kgc.tangcco.chengxiangjian.dao.BookDao;
import cn.kgc.tangcco.chengxiangjian.entity.Book;
public class BookDaoImp implements BookDao {
private Map<String, Book> BookMap = new HashMap<String, Book>();
private Document document;
public BookDaoImp() {
String xmlPath = "src/files/books.xml";
importFromXml(xmlPath);
}
/**
* 从xml文件导入所有图书
*
* @param xmlPath
* 文件地址
*
*/
@Override
public void importFromXml(String xmlPath) {
SAXReader saxReader = new SAXReader();
try {
document = saxReader.read(new File(xmlPath));
} catch (DocumentException e) {
e.printStackTrace();
}
Element root = document.getRootElement();
List<Element> list = root.elements();
for (Element element : list) {
String BookId = element.attributeValue("bookId");
String bookName = element.elementText("bookName");
String bookAuthor = element.elementText("bookAuthor");
String bookPublish = element.elementText("bookPublish");
float bookPrice = Float.parseFloat(element.elementText("bookPrice"));
Date publishDate = Utils.strToDate(element.elementText("publishDate"));
Book book = new Book(BookId, bookName, bookAuthor, bookPublish, bookPrice, publishDate);
BookMap.put(BookId, book);
}
}
/**
* 获取所有图书信息(根据出版时间降序)
*
* @return 所有图书集合
*/
@Override
public List<Book> getAllBook() {
List<Book> list = new ArrayList<Book>();
for (Book book : BookMap.values()) {
list.add(book);
}
return list;
}
/**
* 模糊查询图书(根据出版时间降序)
*
* @param type
* 查询类别:书名/作者
*
* @param keywords
* 查询关键字
*
* @return 查询到的图书集合
*/
@Override
public List<Book> queryBook(String type, String keywords) {
List<Book> list = new ArrayList<Book>();
for (Book book : getAllBook()) {
if (type.equals("1") && book.getBookName().contains(keywords)) {
list.add(book);
} else if (type.equals("2") && book.getBookAuthor().contains(keywords)) {
list.add(book);
}
}
return list;
}
/**
* 添加图书
*
* @param flight
* 待添加的图书
*
* @return 是否添加成功1/0
*/
@Override
public int addBook(Book book) {
int result = 1;
if (BookMap.containsKey(book.getBookId())) {
result = 0;
} else {
BookMap.put(book.getBookId(), book);
}
return result;
}
/**
* 删除图书
*
* @param bookId
* 待删除的图书编号
*
* @return 1:删除成功 / 0:删除是吧
*/
@Override
public int deleteBook(String bookId) {
int result = 0;
if (BookMap.containsKey(bookId)) {
BookMap.remove(bookId);
result = 1;
} else {
result = 0;
}
return result;
}
/**
* 将查询结果导出到txt文件
*
* @param bookList
* 查询到的图书集合
*
* @param txtPath
* txt文件路径
*
*/
@Override
public void exportToTxt(List<Book> bookList, String txtPath) {
File file = new File(txtPath);
OutputStream out = null;
try {
out = new FileOutputStream(file);
String str = "";
for (Book book : bookList) {
str = str + book + "\n";
}
byte[] bs = str.getBytes();
out.write(bs);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 将图书信息保存到xml文件中
*
* @param xmlPath
*/
@Override
public void saveXml(String xmlPath) {
Element root = document.getRootElement();
List<Element> list = root.elements();
for (Element element : list) {
root.remove(element);
}
for (Book book : getAllBook()) {
Element element = root.addElement("book");
element.addAttribute("bookId", book.getBookId());
element.addElement("bookName").setText(book.getBookName());
element.addElement("bookAuthor").setText(book.getBookAuthor());
element.addElement("bookPublish").setText(book.getBookPublish());
element.addElement("bookPrice").setText(book.getBookPrice() + "");
element.addElement("publishDate").setText(Utils.dateTostr(book.getPublishDate()));
}
OutputStream out = null;
XMLWriter xmlWriter = null;
try {
out = new FileOutputStream(xmlPath);
OutputFormat format = new OutputFormat().createPrettyPrint();
xmlWriter = new XMLWriter(out, format);
xmlWriter.write(document);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
xmlWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
BookDao
package cn.kgc.tangcco.chengxiangjian.dao;
import java.util.List;
import cn.kgc.tangcco.chengxiangjian.entity.Book;
public interface BookDao {
/**
* 从xml文件导入所有图书
*
* @param xmlPath
* 文件地址
*/
void importFromXml(String xmlPath);
/**
* 获取所有图书信息(根据出版时间降序)
*
* @return 所有图书集合
*/
List<Book> getAllBook();
/**
* 模糊查询图书(根据出版时间降序)
*
* @param type
* 查询类别:书名/作者
* @param keywords
* 查询关键字
* @return 查询到的图书集合
*/
List<Book> queryBook(String type, String keywords);
/**
* 添加图书
*
* @param flight
* 待添加的图书
* @return 是否添加成功1/0
*/
int addBook(Book book);
/**
* 删除图书
*
* @param bookId
* 待删除的图书编号
* @return 1:删除成功 / 0:删除是吧
*/
int deleteBook(String bookId);
/**
* 将查询结果导出到txt文件
*
* @param bookList
* 查询到的图书集合
* @param txtPath
* txt文件路径
*/
void exportToTxt(List<Book> bookList, String txtPath);
/**
* 将图书信息保存到xml文件中
*
* @param xmlPath
*/
void saveXml(String xmlPath);
}
BookServiceImp
package cn.kgc.tangcco.chengxiangjian.service.impl;
import java.util.List;
import cn.kgc.tangcco.chengxiangjian.common.Property;
import cn.kgc.tangcco.chengxiangjian.common.PropertyFactory;
import cn.kgc.tangcco.chengxiangjian.dao.BookDao;
import cn.kgc.tangcco.chengxiangjian.entity.Book;
import cn.kgc.tangcco.chengxiangjian.service.BookService;
public class BookServiceImp implements BookService {
// 工厂模式创建BookDaoImp对象
private BookDao bookDao = PropertyFactory.getInstence(Property.getUrl(Property.DAO));
// 返回全部图书数组
public List<Book> showAll() {
return bookDao.getAllBook();
}
// 返回查询到的图书数组
public List<Book> queryBook(String type, String keywords) {
return bookDao.queryBook(type, keywords);
}
// 保存到txt文件
public String saveTxt(List<Book> bookList) {
String message = "";
String txtPath = "src/files/books.txt";
bookDao.exportToTxt(bookList, txtPath);
if (txtPath.isEmpty()) {
message = "导出失败";
} else {
message = "导出成功,文件在" + txtPath;
}
return message;
}
// 添加图书
public String add(Book book) {
String message = "";
if (bookDao.addBook(book) == 1) {
message = "添加成功";
} else {
message = "添加失败,图书编号重复";
}
return message;
}
// 删除图书
public String del(String bookId) {
String message = "";
if (bookDao.deleteBook(bookId) == 1) {
message = "删除成功";
} else {
message = "删除失败,图书编号不存在";
}
return message;
}
// 保存到xml文件
public String savaXml() {
String message = "";
String xmlPath = "src/files/books.xml";
bookDao.saveXml(xmlPath);
if (xmlPath.isEmpty()) {
message = "保存失败";
} else {
message = "保存成功";
}
return message;
}
}
BookService
package cn.kgc.tangcco.chengxiangjian.service;
import java.util.List;
import cn.kgc.tangcco.chengxiangjian.entity.Book;
public interface BookService {
// 返回全部图书数组
List<Book> showAll();
// 返回查询到的图书数组
List<Book> queryBook(String type, String keywords);
// 保存到txt文件
String saveTxt(List<Book> bookList);
// 添加图书
String add(Book book);
// 删除图书
String del(String bookId);
// 保存到xml文件
String savaXml();
}
Property
package cn.kgc.tangcco.chengxiangjian.common;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Property {
// 创建map集合,用于解析applicationContext.xml后存放数据
private static Map<String, String> map = new ConcurrentHashMap<String, String>();
// 设定常量值
public static final String DAO = "dao";
public static final String SER = "ser";
// 解析applicationContext.xml文件,数据存入map集合
static {
SAXReader saxReader = new SAXReader();
try {
Document document = saxReader.read(new File("src/files/applicationContext.xml"));
Element root = document.getRootElement();
List<Element> list = root.elements();
for (Element element : list) {
String key = element.attributeValue("id");
String value = element.attributeValue("class");
map.put(key, value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 根据键,返回对应的值
public static String getUrl(String key) {
return map.get(key);
}
}
PropertyFactory
package cn.kgc.tangcco.chengxiangjian.common;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
//工厂模式
public class PropertyFactory {
// 创建map集合
private static Map<String, Object> map = new ConcurrentHashMap<String, Object>();
// 反射模式创建对象
public static <E> E getInstence(String key) {
E object = null;
if (map.containsKey(key)) {
object = (E) map.get(key);
}
try {
Class clz = Class.forName(key);
object = (E) clz.newInstance();
map.put(key, object);
} catch (Exception e) {
e.printStackTrace();
}
return object;
}
}
Utils
package cn.kgc.tangcco.chengxiangjian.common;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class Utils {
private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
// 字符串转日期
public static String dateTostr(Date date) {
return format.format(date);
}
// 日期转字符串
public static Date strToDate(String str) {
try {
return format.parse(str);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
BookAction
package cn.kgc.tangcco.chengxiangjian.action;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
import javax.sound.midi.VoiceStatus;
import org.omg.CORBA.PUBLIC_MEMBER;
import cn.kgc.tangcco.chengxiangjian.common.Property;
import cn.kgc.tangcco.chengxiangjian.common.PropertyFactory;
import cn.kgc.tangcco.chengxiangjian.common.Utils;
import cn.kgc.tangcco.chengxiangjian.entity.Book;
import cn.kgc.tangcco.chengxiangjian.service.BookService;
public class BookAction {
// 工厂模式创建BookServiceImp对象
BookService service = PropertyFactory.getInstence(Property.getUrl(Property.SER));
Scanner scanner = new Scanner(System.in);
// 功能菜单
public void menu() {
System.out.println("1.显示所有图书信息(根据出版时间降序)");
System.out.println("2.查询图书(出版时间降序)");
System.out.println("3.添加图书");
System.out.println("4.删除图书");
System.out.println("0.退出");
System.out.print("请输入>>>");
int key = scanner.nextInt();
switch (key) {
case 1:
showAll();
break;
case 2:
query();
break;
case 3:
add();
break;
case 4:
del();
break;
case 0:
exit();
return;
default:
System.out.println("输入错误,请重新输入:");
return;
}
menu();
}
// 显示菜单
public void showAll() {
List<Book> list = service.showAll();
Collections.sort(list);
Collections.reverse(list);
for (Book book : list) {
System.out.println(book);
}
}
// 查询菜单,支持模糊查询
public void query() {
System.out.print("请选择查询方式:1.根据书名查询2.根据作者查询");
String type = scanner.next();
String keywords = "";
if (type.equals("1")) {
System.out.print("请输入书名(支持模糊查询):");
keywords = scanner.next();
} else if (type.equals("2")) {
System.out.print("请输入作者(支持模糊查询):");
keywords = scanner.next();
}
System.out.println("查询结果如下:");
List<Book> bookList = service.queryBook(type, keywords);
if (bookList.isEmpty()) {
System.out.println("没有符合条件的信息");
} else {
Collections.sort(bookList);
Collections.reverse(bookList);
for (Book book : bookList) {
System.out.println(book);
}
System.out.println("按任意键继续。。。");
Scanner sc = new Scanner(System.in);
String answer = sc.nextLine();
System.out.print("请问是否要将查询结果导出到txt文件:");
String key = scanner.next();
if (key.equals("y")) {
System.out.println(service.saveTxt(bookList));
} else {
return;
}
}
}
// 添加菜单
public void add() {
System.out.println("请输入图书编号:");
String BookId = scanner.next();
System.out.println("书名:");
String bookName = scanner.next();
System.out.println("作者:");
String bookAuthor = scanner.next();
System.out.println("出版社:");
String bookPublish = scanner.next();
System.out.println("价格:");
float bookPrice = scanner.nextFloat();
System.out.println("出版日期(例如:2019-05-17):");
Date publishDate = Utils.strToDate(scanner.next());
Book book = new Book(BookId, bookName, bookAuthor, bookPublish, bookPrice, publishDate);
System.out.println(service.add(book));
}
// 删除菜单
public void del() {
System.out.println("请输入要删除的图书编号:");
String bookId = scanner.next();
System.out.println(service.del(bookId));
}
// 退出菜单
public void exit() {
System.out.println("是否保存修改y/n");
String xmlPath = "src/files/books.xml";
String answer = scanner.next();
if (answer.equals("y")) {
System.out.println(service.savaXml());
} else {
System.out.println("文件未保存");
}
System.out.println("程序结束!");
}
}
Test
package cn.kgc.tangcco.chengxiangjian.test;
import cn.kgc.tangcco.chengxiangjian.action.BookAction;
public class Test {
// 创建main方法
public static void main(String[] args) {
// 实例化BookAction
BookAction b = new BookAction();
// 调用menu()方法
b.menu();
}
}