基于SSM的图书管理系统

2023-11-15

一、系统简介

该项目是基于Java的SSM框架实现的图书管理系统

二、技术实现

1.后台框架:Spring、SpringMVC、MyBatis、Ajax

2.UI界面:BootStrap

3.数据库:MySQL 5.7

4.加密:md5+随机盐

运行环境:

JDK 8

IntelliJ IDEA

Tomcat 9.0

MySQL 5.7

三、系统功能

系统共分为三种用户:

1.普通用户

书籍列表显示、书籍借阅、书籍归还,

2.管理员

用户管理(删除用户,修改用户名),图书管理(编辑,删除,添加)

四、表设计

一共有三张表,book用来存放书籍信息,

bookorder用来保存借书记录和借还状态,user用来保存管理员和用户信息

book表结构(status用来表示书的借还状态,0表示已还,1表示未还)

bookorder表结构

User表结构(grade用于区分角色身份,0是管理员,1是普通用户)

五、运行效果

系统登陆界面:

注册界面(分为管理员注册和普通用户注册)

管理员界面

图书管理界面

普通用户管理界面

普通用户界面

借还书籍操作界面

需求分析:

1.租书

首先输入借书人名称,然后输入要借阅的图书编号,显示该图书信息(已经借出的图书不显示),

2.还书

首先输入借书人名称,显示该借书人的借阅图书信息,已还图书不显示。在显示借阅图书信息后,可以选择还书。

3.租还查询

选择该选项后,显示某个用户所有借书信息,

图书类型管理 图书类型信息包括:编号、名称

4. 添加图书

接收用户输入的图书信息,写入数据库。

5. 修改图书

用户输入要修改图书编号,显示图书信息,然后修改图书,并保存到数据库中。

6.删除图书 

用户输入要删除图书编号,删除图书。

7. 查询全部图书

选择该选项后,首先显示所有图书信息

8.修改用户信息

管理员可以修改用户的名称

9.用户登录

10.用户注册

Entity实体类

public class Book {

    private int bid;

    private String bookname;

    private String author;

    private String detail;

    private int status;//是否借出,1表示可以借,0表示不可借

    private int price;

    private String category;//种类

}
public class BookOrder {

    /**

     * 借书订单表

     */

    private int orderid;

    private int userid;

    private int bid;

    private int orderstatus;//借还状态 0表示已归还,1表示未归还

}
public class User {

    private int id;

    private String username;

    private String password;

    private int grade;//角色

}

Controller

@Controller

@RequestMapping("/admin")

public class AdminController {



    @Autowired

    private BookService bookService;



    @Autowired

    private UserService userService;



    //跳转到图书管理页面

    @RequestMapping("/bookManage.action")

    public String skipBookManage(Model model){

        List<Book> list = bookService.selectAllBook();

        model.addAttribute("list",list);

        return "bookManage";

    }



    //跳转到读者管理页面

    @RequestMapping("/commonUserManage.action")

    public String skipCommonUserManage(){

        return "commonUserManage";

    }



    /**

     * 读者操作

     *  可以让读者跳转到图书馆,User.jsp

     */



    //读者跳转到图书馆

    @RequestMapping("/user.action")

    public String skipUser(Model model,@Param("id") String username) throws UnsupportedEncodingException {

        //中文编码:

        /**

         * 在前端使用URL传递时,使用encodeURI(encodeURI(username))

         * 后端解析使用java.net.URLDecoder.decode(username,"UTF-8");

         */

        username = java.net.URLDecoder.decode(username,"UTF-8");

        System.out.println(username);

        model.addAttribute("user", userService.getUserByUserName(username).get(0));

        model.addAttribute("list",bookService.selectBookByStatus());

        return "user";

    }



    //跳转到admin.jsp

    @RequestMapping("/admin.action")

    public String skipAdmin(){

        return "admin";

    }



}


@Controller

@RequestMapping("/book")

public class BookController {

    @Autowired

    private BookService bookService;

    @Autowired

    private BookOrderService bookOrderService;

    //删除图书

    @RequestMapping("/deleteById.action")

    @ResponseBody

