【项目实战】 图书信息管理系统(Maven,mybatis)(第一个自己独立完成的项目2)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介: 【项目实战】 图书信息管理系统(Maven,mybatis)(第一个自己独立完成的项目)

六、代码清单


1.项目结构全览

q1.png

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  注:&lt;指的是<,在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 &lt;=#{time}
            </if>
            <if test="price != null and price !=''">
                AND b.price &lt;=#{price}
            </if>
        </where>
    </select>
    <!-- 查询小于条件的结果   注:&lt;指的是<,在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模式

q3.png

①录入信息:

q2.png

②图书信息浏览


q1.png

③插入图书信息

w2.png

w1.png

注:因为我数据库里的时钟设置的是UTC

q5.png

所以存储的日期比我输入的日期提早一天


④查询,以按价格查询(小于)为例

q4.png

q3.png

⑤排序,以按价格排序为例

q2.png


⑥修改图书信息

q1.png


q5.png

⑦删除图书信息

q4.png

q3.png


⑧导出为文件

q2.png

q1.png

q2.png

2.noSql模式

NoSql模式与Sql模式区别只是底层实现原理不同,其测试效果是几乎一致的,在此,就只展现该模式的部分功能

q1.png

①插入图书信息

q3.png

q2.png

其余功能就不展示测试效果图了,其效果和Sql模式是一致的。

q1.png



相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
相关文章
|
11天前
|
Java Apache Maven
Maven 项目文档
在`C:/MVN/consumerBanking`中创建Maven Java项目,使用命令`mvn archetype:generate`生成基础结构。确保`pom.xml`包含`maven-site-plugin`和`maven-project-info-reports-plugin`,版本至少为3.3和2.7,以避免`NoClassDefFoundError`。运行`mvn site`生成文档。
|
3天前
|
Java Maven
Maven如何创建Maven web项目
Maven如何创建Maven web项目
|
6天前
|
Java Apache Maven
Maven 项目文档
使用Maven创建`consumerBanking`项目,执行`mvn archetype:generate`命令初始化。确保`pom.xml`包含`maven-site-plugin`至少版本3.3和`maven-project-info-reports-plugin`至少版本2.7,以避免NoClassDefFoundError。升级插件解决文档构建问题。
|
11天前
|
Java Apache Maven
Maven 项目文档
在`C:/MVN/consumerBanking`,使用`mvn archetype:generate`命令创建Java项目后,确保更新`pom.xml`,添加`maven-site-plugin`和`maven-project-info-reports-plugin`,至少版本3.3和2.7。运行`mvn site`时遇到`NoClassDefFoundError`,需升级`maven-site-plugin`至3.3以上以解决。
|
2天前
|
Java 数据库连接 数据库
大事件后端项目05-----springboot整合mybatis
大事件后端项目05-----springboot整合mybatis
大事件后端项目05-----springboot整合mybatis
|
6天前
|
存储 安全 Java
2024ide构建maven项目是总是卡在解析Maven依赖项目 加速方案
2024ide构建maven项目是总是卡在解析Maven依赖项目 加速方案
16 4
2024ide构建maven项目是总是卡在解析Maven依赖项目 加速方案
|
6天前
|
Java 程序员
浅浅纪念花一个月完成Springboot+Mybatis+Springmvc+Vue2+elementUI的前后端交互入门项目
浅浅纪念花一个月完成Springboot+Mybatis+Springmvc+Vue2+elementUI的前后端交互入门项目
19 1
|
1天前
|
Java Shell Apache
Maven 项目文档
使用 Maven 创建 `consumerBanking` 项目,命令行输入: ```sh mvn archetype:generate -DgroupId=com.companyname.bank -DartifactId=consumerBanking -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false ``` 确保 `pom.xml` 包含最新 `maven-site-plugin`(v3.3+)和 `maven-project-info-reports-plugin`(v2.7+)
|
2天前
|
数据可视化 Java Apache
Maven Dependency Tree:深入理解你的项目依赖
Maven Dependency Tree:深入理解你的项目依赖
10 0
|
6天前
|
Java Maven
Maven项目打包成jar项目后运行报错误: 找不到或无法加载主类 Main.Main 和 jar中没有主清单属性解决方案
Maven项目打包成jar项目后运行报错误: 找不到或无法加载主类 Main.Main 和 jar中没有主清单属性解决方案
14 0

相关实验场景

更多