六、代码清单
1.项目结构全览
2. 实体类Book
ackage com.dreamchaser.domain; import java.math.BigDecimal; import java.util.Date; /** * books * * @author 金昊霖 */ public class Book { /** 图书编号 */ private Integer id; /** 图书名称 */ private String title; /** 作者姓名 */ private String name; /** 出版社 */ private String publisher; /** 出版时间 */ private Date time; /** 价格 */ private BigDecimal price; public Book() { } /** * 用于清空对象里的数据 */ public void clear(){ this.id=null; this.title=null; this.name=null; this.publisher=null; this.time=null; this.price=null; } public Book(Integer id, String title, String name, String publisher, Date time, BigDecimal price) { this.id = id; this.title = title; this.name = name; this.publisher = publisher; this.time = time; this.price = price; } public Book(BigDecimal price) { this.price = price; } /** * 获取图书编号 * * @return 图书编号 */ public Integer getId() { return this.id; } /** * 设置图书编号 * * @param id * 图书编号 */ public void setId(Integer id) { this.id = id; } /** * 获取图书名称 * * @return 图书名称 */ public String getTitle() { return this.title; } /** * 设置图书名称 * * @param title * 图书名称 */ public void setTitle(String title) { this.title = title; } /** * 获取作者姓名 * * @return 作者姓名 */ public String getName() { return this.name; } /** * 设置作者姓名 * * @param name * 作者姓名 */ public void setName(String name) { this.name = name; } /** * 获取出版社 * * @return 出版社 */ public String getPublisher() { return this.publisher; } /** * 设置出版社 * * @param publisher * 出版社 */ public void setPublisher(String publisher) { this.publisher = publisher; } /** * 获取出版时间 * * @return 出版时间 */ public Date getTime() { return this.time; } /** * 设置出版时间 * * @param time * 出版时间 */ public void setTime(Date time) { this.time = time; } /** * 获取价格 * * @return 价格 */ public BigDecimal getPrice() { return this.price; } /** * 设置价格 * * @param price * 价格 */ public void setPrice(BigDecimal price) { this.price = price; } }
3.Mapper映射
①接口类 BooKMapper
package com.dreamchaser.mapper; import com.dreamchaser.domain.Book; import java.util.List; import java.util.Map; public interface BookMapper { public List<Book> selectSmaller(Map<String,Object> map); public List<Book> selectAll(); public List<Book> selectBigger(Map<String,Object> map); public List<Book> findBookByCondition(Map<String,Object> map); public List<Book> findBooksById(int id); public void insertBook(Map<String,Object> map); public void insertBooks(List<Book> books); public void updateBookById(Map<String,Object> map); public void updateBooks(List<Map<String,Object>> list); public void deleteBookById(int id); public void deleteBooksByIds(List<Integer> ids); /** * @param map 要注意这里的map中只能有一个对象 * @return */ public List<Book> findBookByConditionO(Map<String,Object> map); }
②BookMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- books 路径不是/,而是.!!!--> <mapper namespace="com.dreamchaser.mapper.BookMapper"> <!-- 字段映射 --> <resultMap id="booksMap" type="Book"> <!--设置主键,提高mybatis性能--> <id property="id" column="id"/> </resultMap> <!-- 表查询字段 --> <sql id="allColumns"> b.id, b.title, b.name, b.publisher, b.time, b.price </sql> <!-- 查询小于条件的结果 多条会自动打包成list 注:<指的是<,在xml中<是非法的 --> <select id="selectSmaller" parameterType="map" resultMap="booksMap"> SELECT <include refid="allColumns"/> from books b <where> <if test="time != null and time!=''"> AND b.time <=#{time} </if> <if test="price != null and price !=''"> AND b.price <=#{price} </if> </where> </select> <!-- 查询小于条件的结果 注:<指的是<,在xml中<是非法的 --> <select id="selectBigger" parameterType="map" resultMap="booksMap"> SELECT <include refid="allColumns"/> from books b <where> <if test="time != null and time!=''"> AND b.time >=#{time} </if> <if test="price != null and price !=''"> AND b.price >=#{price} </if> </where> </select> <!-- 查询所有数据 --> <select id="selectAll" resultMap="booksMap"> SELECT <include refid="allColumns" /> FROM books b </select> <!-- 根据条件参数查询数据列表 --> <select id="findBookByCondition" resultMap="booksMap" parameterType="map"> SELECT <include refid="allColumns" /> FROM books b WHERE 1 = 1 <if test="title != null and title != ''"> AND b.title LIKE CONCAT('%', #{title}, '%') </if> <if test="name != null and name != ''"> AND b.name LIKE CONCAT('%', #{name}, '%') </if> <if test="publisher != null and publisher != ''"> AND b.publisher LIKE CONCAT('%', #{publisher}, '%') </if> <if test="time != null"> AND b.time = #{time} </if> <if test="price != null"> AND b.price = #{price} </if> </select> <!-- 根据主键查询数据 --> <select id="findBooksById" resultMap="booksMap" parameterType="int"> SELECT <include refid="allColumns" /> FROM books b WHERE b.id =#{id} </select> <!-- 插入数据 --> <insert id="insertBook" parameterType="map"> INSERT INTO books ( id, title, name, publisher, time, price ) VALUES ( #{id}, #{title}, #{name}, #{publisher}, #{time}, #{price} ) </insert> <!-- 批量插入数据 --> <insert id="insertBooks" parameterType="list"> INSERT INTO books ( id, title, name, publisher, time, price ) VALUES <foreach collection="list" index="index" item="item" separator=","> ( #{item.id}, #{item.title}, #{item.name}, #{item.publisher}, #{item.time}, #{item.price} ) </foreach> </insert> <!-- 修改数据 --> <update id="updateBookById" parameterType="map"> UPDATE books <set> <if test="title != null"> title = #{title}, </if> <if test="name != null"> name = #{name}, </if> <if test="publisher != null"> publisher = #{publisher}, </if> <if test="time != null"> time = #{time}, </if> <if test="price != null"> price = #{price} </if> </set> WHERE id = #{id} </update> <!-- 批量修改数据 --> <update id="updateBooks" parameterType="list"> <foreach collection="list" index="index" item="item" separator=";"> UPDATE books <set> <if test="item.title != null"> title = #{item.title}, </if> <if test="item.name != null"> name = #{item.name}, </if> <if test="item.publisher != null"> publisher = #{item.publisher}, </if> <if test="item.time != null"> time = #{item.time}, </if> <if test="item.price != null"> price = #{item.price} </if> </set> WHERE id = #{item.id} </foreach> </update> <!-- 根据主键删除数据 --> <delete id="deleteBookById" parameterType="int"> DELETE FROM books WHERE id = #{id} </delete> <!-- 根据主键批量删除数据 --> <delete id="deleteBooksByIds" parameterType="list"> DELETE FROM books WHERE id IN <foreach collection="list" index="index" item="id" open="(" separator="," close=")"> #{id} </foreach> </delete> <!-- 根据条件排序查询--> <select id="findBookByConditionO" resultMap="booksMap" parameterType="map"> SELECT <include refid="allColumns" /> FROM books b WHERE 1 = 1 <if test="title != null and title != ''"> ORDER BY title </if> <if test="name != null and name != ''"> ORDER BY name </if> <if test="time != null"> ORDER BY time </if> <if test="price != null"> ORDER BY price </if> </select> </mapper>
4.工具类 {#工具类 .list-paragraph}
①日期工具类 DateUtil
用于Date和字符串之间的转换 package com.dreamchaser.util; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; /** * 日期工具类,用于date和字符串之间的转换 * @author 金昊霖 */ public class DateUtil { public static String dateToString(Date date,String format){ return new SimpleDateFormat(format).format(date); } public static Date stringToDate(String date,String format){ try { return new SimpleDateFormat(date).parse(date); } catch (ParseException e) { e.printStackTrace(); } return null; } }
②展示工具类 Displayer
用于展示传入的数据 package com.dreamchaser.util; import com.dreamchaser.domain.Book; import java.util.List; /** * 显示类,用于展示传入的数据 * * @author 金昊霖 */ public class Displayer { // public static void main(String[] args) { // Book book = new Book(123, "狂人日记", "鲁迅", "追梦出版社", new Date("2020/6/18"), // new BigDecimal("30.06")); // List<Book> list = new LinkedList<>(); // list.add(book); // show(list); // } public static void show(List<Book> list) { System.out.println("--------------------------------------------------------------------------"); System.out.println("| 图书编号 书名 作者名 出版单位 出版时间 价格 |"); for (Book book : list) { String date=""; if (book.getTime()!=null){ date=DateUtil.dateToString(book.getTime(),"yyyy-MM-dd"); } System.out.println("| " + book.getId() + " " + book.getTitle() + " " + book.getName() + " " + book.getPublisher() + " "+date+ " " + book.getPrice() + " |"); } System.out.println("--------------------------------------------------------------------------"); } public static void show(Book book) { System.out.println("-------------------------------------------------------------------------"); System.out.println("| 图书编号 书名 作者名 出版单位 出版时间 价格 |"); String date=""; if (book.getTime()!=null){ date=DateUtil.dateToString(book.getTime(),"yyyy-MM-dd"); } System.out.println("| " + book.getId() + " " + book.getTitle() + " " + book.getName() + " " + book.getPublisher() + " "+date+ " " + book.getPrice() + " |"); System.out.println("-------------------------------------------------------------------------"); } }
③文件工具类 FileUtil
package com.dreamchaser.util; import com.dreamchaser.domain.Book; import java.io.*; import java.util.ArrayList; import java.util.List; /** * 读取文件工具类 */ public class FileUtil { /** * 读取txt文件内容 * @param path 文件路径 * @return List<String> txt文件内容封装成一个list返回,如果文件不存在就返回null */ public static List<String> readTxtFile(String path){ File file=new File(path); List<String> list=new ArrayList<>(); if (file.exists()&&file.isFile()){ BufferedReader reader=null; try { reader=new BufferedReader(new FileReader(file)); String line=null; while ((line=reader.readLine())!=null){ list.add(line); } return list; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { try { //最后将输入流关闭 reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } public static boolean writeFile(List<Book> list,String path){ File file=new File(path); if (file.exists()&&file.isFile()){ try { BufferedWriter bufferedWriter=new BufferedWriter(new FileWriter(file)); for (Book book:list){ bufferedWriter.write(book.getId()+" "); bufferedWriter.write(book.getTitle()+" "); bufferedWriter.write(book.getName()+" "); bufferedWriter.write(book.getPublisher()+" "); bufferedWriter.write(book.getTime()+" "); bufferedWriter.write(book.getPrice()+" "); bufferedWriter.newLine(); bufferedWriter.flush(); bufferedWriter.close(); return true; } } catch (IOException e) { e.printStackTrace(); } } return false; }
④SqlSession工具类
用于返回所需的SqlSession对象
package com.dreamchaser.util; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.InputStream; /** * SqlSession工具类 * 用于产生sqlSession */ public class SqlSessionUtil { public SqlSession getSqlSession(){ // 指定全局配置文件 String resource = "mybatis-config.xml"; // 读取配置文件 InputStream inputStream = null; try { inputStream = Resources.getResourceAsStream(resource); } catch (IOException e) { e.printStackTrace(); } // 构建sqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); return sqlSessionFactory.openSession(); } }
5.模块类 {#模块类 .list-paragraph}
①总驱动类 Driver
用于整个项目的驱动 package com.dreamchaser; import java.util.Scanner; /** * 驱动类 * 主要负责统一Sql和NoSql两个模式 * 为了便捷,功能之间采用“套娃”的方式连接(实质就是避免递归调用造成堆栈溢出) * 套娃的基本思路:每个函数都有一个整数类型的返回值,只要返回1,就能返回上一级(实现原理,由该函数(记为函数1)的 * 上一级(记为函数2)控制,如果函数1返回一了,就在函数2的上一级(记为函数3)再次调用函数2,即可做到返回上一层; * 而如果函数1返回0则在函数2再次循环调用,直至函数返回1) * 这样做不仅能实现功能,而且能避免多次“套娃”导致堆栈溢出的风险 * @author 金昊霖 */ public class Driver { static Scanner scanner = new Scanner(System.in); public static void main(String[] args) { while (true) { if (choosePattern(1) == 1) { break; } } } /** * 一级模块 * 选择模式模块 * i 用于递归时判断其是否是第一次来还是输入错误来的 * * @return 用于判断函数状态,0表示继续呆在这层,1表示退回上一层 */ private static int choosePattern(int i) { if (i == 1) { System.out.println("\n\n\n||||图书信息管理系统|||| \n"); System.out.println("技术栈选择:mysql+mybatis+java"); System.out.println("作者:软工1902 金昊霖\n"); System.out.println("请选择存储模式:"); System.out.println("1.mysql存储(持久化规范数据存储)"); System.out.println("2.简单运存存储(如要数据持久化,则需导出文件)"); System.out.println("3.退出该系统\n\n"); System.out.println("请输入你的选择(序号):"); } switch (scanner.nextInt()) { case 1: //这样做既能使其能返回上一级,而且想留在此级时不会造成“无限套娃”,即堆栈不断压缩的情况 while (true) { if (PatternSql.chooseFunction(1) == 1) { return 0; } } case 2: while (true) { if (PatternNoSql.chooseFunction(1) == 1) { return 0; } } case 3: return 1; default: System.out.println("抱歉,输入的是非法字符,请重新输入:"); //这里是采用递归,暂时没办法,如不采用会很麻烦 return choosePattern(0); } } }
②SqlPattern模块类
集成Sql模式 package com.dreamchaser; import com.dreamchaser.mapper.BookMapper; import com.dreamchaser.domain.Book; import com.dreamchaser.util.DateUtil; import com.dreamchaser.util.Displayer; import com.dreamchaser.util.FileUtil; import com.dreamchaser.util.SqlSessionUtil; import org.apache.ibatis.session.SqlSession; import java.math.BigDecimal; import java.util.*; /** * Sql模式 */ public class PatternSql { static Scanner scanner = new Scanner(System.in); /** * mybatis中的sql */ static SqlSession sqlSession = new SqlSessionUtil().getSqlSession(); /** * 获取mybatis为我们创建好的Mapper对象 */ static BookMapper bookMapper = sqlSession.getMapper(BookMapper.class); /** * 空map,用于记录数据,每次方法加载时都要清空 */ static Map<String, Object> map = new HashMap<>(); /** * 测试xml到底有没有载入 * 这里就不删了,留作纪念 * @param args */ // public static void main(String[] args) { PatternSql patternSql=new PatternSql(); // SqlSession sqlSession =new SqlSessionUtil().getSqlSession(); // List list = sqlSession.selectList("com.dreamchaser.mapper.BookMapper.selectAll"); // Displayer.show(list); // } /** * 二级模块 * * @param i 用于递归时判断其是否是第一次来还是输入错误来的 * @return 用于返回上一级, 返回1就表示需要返回上一级,返回0则说明继续执行 */ public static int chooseFunction(int i) { if (i == 1) { System.out.println("\n\n功能:"); System.out.println("1.图书信息录入"); System.out.println("2.图书信息浏览"); System.out.println("3.插入图书信息"); System.out.println("4.查询"); System.out.println("5.排序"); System.out.println("6.修改图书信息"); System.out.println("7.删除图书信息"); System.out.println("8.导出为文件"); System.out.println("9.返回模式选择"); System.out.println("\n\n请输入你需要选择的功能(序号):"); } while (true) { switch (scanner.nextInt()) { case 1: saveFile(); return 0; case 2: selectAll(); return 0; case 3: addOneBook(); return 0; case 4: while (true) { if (chooseSelect(1) == 1) { return 0; } } case 5: while (true) { if (chooseOrder(1) == 1) { return 0; } } case 6: updateBook(); return 0; case 7: deleteOne(); return 0; case 8: writeToFile(); return 0; case 9: return 1; default: System.out.println("抱歉,输入的是非法字符,请重新输入:"); return chooseFunction(0); } } } private static void deleteOne() { System.out.println("请输入你要删除书籍的图书编号:"); bookMapper.deleteBookById(scanner.nextInt()); System.out.println("删除成功!"); } private static void updateBook() { map.clear(); System.out.println("请输入你要更新的书籍图书编号:"); map.put("id", scanner.nextInt()); scanner.nextLine(); System.out.println("是否要修改其图书名称(若是,请输入其名称,若否,则输入“否”):"); String title = scanner.nextLine(); if (!title.equals("否")) { map.put("title", title); } System.out.println("是否要修改其作者姓名(若是,请输入其姓名,若否,则输入“否”):"); String name = scanner.nextLine(); if (!name.equals("否")) { map.put("name", name); } System.out.println("是否要修改其出版社(若是,请输入其出版社名称,若否,则输入“否”):"); String publisher = scanner.nextLine(); if (!publisher.equals("否")) { map.put("publisher", publisher); } System.out.println("是否要修改其出版时间(若是,请输入其时间,请以“2020/10/06”的形式输入时间,若否,则输入“否”):"); String time = scanner.nextLine(); if (!time.equals("否")) { map.put("time", new Date(time)); } System.out.println("是否要修改其价格(若是,请输入其价格,若否,则输入“否”):"); String price = scanner.nextLine(); if (!price.equals("否")) { map.put("price", new BigDecimal(price)); } bookMapper.updateBookById(map); System.out.println("更新成功!"); } private static void writeToFile() { System.out.println("请输入你要保存的文件名(如:dreamchaser.txt):"); scanner.nextLine(); Boolean flag=FileUtil.writeFile(bookMapper.selectAll(),scanner.nextLine()); if (flag){ System.out.println("保存成功!"); }else { System.out.println("保存失败,请确认输入的文件路径是否正确!"); } } private static void saveFile() { System.out.println("请输入要录入的文件(txt,且需每一行都是一条记录)路径(绝对路径或者相对路径皆可):"); //把回车吃掉 scanner.nextLine(); List<String> list = FileUtil.readTxtFile(scanner.nextLine()); String[] strings=null; if (list!=null){ for (String s:list){ strings=s.split(" |\n"); map.clear(); map.put("id",strings[0]); map.put("title",strings[1]); map.put("name",strings[2]); map.put("publisher",strings[3]); map.put("time", DateUtil.stringToDate(strings[4],"yyyy/MM/dd")); map.put("price",new BigDecimal(strings[5])); bookMapper.insertBook(map); } System.out.println("录入成功"); }else { System.out.println("文件未找到或者文件不符合要求。请重新输入!"); } } private static void selectAll() { List<Book> books = bookMapper.selectAll(); Displayer.show(books); } private static void addOneBook() { map.clear(); System.out.println("请输入你要插入书籍的图书编号:"); map.put("id", scanner.nextInt()); scanner.nextLine(); System.out.println("请输入你要插入书籍的图书名称:"); String title = scanner.nextLine(); map.put("title", title); System.out.println("请输入你要插入书籍的作者姓名:"); String name = scanner.nextLine(); map.put("name", name); System.out.println("请输入你要插入书籍的出版社(若是,请输入其出版社名称,若否,则输入“否”):"); String publisher = scanner.nextLine(); if (!publisher.equals("否")) { map.put("publisher", publisher); } System.out.println("请输入你要插入书籍的出版时间(若是,请输入其时间,请以“2020/10/06”的形式输入时间,若否,则输入“否”):"); String time = scanner.nextLine(); if (!time.equals("否")) { map.put("time", new Date(time)); } System.out.println("请输入你要插入书籍的价格(若是,请输入其价格,若否,则输入“否”):"); String price = scanner.nextLine(); if (!price.equals("否")) { map.put("price", new BigDecimal(price)); } bookMapper.insertBook(map); System.out.println("插入成功"); } /** * 排序模块 * 三级模块 * * @param i * @return */ private static int chooseOrder(int i) { if (i == 1) { System.out.println("\n\n排序:"); System.out.println("1.按图书编号排序"); System.out.println("2.按书名排序"); System.out.println("3.按出版时间排序"); System.out.println("4.按价格排序等"); System.out.println("5.返回功能选择"); System.out.println("\n\n请输入你需要的排序方式(序号):"); } while (true) { switch (scanner.nextInt()) { case 1: selectOrderById(); return 0; case 2: selectOrderByTitle(); return 0; case 3: selectOrderByTime(); return 0; case 4: selectOrderByPrice(); return 0; case 5: return 1; default: System.out.println("抱歉,输入的是非法字符,请重新输入:"); return chooseFunction(0); } } } private static void selectOrderByPrice() { map.clear(); map.put("price", "1"); List<Book> books = bookMapper.findBookByConditionO(map); Displayer.show(books); } private static void selectOrderByTime() { map.clear(); map.put("time", "1"); List<Book> books = bookMapper.findBookByConditionO(map); Displayer.show(books); } private static void selectOrderByTitle() { map.clear(); map.put("title", "1"); List<Book> books = bookMapper.findBookByConditionO(map); Displayer.show(books); } private static void selectOrderById() { map.clear(); map.put("id", "1"); List<Book> books = bookMapper.findBookByConditionO(map); Displayer.show(books); } /** * 查询模块 * 三级模块 * * @param i * @return */ private static int chooseSelect(int i) { if (i == 1) { System.out.println("\n\n查询:"); System.out.println("1.按书名查询"); System.out.println("2.按作者名查询"); System.out.println("3.按价格查询(小于)"); System.out.println("4.按价格查询(等于)"); System.out.println("5.按价格查询(大于)"); System.out.println("6.返回模式选择"); System.out.println("\n\n请输入你需要的查询方式(序号):"); } while (true) { switch (scanner.nextInt()) { case 1: selectByTitle(); return 0; case 2: selectByName(); return 0; case 3: selectByPriceS(); return 0; case 4: selectByPrice(); return 0; case 5: selectByPriceB(); return 0; case 6: return 1; default: System.out.println("抱歉,输入的是非法字符,请重新输入:"); return chooseFunction(0); } } } private static void selectByPriceB() { System.out.println("请输入你要查询的价格:"); map.clear(); map.put("price", scanner.nextInt()); List<Book> books = bookMapper.selectBigger(map); Displayer.show(books); } private static void selectByPrice() { System.out.println("请输入你要查询的价格:"); map.clear(); map.put("price", scanner.nextInt()); List<Book> books = bookMapper.findBookByCondition(map); Displayer.show(books); } private static void selectByPriceS() { System.out.println("请输入你要查询的价格:"); map.clear(); map.put("price", new BigDecimal(scanner.nextInt())); List<Book> books = bookMapper.selectSmaller(map); Displayer.show(books); } private static void selectByName() { System.out.println("请输入你要查询的作者姓名:"); map.clear(); //因为后面是nextLine,而之前是nextInt,会算上回车键,所以得先用nextLine吃掉回车 scanner.nextLine(); map.put("name", scanner.nextLine()); List<Book> books = bookMapper.findBookByCondition(map); Displayer.show(books); } private static void selectByTitle() { System.out.println("请输入你要查询的书籍名称:"); map.clear(); scanner.nextLine(); map.put("title", scanner.nextLine()); List<Book> books = bookMapper.findBookByCondition(map); Displayer.show(books); } }
③noSql模块类
集成noSql模式 package com.dreamchaser; import com.dreamchaser.domain.Book; import com.dreamchaser.util.DateUtil; import com.dreamchaser.util.Displayer; import com.dreamchaser.util.FileUtil; import java.math.BigDecimal; import java.util.*; public class PatternNoSql { static Scanner scanner = new Scanner(System.in); /** * 维护的链表 */ static List<Book> list = new LinkedList<>(); static Book book = new Book(); /** * 二级模块 * * @param i 用于递归时判断其是否是第一次来还是输入错误来的 * @return 用于返回上一级, 返回1就表示需要返回上一级,返回0则说明继续执行 */ public static int chooseFunction(int i) { if (i == 1) { System.out.println("\n\n功能:"); System.out.println("1.图书信息录入"); System.out.println("2.图书信息浏览"); System.out.println("3.插入图书信息"); System.out.println("4.查询"); System.out.println("5.排序"); System.out.println("6.修改图书信息"); System.out.println("7.删除图书信息"); System.out.println("8.导出为文件"); System.out.println("9.返回模式选择"); System.out.println("\n\n请输入你需要选择的功能(序号):"); } while (true) { switch (scanner.nextInt()) { case 1: saveFile(); return 0; case 2: selectAll(); return 0; case 3: addOneBook(); return 0; case 4: while (true) { if (chooseSelect(1) == 1) { return 0; } } case 5: while (true) { if (chooseOrder(1) == 1) { return 0; } } case 6: updateBook(); return 0; case 7: deleteOne(); return 0; case 8: writeToFile(); return 0; case 9: return 1; default: System.out.println("抱歉,输入的是非法字符,请重新输入:"); return chooseFunction(0); } } } private static void writeToFile() { System.out.println("请输入你要保存的文件名(如:dreamchaser.txt):"); scanner.nextLine(); Boolean flag=FileUtil.writeFile(list,scanner.nextLine()); if (flag){ System.out.println("保存成功!"); }else { System.out.println("保存失败,请确认输入的文件路径是否正确!"); } } private static void deleteOne() { System.out.println("请输入你要删除书籍的图书编号:"); int id = scanner.nextInt(); boolean flag = list.removeIf(a -> a.getId() == id); if (flag) { System.out.println("删除成功!"); } else { System.out.println("未找到相应的图书!"); } } private static void updateBook() { book.clear(); System.out.println("请输入你要更新的书籍图书编号:"); book.setId(scanner.nextInt()); scanner.nextLine(); System.out.println("是否要修改其图书名称(若是,请输入其名称,若否,则输入“否”):"); String title = scanner.nextLine(); if (!title.equals("否")) { book.setTitle(title); } System.out.println("是否要修改其作者姓名(若是,请输入其姓名,若否,则输入“否”):"); String name = scanner.nextLine(); if (!name.equals("否")) { book.setName(name); } System.out.println("是否要修改其出版社(若是,请输入其出版社名称,若否,则输入“否”):"); String publisher = scanner.nextLine(); if (!publisher.equals("否")) { book.setPublisher(publisher); } System.out.println("是否要修改其出版时间(若是,请输入其时间,请以“2020/10/06”的形式输入时间,若否,则输入“否”):"); String time = scanner.nextLine(); if (!time.equals("否")) { book.setTime(new Date(time)); } System.out.println("是否要修改其价格(若是,请输入其价格,若否,则输入“否”):"); String price = scanner.nextLine(); if (!price.equals("否")) { book.setPrice(new BigDecimal(price)); } for (Book book1 : list) { if (book1.getId().equals(book.getId())) { list.remove(book1); list.add(book); } } System.out.println("更新成功!"); } private static void saveFile() { System.out.println("请输入要录入的文件(txt,且需每一行都是一条记录)路径(绝对路径或者相对路径皆可):"); //把回车吃掉 scanner.nextLine(); List<String> list1 = FileUtil.readTxtFile(scanner.nextLine()); String[] strings = null; if (list1 != null) { for (String s : list1) { strings = s.split(" |\n"); book.clear(); book.setId(Integer.parseInt(strings[0])); book.setTitle(strings[1]); book.setName(strings[2]); book.setPublisher(strings[3]); book.setTime(DateUtil.stringToDate(strings[4], "yyyy/MM/dd")); book.setPrice(new BigDecimal(strings[5])); list.add(book); } System.out.println("录入成功"); } else { System.out.println("文件未找到或者文件不符合要求。请重新输入!"); } } private static void selectAll() { Displayer.show(list); } private static void addOneBook() { book.clear(); System.out.println("请输入你要插入书籍的图书编号:"); book.setId(scanner.nextInt()); scanner.nextLine(); System.out.println("请输入你要插入书籍的图书名称:"); String title = scanner.nextLine(); book.setTitle(title); System.out.println("请输入你要插入书籍的作者姓名:"); String name = scanner.nextLine(); book.setName(name); System.out.println("请输入你要插入书籍的出版社(若是,请输入其出版社名称,若否,则输入“否”):"); String publisher = scanner.nextLine(); if (!publisher.equals("否")) { book.setPublisher(publisher); } System.out.println("请输入你要插入书籍的出版时间(若是,请输入其时间,请以“2020/10/06”的形式输入时间,若否,则输入“否”):"); String time = scanner.nextLine(); if (!time.equals("否")) { book.setTime(new Date(time)); } System.out.println("请输入你要插入书籍的价格(若是,请输入其价格,若否,则输入“否”):"); String price = scanner.nextLine(); if (!price.equals("否")) { book.setPrice(new BigDecimal(price)); } list.add(book); System.out.println("插入成功"); } /** * 排序模块 * 三级模块 * * @param i * @return */ private static int chooseOrder(int i) { if (i == 1) { System.out.println("\n\n排序:"); System.out.println("1.按图书编号排序"); System.out.println("2.按书名排序"); System.out.println("3.按出版时间排序"); System.out.println("4.按价格排序等"); System.out.println("5.返回功能选择"); System.out.println("\n\n请输入你需要的排序方式(序号):"); } while (true) { switch (scanner.nextInt()) { case 1: selectOrderById(); return 0; case 2: selectOrderByTitle(); return 0; case 3: selectOrderByTime(); return 0; case 4: selectOrderByPrice(); return 0; case 5: return 1; default: System.out.println("抱歉,输入的是非法字符,请重新输入:"); return chooseFunction(0); } } } private static void selectOrderByPrice() { /** * 把 x -> System.out.println(x) 简化为 System.out::println 的过程称之为 eta-conversion * 把 System.out::println 简化为 x -> System.out.println(x) 的过程称之为 eta-expansion * 范式: * 类名::方法名 * 方法调用 * * person -> person.getAge(); * 可以替换成 * Person::getAge * * x -> System.out.println(x) * 可以替换成 * System.out::println * out是一个PrintStream类的对象,println是该类的方法,依据x的类型来重载方法 * 创建对象 * * () -> new ArrayList<>(); * 可以替换为 * ArrayList::new */ list.sort(Comparator.comparing(Book::getPrice)); Displayer.show(list); } private static void selectOrderByTime() { list.sort(Comparator.comparing(Book::getTime)); Displayer.show(list); } private static void selectOrderByTitle() { list.sort(Comparator.comparing(Book::getTitle)); Displayer.show(list); } private static void selectOrderById() { list.sort(Comparator.comparing(Book::getId)); Displayer.show(list); } /** * 查询模块 * 三级模块 * * @param i * @return */ private static int chooseSelect(int i) { if (i == 1) { System.out.println("\n\n查询:"); System.out.println("1.按书名查询"); System.out.println("2.按作者名查询"); System.out.println("3.按价格查询(小于)"); System.out.println("4.按价格查询(等于)"); System.out.println("5.按价格查询(大于)"); System.out.println("6.返回模式选择"); System.out.println("\n\n请输入你需要的查询方式(序号):"); } while (true) { switch (scanner.nextInt()) { case 1: selectByTitle(); return 0; case 2: selectByName(); return 0; case 3: selectByPriceS(); return 0; case 4: selectByPrice(); return 0; case 5: selectByPriceB(); return 0; case 6: return 1; default: System.out.println("抱歉,输入的是非法字符,请重新输入:"); return chooseFunction(0); } } } private static void selectByPriceB() { System.out.println("请输入你要查询的价格:"); List<Book> result = new LinkedList<>(); for (Book book1 : list) { if (book1.getPrice().compareTo(new BigDecimal(scanner.nextInt())) == 1) { result.add(book1); } } Displayer.show(result); } private static void selectByPrice() { System.out.println("请输入你要查询的价格:"); List<Book> result = new LinkedList<>(); for (Book book1 : list) { if (book1.getPrice().compareTo(new BigDecimal(scanner.nextInt())) == 0) { result.add(book1); } } Displayer.show(result); } private static void selectByPriceS() { System.out.println("请输入你要查询的价格:"); List<Book> result = new LinkedList<>(); for (Book book1 : list) { if (book1.getPrice().compareTo(new BigDecimal(scanner.nextInt())) == -1) { result.add(book1); } } Displayer.show(result); } private static void selectByName() { System.out.println("请输入你要查询的作者姓名:"); //因为后面是nextLine,而之前是nextInt,会算上回车键,所以得先用nextLine吃掉回车 scanner.nextLine(); List<Book> result = new LinkedList<>(); for (Book book1 : list) { if (book1.getName().equals(scanner.nextLine())) { result.add(book1); } } Displayer.show(result); } private static void selectByTitle() { System.out.println("请输入你要查询的书籍名称:"); scanner.nextLine(); List<Book> result = new LinkedList<>(); for (Book book1 : list) { if (book1.getTitle().equals(scanner.nextLine())) { result.add(book1); } } Displayer.show(result); } }
6.配置文件 {#配置文件 .list-paragraph}
①db.properties
配置数据库的路径,用户密码等
dbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/library?serverTimezone=UTC jdbc.username=root jdbc.password=jinhaolin
②log4j.properties
配置log4j
log4j.rootCategory=DEBUG, CONSOLE,LOGFILE log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=-%p-%d{yyyy/MM/dd HH:mm:ss,SSS}-%l-%L-%m%n log4j.appender.LOGFILE=org.apache.log4j.FileAppender log4j.appender.LOGFILE.File=E:/axis.log log4j.appender.LOGFILE.Append=true log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout log4j.appender.LOGFILE.layout.ConversionPattern=-%p-%d{yyyy/MM/dd HH:mm:ss,SSS}-%l-%L-%m%n
③mybatis-config.xml
配置mybatis框架
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="db.properties"/> <!--用于开启缓存,优化查询速度,但基本没什么用,效果很不明显。 优化查询速度一般采取的措施: 1.构建索引 2.使用redio缓存数据库 3.使用搜索引擎(一般用于电商项目)--> <typeAliases> <!--方式一:为类起别名--> <!-- <typeAlias type="com.dreamchaser.domain.User" alias="user"/>--> <!--方式二:使用package起别名,该包下的类别名是mybatis自动为我们取好的,就是类名(不区分大小写,但最好按照约定 俗成的标准去写)--> <package name="com.dreamchaser.domain"/> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <!--注册中心,指定mapper映射文件--> <mappers> <!--方式一:单独注册--> <!-- <mapper resource="com/dreamchaser/dao/UserDao.xml"/>--> <!-- <mapper resource="com.dreamchaser.mapper/BookMapper.xml"/>--> <!--方式二:使用接口的全路径注册--> <!--方式三:批量注册,该包下的所有mapper映射文件自动注册(通常采用此种方法注册)--> <mapper resource="com.dreamchaser/mapper/BookMapper.xml"/> <!-- <package name="com.dreamchaser.mapper"/>--> </mappers> </configuration>
④pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>library</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>图书信息管理系统 Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.18</version> </dependency> </dependencies> <build> <finalName>图书信息管理系统</finalName> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.1.0</version> </plugin> <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.2</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> </plugins> </pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>8</source> <target>8</target> </configuration> </plugin> </plugins> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </resource> </resources> </build> </project>
七、部分测试结果展示
1.Sql模式
①录入信息:
②图书信息浏览
③插入图书信息
注:因为我数据库里的时钟设置的是UTC
所以存储的日期比我输入的日期提早一天
④查询,以按价格查询(小于)为例
⑤排序,以按价格排序为例
⑥修改图书信息
⑦删除图书信息
⑧导出为文件
2.noSql模式
NoSql模式与Sql模式区别只是底层实现原理不同,其测试效果是几乎一致的,在此,就只展现该模式的部分功能
①插入图书信息
其余功能就不展示测试效果图了,其效果和Sql模式是一致的。