    public Map<String,String> deleyeById(@RequestParam("bid") int bid){

        bookService.deleteBook(bid);

        Map map = new HashMap<String,String>();

        map.put("msg","删除成功");

        return map;

    }

    //添加图书

    @RequestMapping("/addBook.action")

    @ResponseBody

    public int addBook(Book book){

        bookService.addBook(book);

        int i = bookService.selectLastNum();

        return i;

    }

    //修改图书

    @RequestMapping("/modify.action")

    @ResponseBody

    public int modifyBook(Book book){

        System.out.println(book);

        bookService.modifyBook(book);

        return book.getBid();

    }

    //借书

    /**

     * 借书所要进行的操作:

     *  将书籍状态改为0

     *  在记录单上添加该用户的信息以及对应的书ID,并设置该订单状态为未完成(未还书,还书即算本次订单完成,未完成状态为1,完成状态为0)

     * @param bid

     */

    @RequestMapping("/updateBookStatusToZero.action")

    @ResponseBody

    public int updateBookStatusToZero(@Param("id") int id ,@Param("bid") int bid){

        bookService.updateBookStatusToZero(bid);

        //借书订单添加用户以及对应的书籍ID

        bookOrderService.addOrder(id,bid);

        return bid;

    }

    //还书

    @RequestMapping("/updateBookStatusToOne.action")

    @ResponseBody

    public int updateBookStatusToOne(@Param("bid") int bid){

        //根据书籍的id更改书籍的状态为1

        bookService.updateBookStatusToOne(bid);

        //将订单的状态更改为0(我的借还中书籍的状态需要是1)

        bookOrderService.updateOrderStatus(bid);

        return bid;

    }

}
@Controller

@RequestMapping("/login")

public class UserController {

    @Autowired

    private BookService bookService;

    @Autowired

    private BookOrderService bookOrderService;

    @Autowired

    private UserService userService;

    //登录校验

    @RequestMapping("/checkLogin.action")

    public String checkLogin(@RequestParam("username")String username, @RequestParam("password")String password, Model model){

        Map map = userService.checkLogin(username,password);//校验,返回不同的返回值和角色存入map集合

        if(map.get("result").equals("login")){

            model.addAttribute("msg","账号或密码错误");

        }else if(map.get("result").equals("admin")) {

            model.addAttribute("user",map.get("user"));//如果是管理员返回管理员管理初始界面,并把管理员存入Attribute

        }else{//user

            List<Book> list = bookService.selectBookByStatus();//如果是普通用户,返回书籍展示页面并把普通用户存入Attribute

            model.addAttribute("list",list);

            model.addAttribute("user",map.get("user"));

        }

        return (String)map.get("result");//返回角色信息或者错误信息,经过前端ajax判断,如果不是错误信息,跳转到user或者admin的action里

    }

   //用户注册功能实现

    @RequestMapping(value = "/addUser.action")

    @ResponseBody()

    public Map<String, Boolean> addUser(User user, HttpServletRequest request, HttpServletResponse res) throws UnsupportedEncodingException {

        Map<String , Boolean> map = new HashMap<>();

        if(!userService.isInserUser(user)){//不可插入

            map.put("isUse",false);

            return map;

        }

        //对用户的密码进行md5加密

        String pwd = SecureUtil.md5(user.getPassword() + user.getUsername());

        user.setPassword(pwd);//把加密的密码设置给user

        userService.addUser(user);//执行添加操作

        map.put("msg",true);

        return map;

    }

    //用户注册

    //跳转到register.jsp

    @RequestMapping("/register.action")

    public String register(){

        return "register";

    }

    /*//前端跳转到的页面,暂未启用

    @RequestMapping("/admin.action")

    public String admin(int id){//传递的参数仅为跳转那个页面

        /*String result;

        if(id == 1){

            result = "bookManage";

        }else if(id == 2){

            result = "";

        }

        return result;

        return "";

    }*/

    //获取所有的普通User

    //跳转到getCommonUser.jsp

    @RequestMapping("/getCommonUser.action")

    public String getCommonUser(Model model){

        model.addAttribute("list",userService.getCommonUser());

        return "commonUserManage";

    }

    //删除某一个用户

    //跳转到deleteUser.jsp

    @RequestMapping("/deleteUser.action")

    @ResponseBody

    public Map<String ,String> deleteUser(@Param("id") int id){

        userService.deleteUser(id);

        Map<String,String> map = new HashMap<>();

        map.put("msg","删除成功!");

        return map;

    }

    //修改一个用户

    //跳转到modifyUser.jsp

    @RequestMapping("/modifyUser.action")

    @ResponseBody

    public int modifyUser(User user){

        System.out.println(user);

        userService.modifyUser(user);

        return user.getId();

    }

    //跳转到login.jsp

    @RequestMapping("/login.action")

    public String login(){

        return "login";

    }

    //我的借还跳转

    //跳转到myBorrow.jsp

    @RequestMapping("/myBorrow.action")

    public String myBorrow(Model model,int id){//一个参数为user 的id

        List<Book> list = bookOrderService.myBorrow(id);

        model.addAttribute("list",list);//传递的是我的借还的这个书籍id

        model.addAttribute("user",userService.getUserById(id).get(0));

        return "myBorrow";

    }

    //我的借还跳转到User.jsp

    @RequestMapping("/user.action")

    public String jumpUser(Model model,@Param("id") int id){

        //该方法需要传递一个书籍状态为1的书籍列表,key为list

        //还有一个是user的实例

        //user实例的获取:

        model.addAttribute("user",userService.getUserById(id).get(0));

        List<Book> list = bookService.selectBookByStatus();

        model.addAttribute("list",list);

        return "user";

    }

}

Service

public interface UserService {

    //检查登录

    public Map checkLogin(String username, String password);

    //添加用户

    public void addUser(User user);

    //查询根据用户名是否有重名

    public boolean isInserUser(User user);

    //查询所有的普通用户

    public List<User> getCommonUser();

    //删除用户

    public void deleteUser(int id);

    //修改用户

    public void modifyUser(User user);

    //根据id查询用户

    public List<User> getUserById(int id);

    public List<User> getUserByUserName(String username);

}

public interface BookService {

    //查询所有书籍

    public List<Book> selectAllBook();

    //添加书籍

    public int addBook(Book book);

    //删除图书

    public void deleteBook(int bid);

    //修改图书

    public void modifyBook(Book book);

    //查询库存

    public int selectBookNumByBookName(String bookname);

    //根据作者名查询图书

    public List<Book> selectBookByAuthor(String author);

    //查询最后一个主键

    public int selectLastNum();

    //查询图书状态为1的图书list,即可借状态

    public List<Book> selectBookByStatus();

    //借书

    public void updateBookStatusToZero(int bid);

    //还书

    public void updateBookStatusToOne(int bid);

}
public interface BookOrderService {

    /**

     * 添加图书订单

     * 更改订单状态

     */

    public void addOrder(int userId, int bid);

    public void updateOrderStatus(int bid);

    //查询我的借还

    public List<Book> myBorrow(int id);

}

Dao

public interface BookDao {

    /**

     * 书的操作:

     *  查询所有图书

     *  添加图书

     *  删除图书

     *  根据作者名查询图书

     *

     */

    @Select("select * from book")

    public List<Book> selectAllBook();

    @Insert("insert into book(bookname,author,detail,status,price,category) value(#{bookname},#{author},#{detail},${status},${price},#{category})")

    public void addBook(Book book);

    //查找最后一条记录的主键

    @Select("select max(bid) from book")

    public List<Integer> selectLastNum();


    @Delete("delete from book where bid = #{bid}")

    public void deleteBookById(int bid);


    @Select("select count(*) from book where bookname like #{bookname}")

    public int selectAllNum(String bookName);


    @Select("select * from book where author like #{author}")

    public List<Book> selectBookByAuthor(String author);

    //根据状态查询书籍,查询书籍状态为1的书籍,可借状态

    @Select("select * from book where status = 1")

    public List<Book> selectBookByStatus();


    //借书,即将书籍状态改为0

    @Select("update book set status = 0 where bid = #{bid}")

    public void updateBookStatusToZero(int bid);


    //还书,即将书籍状态改为1

    @Select("update book set status = 1 where bid = #{bid}")

    public void updateBookStatusToOne(int bid);


    //修改图书

    @Update("update book set bookname=#{bookname},author=#{author},detail=#{detail},price=#{price},category=#{category} where bid = #{bid}")

    public void modifyBook(Book book);

}
public interface BookOrderDao {

    /**

     * 图书订单Dao

     * 新建图书订单,UserId,BookId,订单状态为1,(订单状态为0时表示已还)

     * 还书操作:将订单状态置为0

     */


    //添加订单,当进行借书操作时需要

    @Insert("insert into bookorder(userid,bid,orderstatus) values(${id},${bid},1)")

    public void addOrder(@Param("id") int id, @Param("bid") int bid);


    //将订单状态置为0,表示已还,当进行还书操作时需要

    @Update("update bookorder set orderstatus = 0 where bid = #{bid}")

    public void updataOrderStatus(int bid);


    //根据userid查询对应的用户所有的订单

    @Select("SELECT * FROM book where bid = ANY(SELECT bid from bookorder WHERE userid = #{id} and orderstatus = 1)")

    public List<Book> selectOrder(int id);//用户的id

}
public interface UserDao {

    /**

     * 用户表操作的接口

     *  方法有:

     *      给定用户名,查询密码

     *      添加用户

     */

    //获取用户

    @Select("select * from user where username = #{username}")

    public List<User> getUser(String username);


    @Insert("insert into user(username,password,grade) value(#{username},#{password},#{grade})")

    public void addUser(User user);


    //查询所有普通用户

    @Select("select * from user where grade = 1")

    public List<User> getCommonUser();

    //删除指定用户

    @Delete("delete from user where id = #{id}")

    public void deleteUser(int id);

    @Update("update user set username = #{username},password = #{password} where id = #{id}")

    public void modifyUser(User user);


    //根据用户id获取用户信息

    @Select("select * from user where id = #{id}")

    public List<User> getUserById(int id);

}

ApplicationContext.xml配置

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:context="http://www.springframework.org/schema/context"

       xmlns:aop="http://www.springframework.org/schema/aop"

       xmlns:tx="http://www.springframework.org/schema/tx"

       xsi:schemaLocation="http://www.springframework.org/schema/beans

       http://www.springframework.org/schema/beans/spring-beans.xsd

       http://www.springframework.org/schema/context

       http://www.springframework.org/schema/context/spring-context.xsd

       http://www.springframework.org/schema/aop

       http://www.springframework.org/schema/aop/spring-aop.xsd

       http://www.springframework.org/schema/tx

       http://www.springframework.org/schema/tx/spring-tx.xsd">


    <!--开启注解的扫描,希望处理service和dao,controller不需要Spring框架去处理-->

    <context:component-scan base-package="com.gx" >

        <!--配置哪些注解不扫描-->

        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />

    </context:component-scan>


    <!--Spring整合MyBatis框架-->

    <!--配置连接池-->

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

        <property name="driverClass" value="com.mysql.jdbc.Driver"/>

        <property name="jdbcUrl" value="jdbc:mysql:///bookm?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=CST"/>

        <property name="user" value="root"/>

        <property name="password" value="zwh19991219"/>

    </bean>


    <!--配置SqlSessionFactory工厂-->

    <bean id="sqlSessonFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

        <property name="dataSource" ref="dataSource"/>

    </bean>


    <!--配置IAccountdao接口所在包-->

    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">

        <property name="basePackage" value="com.gx.dao"/>

    </bean>

    <!--配置Spring框架声明式事务管理-->

    <!--配置事务管理器-->

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

        <property name="dataSource" ref="dataSource" />

    </bean>


    <!--配置事务通知-->

    <tx:advice id="txAdvice" transaction-manager="transactionManager">

        <tx:attributes>

            <tx:method name="find*" read-only="true"/>

            <tx:method name="*" isolation="DEFAULT"/>

        </tx:attributes>

    </tx:advice>

    <!--配置AOP增强-->

    <aop:config>

        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.gx.service.impl.*ServiceImpl.*(..))"/>

    </aop:config>

</beans>

Springmvc.xml配置

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:mvc="http://www.springframework.org/schema/mvc"

       xmlns:context="http://www.springframework.org/schema/context"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xsi:schemaLocation="

        http://www.springframework.org/schema/beans

        http://www.springframework.org/schema/beans/spring-beans.xsd

        http://www.springframework.org/schema/mvc

        http://www.springframework.org/schema/mvc/spring-mvc.xsd

        http://www.springframework.org/schema/context

        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--开启注解扫描,只扫描Controller注解-->

    <context:component-scan base-package="com.gx">

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>

    </context:component-scan>


    <!--配置的视图解析器对象-->

    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

        <property name="prefix" value="/WEB-INF/pages/"/>

        <property name="suffix" value=".jsp"/>

    </bean>

    <!--过滤静态资源-->

    <mvc:resources location="/css" mapping="/css/**"/>

    <mvc:resources location="/js/" mapping="/js/**"/>

    <mvc:resources location="/images/" mapping="/images/**"/>

    <!--开启SpringMVC注解的支持-->

    <mvc:annotation-driven/>

</beans>

需要项目源码的可以点击个人主页资源下载,

也可以去我个人gitHub下载:GitHub - zhouwenhao123456/BookManage: 基于SSM的图书管理系统

当然,如果你觉得我的项目对你有帮助的话,

看个人心情适当打赏几块钱,请博主喝瓶可乐,hhhh~
 

注意:开发软件IDEA,如果是ecplise的读者,需要上网查找IDEA转ecplise的方法

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于SSM的图书管理系统 的相关文章

随机推荐

  • VUE知识(三)计算属性、监听属性、动画

    文章目录 一 计算属性 一 计算属性 computed 1 目标 2 语法 3 特点 4 注意 二 计算属性 缓存 1 目标 2 使用场景 3 优势 三 计算属性 完整写法 1 目标 2 语法 4 使用场景 二 监听属性 一 监听属性 wa
  • [LeetCode]栈,队列相关题目(C语言实现)

    文章目录 LeetCode20 有效的括号 LeetCode225 用队列实现栈 LeetCode232 用栈实现队列 LeetCode622 设计循环队列 LeetCode20 有效的括号 题目 给定一个只包括 的字符串 s 判断字符串是
  • 使用stream流对List<Map>分组求和

    使用stream流对List分组求和 public class Test2 public static void main String args List
  • linux 非root进程,Linux查看非root运行的进程

    Linux查看非root运行的进程 email protected ps U root u root N PID TTY TIME CMD 663 00 00 00 dbus daemon 713 00 00 00 rsyslogd 730
  • 性能优化:Excel导入10w数据

    需求说明 excel报表导出10w 数据 在我们的进出口贸易系统可能由于之前导入的数据量并不多没有对效率有过高的追求 但是到了二次开发版本 我预估导入时Excel 行数会是 10w 级别 而往数据库插入的数据量是大于 3n 的 也就是说 1
  • 5-2 有监督特征抽取

    文章目录 5 2 有监督特征抽取 基础知识 项目案例 动手练习 5 2 有监督特征抽取 请参考 数据准备和特征工程 中的相关章节 调试如下代码 基础知识 from sklearn datasets import make classific
  • 【绝㊙️】三年开发内功心得

    经典嵌套if else问题 这个也是老生常谈问题了 不管哪里都能看到 那如何解决 方法一 重要 如果逻辑分支过多 即使你不解决嵌套if slse 至少也要把每个 if的 里的逻辑抽到一个独立的方法或者工具类或者策略模式类 保证 里只有一行或
  • display:flex布局方式

    2009年 W3C提出了一种新的方案 Flex布局 可以简便 完整 响应式地实现各种页面布局 目前已得到所有现在浏览器的支持 Flex是Flexible Box的缩写 翻译成中文就是 弹性盒子 用来为盒装模型提供最大的灵活性 任何一个容器都
  • 元宇宙离我们有多远

    元宇宙离我们有多远 杨圆飞 202128015029001 No 145 元宇宙 Metaverse 即数字虚拟世界 电影 头号玩家 中的游戏 绿洲 黑客帝国 中的 矩阵 就是这样一个数字虚拟世界 因为这两个电影 人们对元宇宙有了具象化的认
  • JUC - 类汇总和学习指南

    一 概述 我们先来看下 JUC 的包括那些部分 Lock 框架和 Tools 类 把图中这两个放到一起理解 Collections 并发集合 Atomic 原子类 Executors 线程池 二 Lock 框架和 Tools 类 2 1 类
  • 解决org.gradle.api.tasks.TaskExecutionException: Execution failed for task ‘:framework:compileDebugJav

    目录 介绍 解决方法1 解决方法2 解决方法3 解决方法4 解决方法5 解决方法6 解决方法7 介绍 今天在拉公司项目的时候报了一个奇怪的错误 在这里分享给大家 让大家少走弯路 报了这个错误信息其实有很多种可能性我依依把解决方案写在下面并且
  • 2022-12-18 网工进阶(三十八)MPLS LDP---LDP基础、工作原理(会话、标签的发布和管理、特性)、配置举例

    LDP概述 LDP是MPLS的一种控制协议 相当于传统网络中的信令协议 负责FEC的分类 标签的分配以及LSP的建立和维护等操作 LDP规定了标签分发过程中的各种消息以及相关处理过程 LDP的工作过程主要分为两部分 LSR之间建立LDP会话
  • PTA L2-034 口罩发放 (25 分)

    题目地址 L2 034 口罩发放 25 分 测试点 记录一下我遇到的坑 1 测试点4和测试点5的提交时间一样 卡排队顺序 2 有合法记录的 身体状况为 1 的申请人必须全部存下来 输出时再判重 不可以set直接存放判重 否则卡4 5 6测试
  • UDP的一对多通信(广播)

    补充 1 TCP通信采用一对一的通信模式 日常生活中的网络会议通知 广告 网络信息公告等功能 需要采用UDP实现一对多的群发功能 通过Internet实现群发功能的形式有两种 1 利用广播向子网中的所有客户发送消息 比如各类通知 单位公告
  • Day2-1 Maven工程、pom.xml工程管理、数据库连接和文件读写

    Maven工程 工具包 apache maven 3 5 4 bin tar gz 使用方法 解压后 在 conf settings xml文件配置镜像来源和本地存储目录等信息 并在STS关联 如下
  • JS中0.1+0.2!=0.3

    控制台打印测试 console log 0 1 0 2 0 30000000000000004 原因 1 存储原理 在计算机中数字无论是定点数还是浮点数都是以多位二进制的方式进行存储的 在JS中数字采用的IEEE 754的双精度标准进行存储
  • C++【多线程】

    文章目录 一 什么是线程 二 创建线程 pthread create pthread join 三 线程退出 pthread exit pthread cancel 线程id pthread self 四 进程对于共享资源的访问 threa
  • 餐饮行业RPA之5大应用场景

    眼下 伴随着一系列风险因素 餐饮业的情况变得越来越困难 规模较小 财务状况较差的餐饮商户面临着极大的生存挑战 即使是有一定知名度和客源的大品牌餐饮加盟连锁店 也被逼到了墙角 近年来 餐饮业市场竞争激烈 而且同质化严重 即使没有疫情冲击 众多
  • 计算机恢复工具有哪些,电脑数据恢复软件选哪个?这三款恢复工具不容错过

    不论我们是使用电脑来编写学习论文 还是完成老师所留的专业作业 再或者是处理日常工作或者是紧急工作 我们都会在电脑上存储一些重要的文件 就算我们的电脑不是学习或工作所用的话 那么电脑上也会存储一些自己认为比较重要的文件的 即便我们将重要的文件
  • 基于SSM的图书管理系统

    一 系统简介 该项目是基于Java的SSM框架实现的图书管理系统 二 技术实现 1 后台框架 Spring SpringMVC MyBatis Ajax 2 UI界面 BootStrap 3 数据库 MySQL 5 7 4 加密 md5 随