JavaWeb——基于Spring Boot的图书数字化管理系统的设计与实现

课程设计总结

1    概述

1.1  项目开发背景

随着信息技术的快速发展,数字化管理已经成为各行各业提高效率和管理水平的重要手段。在图书管理领域,数字化管理系统可以有效地提高管理效率,提供更好的用户体验。本项目旨在开发一个基于Spring Boot的图书数字化管理系统,为管理员和读者提供便捷的操作和管理功能。

  • 自动化管理需求:传统的图书管理往往涉及大量的人工操作,包括手动记录借还信息、图书分类整理和查询等。通过开发一个数字化管理系统,可以实现自动化的图书管理,减少人力成本和提高工作效率。
  • 提升用户体验:对于图书馆或图书管理机构而言,提供一个方便易用的系统可以提升用户的体验和满意度。数字化管理系统可以提供在线图书查询、预约借阅、自助借还等功能,方便用户快速获取所需图书,并且减少繁琐的手续。
  • 数据统计和分析:数字化管理系统可以收集和存储大量的图书相关数据,包括借还记录、读者偏好、图书馆资源利用情况等。通过对这些数据进行统计和分析,可以为图书馆管理者提供决策支持,例如优化图书采购、调整借阅规则、推荐相关图书等。
  • 安全和保护:数字化管理系统可以加强对图书和图书借阅信息的安全管理。通过权限控制和身份验证,确保只有授权人员可以进行借阅操作,并保护读者隐私和借阅记录的安全。

通过这个基于Spring Boot的图书数字化管理系统,管理员和读者可以在线完成相关操作和管理流程,提高了管理效率,提供了更好的用户体验。同时,系统还具备安全性高、易于扩展和维护等特点,为图书管理提供了新的解决方案。

1.2  开发工具

本项目采用Windows 10IntelliJ IDEA进行系统开发。

1.3  采用的技术

本项目主要采用的技术有JavaMySQLMavenSpringBootMybatis-PlusMySQLVue3ElementPlus等。

l JavaJava是一种广泛使用的编程语言,它适用于各种领域,包括桌面应用程序、移动应用程序、网络应用程序等。

l MySQLMySQL是一种流行的开源关系数据库管理系统,它使用SQL语言作为查询语言,它被广泛应用于各种应用程序中,如JavaPython等。

l MavenMaven是一个用于管理Java项目的工具,它可以帮助构建、打包和部署Java应用程序,它还可以管理项目的依赖关系。

l SpringBootSpringBoot是一个用于快速构建基于Spring框架的Java应用程序的工具,它通过自动配置和快速开发接口简化了Java开发。

l Mybatis-PlusMybatis-Plus是一个增强Mybatis的插件,它提供了更简单的API和更强大的功能,如全表操作、分页查询等,可以更方便地使用Mybatis进行数据库操作。

l Vue3Vue3Vue.js框架的最新版本,它提供了一个强大的API,用于构建可复用的组件,并使用虚拟DOM来实现快速、高效的渲染。

l ElementPlusElementPlusElement UI的升级版,它提供了更多主题和组件,可以快速构建美观的Web应用程序界面。

1.4  项目成员

项目成员如表 1‑1 项目成员表 1‑1所示。

1‑1 项目成员

姓名

职位

负责范围

项目经理

负责设计系统架构,并整合资料

系统分析师

负责对系统的可行性进行分析,并编写实现与测试的内容

设计师

负责对前端页面的设计,并编写界面设计和数据库设计的内容

前端开发

负责前端开发,并编写概述以及开发日志

后端开发

负责后端开发,并编写接口设计

测试工程师

负责测试系统,并编写实验总结

运维工程师

负责运维系统,并编写系统分析的内容

2    系统分析

2.1  需求分析

基于Spring Boot框架的数字化图书管理系统的需求分析包括账号管理、图书管理、借阅关系管理和操作台统计信息显示等功能模块。系统需要提供普通用户界面和管理员界面,普通用户和管理员都能借阅图书,管理员能够管理用户账号。此外,系统应具备统计功能,能够实时显示网站访问次数、用户数量、借阅数量和图书总量等统计信息。通过SSM框架的技术实现,系统能够实现用户注册、登录、图书录入、借阅操作和管理功能,满足用户的数字化图书管理需求。

2.1.1       成本考虑

在开发数字化图书管理系统的需求分析中,成本考虑是一个重要因素。团队规模为七人、时间限制为一周,资金不计。成本考虑包括人力成本、开发工具和环境成本、项目管理成本、硬件和基础设施成本,以及培训和支持成本。在评估成本时,需要综合考虑团队投入工时、技能水平、开发工具和基础设施需求,确保在给定时间内能够实现核心功能,并根据实际情况进行权衡和决策。

2.1.2       技术考虑

在技术考虑中,前端采用Vue框架,后端使用Spring Boot框架,数据库选择MySQL。技术考虑包括前端开发、后端开发、数据库选择、数据交互与API设计以及安全性考虑。通过合理利用这些技术,能够实现用户界面的交互和数据展示,实现业务逻辑和数据访问,确保数据的安全性和有效性,以满足系统的功能、性能和安全性要求。

2.1.3       市场考虑

市场考虑在需求分析中是至关重要的,包括明确目标用户群体、竞争分析、了解市场需求和趋势、设计合适的商业模式,并关注用户反馈和持续改进。通过这些市场考虑,系统能够满足目标用户的需求,与竞争对手保持竞争力,并在商业上具备可行性和市场适应性,以实现系统的成功和可持续发展。

2.1.4       用户考虑

用户考虑中,需要深入了解目标用户的特征和需求,设计用户友好的界面和良好的用户体验,鼓励用户参与和反馈,提供适当的培训和支持,以及确保用户隐私和数据安全。通过这些用户考虑,系统能够满足用户的期望和需求,提供优质的用户体验,并建立用户的信任和满意度,以实现系统的成功和用户的长期使用。

2.2  可行性分析

2.2.1       经济可行性

可行性分析主要关注开发成本和维护成本。根据团队规模为七人、时间限制为一周的条件,需对人力成本进行评估,确保在限定时间内完成核心功能开发。基于Spring Boot等开源框架的使用,可以减少开发成本,并且降低后续维护和升级的成本。进一步的经济可行性分析需要综合考虑系统的商业模式、收费方式和潜在收入,以确保系统能够获得足够的回报和盈利。

2.2.2       技术可行性

前端使用Vue框架,后端采用Spring Boot框架,数据库选择MySQL,这些技术都是成熟且广泛应用的技术栈,具备稳定性和可靠性。开发团队熟悉这些技术,并且有相关经验和技能,能够有效地开发和维护系统。相关的开发工具、集成环境和数据库管理工具等也易于获得和配置,支持系统的开发和部署。

2.2.3       操作可行性

系统的操作可行性指用户使用系统的便利性和可操作性。通过使用Vue框架和用户友好的界面设计,能够提供直观易用的用户界面,使用户能够方便地浏览图书、借阅和管理账号等。合理的界面交互和功能设计,以及提供适当的用户培训和支持,可以帮助用户快速上手并高效地使用系统。

2.3  功能分析

功能分析包括:账号管理,图书管理和借阅管理,此外还有查看用户数量,借阅数量,访问数量的显示台功能。账号管理分为普通用户账户管理和管理员账户管理;而管理员账号可以管理普通用户。图书管理包括添加图书,删除图书,查询图书和查询图书页面。在查询中,还包括单独查询和批量查询。借阅管理包括普通用户图书借阅和管理员图书借阅。用户借阅图书后,可以进行归还或者续借,管理员可以进行节约编辑,调整时间。

3    系统设计

3.1  功能概述

本系统分为管理员和读者模块。

管理员模块:注册、登录、书籍管理、读者管理、借阅管理、借阅状态、修改个人信息、修改密码

读者模块:注册、登录、查询图书信息、借阅和归还图书、查看个人借阅记录、修改个人信息、修改密码

系统结构图如图 3‑1所示。

3‑1 系统结构图

3.2  界面设计

3.2.1       注册页面

注册页面包括用户名、密码、确认密码、管理员/读者选项、验证码和注册按钮。用户完成这些步骤后即可成功注册,系统也将保存用户信息,提供后续操作的便利。具体页面如所示。

3‑2 读者注册页面

在选择管理员选项时,会多出一个管理员注册码,进行再一次的验证,以确保安全。

3‑3 管理员注册页面

3.2.2       登录页面

直接输入账号密码和验证码,如数据表中未找到该用户为此用户注册;如找到该用户,判断密码是否正确,正确即能进入用户个人页面。登录页面如图 3‑4所示。

3‑4 登录页面

3.2.3       用户展示板页面

用户展示页面包括已借阅数量,总访问的次数,图书的数量,用户数量以及统计图的展示,使得用更加直观的看到图书管理的情况。用户展示页面如图 3‑5所示。

3‑5 用户展示页面

3.2.4       用户个人信息

1)修改个人信息

修改个人信息可以变更用户名,姓名,电话号码,性别,地址最后进行保存。修改个人信息页面如图 3‑6所示。

3‑6 修改个人信息

2)修改密码

用户需要达到密码的安全性可以进行密码的修改,最后进行提交新密码。修改密码页面如图 3‑7所示。

3‑7 修改密码页面

3.2.5       用户图书查询

用户可以进行图书的查询,可以利用图书编号,图书名称以及作者进行查询。每次借阅最多5本书。用户图书查询页面如图 3‑8所示。

3‑8 用户图书查询

1)图书编号查询页面如图 3‑9所示。

 

3‑9 图书编号查询

2)作者查询如图 3‑10所示。

​​​​​​​

3‑10 作者查询

3.2.6       用户借阅信息

用户可以进行查看图书是否归还,可以利用图书编号,图书名称以及作者进行查询归还状态。用户借阅信息页面如图 3‑11所示。

3‑11 用户借阅信息图

1)图书编号查询归还状态页面如图 3‑12所示。

3‑12 图书编号查询归还状态图

3.2.7       用户借阅信息

用户可以看自己借书的状态,在归还日期到了的时候,可以考虑是否续借。用户借阅信息如图 3‑13所示。

3‑13 用户借阅信息

3.2.8       管理员展示板

管理员展示页面包括已借阅数量,总访问的次数,图书的数量,用户数量以及统计图的展示,使得用更加直观的看到图书管理的情况。管理员展示板页面如图 3‑14所示

3‑14 管理员展示板

3.2.9       管理员个人信息

1)修改个人信息

管理员可以修改个人信息可以变更用户名,姓名,电话号码,性别,地址最后进行保存。修改个人信息页面如图 3‑15所示。

3‑15 管理员个人信息图

2)修改密码

管理员需要达到密码的安全性可以进行密码的修改,最后进行提交新密码。修改密码页面如图 3‑16所示。

3‑16 修改密码

3.2.10     读者管理

管理员可以查看读者的信息,可以对读者的信息进行修改,也可以删除读者的信息。读者管理页面如图 3‑17所示。

3‑17 读者管理页面

3.2.11     书籍管理

管理员可以查看书籍的信息,可以对书籍的信息进行修改,也可以删除书籍的信息。书籍管理页面如图 3‑18所示。

​​​​​​​

3‑18 书籍管理

3.2.12     借阅管理

管理员可以查看借阅信息,可以使用图书编号,图书名称,读者编号进行查阅。借阅管理页面如图 3‑19所示

3‑19 借阅管理

图书编号查询如图 3‑20所示。

3‑20 图书编号查询

读者编号查询如图 3‑21所示。

3‑21 读者编号查询图

3.2.13     借阅状态

管理员可以查看书籍被那个读者借阅了,可以查看那本书被借了,可以修改借阅信息,也可以删除借阅信息。借阅状态页面如图 3‑22所示。

3‑22 借阅状态

3.3  接口设计

3.3.1       BookController

使用Spring Boot框架的RESTful接口控制器类,用于处理与图书相关的操作。以下BookController每个方法的功能解释,如 3‑1所示。

3‑1 BookController的方法

方法

作用

Result<?> save(@RequestBody Book Book)

保存一个Book对象到数据库,并返回保存后的结果。

Result<?> update(@RequestBody Book Book)

更新一个Book对象到数据库,并返回更新后的结果。

Result<?> deleteBatch(@RequestBody List<Integer> ids)

根据id删除一个Book对象,并返回删除后的结果。

Result<?> delete(@PathVariable Long id)

根据id删除一个Book对象,并返回删除后的结果。

3.3.2       BookWithUserController

使用Spring Boot框架的RESTful接口控制器类,用于处理与图书和用户相关的操作。以下是BookWithUserController的每个方法的功能解释,如 3‑2所示。

3‑2 BookWithUserController的方法

方法

作用

Result<?> insertNew(@RequestBody BookWithUser BookWithUser)

新增一个BookWithUser对象到数据库,并返回新增后的结果。

Result<?> update(@RequestBody BookWithUser BookWithUser)

更新一个BookWithUser对象到数据库,并返回更新后的结果。

Result<?> deleteRecord(@RequestBody BookWithUser BookWithUser)

删除一个BookWithUser对象到数据库,并返回删除后的结果。

3.3.3       DashboardController

使用Spring Boot框架的RESTful接口控制器类,用于处理与仪表板相关的操作。仪表板页面包括已借阅数量,总访问的次数,图书的数量,用户数量以及统计图的展示,使得用更加直观的看到图书管理的情况。

DashboardController类的主要作用是处理仪表盘页面的GET请求,并通过调用其他Mapper类的方法来获取相关统计信息,并将这些信息以键值对的形式存储在Map对象中,最终返回给调用者以展示仪表盘页面。

3.3.4       LendRecordController

使用Spring Boot框架的RESTful接口控制器类,用于处理与借阅记录相关的操作。以下是LendRecordController的每个方法的功能解释,如 3‑3所示。

3‑3 LendRecordController的方法

方法

作用

Result<?> deleteRecord(@RequestBody LendRecord LendRecord)

根据单个LendRecord对象进行删除操作,并返回删除后的结果。

Result<?> deleteRecords(@RequestBody List<LendRecord> LendRecords)

根据多个LendRecord对象进行批量删除操作,并返回删除后的结果。

Result<?> save(@RequestBody LendRecord LendRecord)

保存单个LendRecord对象到数据库,并返回保存后的结果。

3.3.5       UserController

使用Spring Boot框架的RESTful接口控制器类,用于处理与用户相关的操作。以下是UserController的每个方法的功能解释,如 3‑4所示。

3‑4 UserController的方法

方法

作用

Result<?> register(@RequestBody User user)

注册一个新用户到数据库,并返回注册后的结果。

Result<?> login(@RequestBody User user)

验证用户登录,并返回登录后的结果。

Result<?> save(@RequestBody User user)

保存用户信息到数据库,并返回保存后的结果。

Result<?> password(@RequestBody User user)

修改用户密码,并返回修改后的结果。

Result<?> deleteBatch(@RequestBody List<Integer> ids)

批量删除用户,并返回删除后的结果。

3.4  数据库设计

本系统的数据库一共有4张数据表,分别是bookbookwithuserlend_recorduser表,表设计,如图 3‑23到图 3‑26所示。

3‑23 book表设计

3‑24 bookwithuser表设计

3‑25 lend_record表设计

3‑26 user表设计

4    实现与测试

4.1  关键技术实现(关键问题或难点是如何实现的)

4.1.1       BookController

本模块用于保存图书实体,通过bookMapper id更新图书,通过Batch id批量删除,通过bookMapper id删除图书,查找页面。

package com.example.demo.controller;

@RestController
@RequestMapping("/book")
public class BookController {
    @Resource
    BookMapper BookMapper;

    @PostMapping
    public Result<?> save(@RequestBody Book Book) {
        BookMapper.insert(Book);
        return Result.success();
    }

    @PutMapping
    public Result<?> update(@RequestBody Book Book) {
        BookMapper.updateById(Book);
        return Result.success();
    }

    //    批量删除
    @PostMapping("/deleteBatch")
    public Result<?> deleteBatch(@RequestBody List<Integer> ids) {
        BookMapper.deleteBatchIds(ids);
        return Result.success();
    }

    @DeleteMapping("/{id}")
    public Result<?> delete(@PathVariable Long id) {
        BookMapper.deleteById(id);
        return Result.success();
    }

    @GetMapping
    public Result<?> findPage(@RequestParam(defaultValue = "1") Integer pageNum,
                              @RequestParam(defaultValue = "10") Integer pageSize,
                              @RequestParam(defaultValue = "") String search1,
                              @RequestParam(defaultValue = "") String search2,
                              @RequestParam(defaultValue = "") String search3) {
        LambdaQueryWrapper<Book> wrappers = Wrappers.<Book>lambdaQuery();
        if (StringUtils.isNotBlank(search1)) {
            wrappers.like(Book::getIsbn, search1);
        }
        if (StringUtils.isNotBlank(search2)) {
            wrappers.like(Book::getName, search2);
        }
        if (StringUtils.isNotBlank(search3)) {
            wrappers.like(Book::getAuthor, search3);
        }
        Page<Book> BookPage = BookMapper.selectPage(new Page<>(pageNum, pageSize), wrappers);
        return Result.success(BookPage);
    }
}

​​​​​​​4.1.2       BookWithUserController

本模块用于,插入新的借阅关系实体,通过图书名称和借阅关系id更新借阅关系,通过图书名称和借阅关系id删除一条或多条借阅关系记录,查找页面。具体代码如下。

package com.example.demo.controller;

@RestController
@RequestMapping("/bookwithuser")
public class BookWithUserController {
    @Resource
    BookWithUserMapper BookWithUserMapper;

    @PostMapping("/insertNew")
    public Result<?> insertNew(@RequestBody BookWithUser BookWithUser) {
        BookWithUserMapper.insert(BookWithUser);
        return Result.success();
    }

    @PostMapping
    public Result<?> update(@RequestBody BookWithUser BookWithUser) {
        UpdateWrapper<BookWithUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("isbn", BookWithUser.getIsbn()).eq("id", BookWithUser.getId());
        BookWithUserMapper.update(BookWithUser, updateWrapper);
        return Result.success();
    }

    //删除一条记录
    @PostMapping("/deleteRecord")
    public Result<?> deleteRecord(@RequestBody BookWithUser BookWithUser) {
        Map<String, Object> map = new HashMap<>();
        map.put("isbn", BookWithUser.getIsbn());
        map.put("id", BookWithUser.getId());
        BookWithUserMapper.deleteByMap(map);
        return Result.success();
    }

    @PostMapping("/deleteRecords")
    public Result<?> deleteRecords(@RequestBody List<BookWithUser> BookWithUsers) {
        int len = BookWithUsers.size();
        for (int i = 0; i < len; i++) {
            BookWithUser curRecord = BookWithUsers.get(i);
            Map<String, Object> map = new HashMap<>();
            map.put("isbn", curRecord.getIsbn());
            map.put("id", curRecord.getId());
            BookWithUserMapper.deleteByMap(map);
        }
        return Result.success();
    }

    @GetMapping
    public Result<?> findPage(@RequestParam(defaultValue = "1") Integer pageNum,
                              @RequestParam(defaultValue = "10") Integer pageSize,
                              @RequestParam(defaultValue = "") String search1,
                              @RequestParam(defaultValue = "") String search2,
                              @RequestParam(defaultValue = "") String search3) {
        LambdaQueryWrapper<BookWithUser> wrappers = Wrappers.<BookWithUser>lambdaQuery();
        if (StringUtils.isNotBlank(search1)) {
            wrappers.like(BookWithUser::getIsbn, search1);
        }
        if (StringUtils.isNotBlank(search2)) {
            wrappers.like(BookWithUser::getBookName, search2);
        }
        if (StringUtils.isNotBlank(search3)) {
            wrappers.like(BookWithUser::getId, search3);
        }
        Page<BookWithUser> BookPage = BookWithUserMapper.selectPage(new Page<>(pageNum, pageSize), wrappers);
        return Result.success(BookPage);
    }
 
}

4.1.3       DashboardController

本模块用于使用显示网站访问次数,用户数量,借阅记录,图书数量。具体代码如下。

package com.example.demo.controller;


@RestController
@RequestMapping("/dashboard")
public class DashboardController {
    @Resource
    private UserMapper userMapper;
    @Resource
    private LendRecordMapper lendRecordMapper;
    @Resource
    private BookMapper bookMapper;
    @GetMapping
    public  Result<?> dashboardrecords(){
        int visitCount = LoginUser.getVisitCount();
        QueryWrapper<User> queryWrapper1=new QueryWrapper();
        int userCount = userMapper.selectCount(queryWrapper1);
        QueryWrapper<LendRecord> queryWrapper2=new QueryWrapper();
        int lendRecordCount = lendRecordMapper.selectCount(queryWrapper2);
        QueryWrapper<Book> queryWrapper3=new QueryWrapper();
        int bookCount = bookMapper.selectCount(queryWrapper3);
        Map<String, Object> map = new HashMap<>();//键值对形式
        map.put("visitCount", visitCount);//放置visitCount到map中
        map.put("userCount", userCount);
        map.put("lendRecordCount", lendRecordCount);
        map.put("bookCount", bookCount);
        return Result.success(map);
    }
}

4.1.4       LendRecordController

本模块用于根据图书名称删除借阅记录,删除一条或多条借阅记录,保存借阅记录,查找页面,修改借阅记录。

package com.example.demo.controller;


@RestController
@RequestMapping("/LendRecord")
public class LendRecordController {
    @Resource
    LendRecordMapper LendRecordMapper;

    @DeleteMapping("/{isbn}")
    public Result<?> delete(@PathVariable String isbn) {
        Map<String, Object> map = new HashMap<>();
        map.put("isbn", isbn);
        LendRecordMapper.deleteByMap(map);
        return Result.success();
    }

    //删除一条记录
    @PostMapping("/deleteRecord")
    public Result<?> deleteRecord(@RequestBody LendRecord LendRecord) {
        Map<String, Object> map = new HashMap<>();
        map.put("isbn", LendRecord.getIsbn());
        map.put("borrownum", LendRecord.getBorrownum());
        LendRecordMapper.deleteByMap(map);
        return Result.success();
    }

    @PostMapping("/deleteRecords")
    public Result<?> deleteRecords(@RequestBody List<LendRecord> LendRecords) {
        int len = LendRecords.size();
        for (int i = 0; i < len; i++) {
            LendRecord curRecord = LendRecords.get(i);
            Map<String, Object> map = new HashMap<>();
            map.put("isbn", curRecord.getIsbn());
            map.put("borrownum", curRecord.getBorrownum());
            LendRecordMapper.deleteByMap(map);
        }
        return Result.success();
    }

    @PostMapping
    public Result<?> save(@RequestBody LendRecord LendRecord) {
        LendRecordMapper.insert(LendRecord);
        return Result.success();
    }

    @GetMapping
    public Result<?> findPage(@RequestParam(defaultValue = "1") Integer pageNum,
                              @RequestParam(defaultValue = "10") Integer pageSize,
                              @RequestParam(defaultValue = "") String search1,
                              @RequestParam(defaultValue = "") String search2,
                              @RequestParam(defaultValue = "") String search3) {
        LambdaQueryWrapper<LendRecord> wrappers = Wrappers.<LendRecord>lambdaQuery();
        if (StringUtils.isNotBlank(search1)) {
            wrappers.like(LendRecord::getIsbn, search1);
        }
        if (StringUtils.isNotBlank(search2)) {
            wrappers.like(LendRecord::getBookname, search2);
        }
        if (StringUtils.isNotBlank(search3)) {
            wrappers.like(LendRecord::getReaderId, search3);
        }
        Page<LendRecord> LendRecordPage = LendRecordMapper.selectPage(new Page<>(pageNum, pageSize), wrappers);
        return Result.success(LendRecordPage);
    }

    @PutMapping("/{isbn}")
    public Result<?> update(@PathVariable String isbn, @RequestBody LendRecord lendRecord) {
        UpdateWrapper<LendRecord> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("isbn", isbn);
        LendRecord lendrecord = new LendRecord();
        lendrecord.setLendTime(lendRecord.getLendTime());
        lendrecord.setReturnTime(lendRecord.getReturnTime());
        lendrecord.setStatus(lendRecord.getStatus());
        LendRecordMapper.update(lendrecord, updateWrapper);
        return Result.success();
    }

    @PutMapping("/{lendTime}")
    public Result<?> update2(@PathVariable Date lendTime, @RequestBody LendRecord lendRecord) {
        UpdateWrapper<LendRecord> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("lendTime", lendTime);
        LendRecord lendrecord = new LendRecord();
        lendrecord.setReturnTime(lendRecord.getReturnTime());
        lendrecord.setStatus(lendRecord.getStatus());
        LendRecordMapper.update(lendrecord, updateWrapper);
        return Result.success();
    }

}

​​​​​​​ 4.1.5       UserController

本模块用于用户注册,用户登录,插入用户信息,修改密码,用户ID修改密码,批量删除ID,通过昵称查找书籍页面。

具体实现代码如下:

package com.example.demo.controller;

@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    UserMapper userMapper;

    @PostMapping("/register")
    public Result<?> register(@RequestBody User user) {
        User res = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, user.getUsername()));
        if (res != null) {
            return Result.error("-1", "用户名已重复");
        }
        userMapper.insert(user);
        return Result.success();
    }

    @CrossOrigin
    @PostMapping("/login")
    public Result<?> login(@RequestBody User user) {
        User res = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, user.getUsername()).eq(User::getPassword, user.getPassword()));
        if (res == null) {
            return Result.error("-1", "用户名或密码错误");
        }
        String token = TokenUtils.genToken(res);
        res.setToken(token);
        LoginUser loginuser = new LoginUser();
        loginuser.addVisitCount();
        return Result.success(res);
    }

    @PostMapping
    public Result<?> save(@RequestBody User user) {
        if (user.getPassword() == null) {
            user.setPassword("abc123456");
        }
        userMapper.insert(user);
        return Result.success();
    }

    @PutMapping("/password")
    public Result<?> update(@RequestParam Integer id,
                            @RequestParam String password2) {
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);
        User user = new User();
        user.setPassword(password2);
        userMapper.update(user, updateWrapper);
        return Result.success();
    }

    @PutMapping
    public Result<?> password(@RequestBody User user) {
        userMapper.updateById(user);
        return Result.success();
    }

    @PostMapping("/deleteBatch")
    public Result<?> deleteBatch(@RequestBody List<Integer> ids) {
        userMapper.deleteBatchIds(ids);
        return Result.success();
    }

    @DeleteMapping("/{id}")
    public Result<?> delete(@PathVariable Long id) {
        userMapper.deleteById(id);
        return Result.success();
    }

    @GetMapping
    public Result<?> findPage(@RequestParam(defaultValue = "1") Integer pageNum,
                              @RequestParam(defaultValue = "10") Integer pageSize,
                              @RequestParam(defaultValue = "") String search) {
        LambdaQueryWrapper<User> wrappers = Wrappers.<User>lambdaQuery();
        if (StringUtils.isNotBlank(search)) {
            wrappers.like(User::getNickName, search);
        }
        wrappers.like(User::getRole, 2);
        Page<User> userPage = userMapper.selectPage(new Page<>(pageNum, pageSize), wrappers);
        return Result.success(userPage);
    }

    @GetMapping("/usersearch")
    public Result<?> findPage2(@RequestParam(defaultValue = "1") Integer pageNum,
                               @RequestParam(defaultValue = "10") Integer pageSize,
                               @RequestParam(defaultValue = "") String search1,
                               @RequestParam(defaultValue = "") String search2,
                               @RequestParam(defaultValue = "") String search3,
                               @RequestParam(defaultValue = "") String search4) {
        LambdaQueryWrapper<User> wrappers = Wrappers.<User>lambdaQuery();
        if (StringUtils.isNotBlank(search1)) {
            wrappers.like(User::getId, search1);
        }
        if (StringUtils.isNotBlank(search2)) {
            wrappers.like(User::getNickName, search2);
        }
        if (StringUtils.isNotBlank(search3)) {
            wrappers.like(User::getPhone, search3);
        }
        if (StringUtils.isNotBlank(search4)) {
            wrappers.like(User::getAddress, search4);
        }
        wrappers.like(User::getRole, 2);
        Page<User> userPage = userMapper.selectPage(new Page<>(pageNum, pageSize), wrappers);
        return Result.success(userPage);
    }
}

5    开发日志

本团队开发日志如下。

202373日:

l 使用IDEA开发工具创建Spring Boot项目,配置项目的基本信息和依赖。

l 配置数据库连接信息,包括MySQLURL、用户名和密码。

l 设计数据库表结构。

l 编写数据库初始化脚本,创建数据库表并插入初始数据。

202374日:

l 引入MyBatis-Plus依赖,配置MyBatis-Plus的相关信息。

l 创建图书管理、用户管理等模块的Service接口和实现类。

l 实现图书管理模块的增删改查功能,包括图书的添加、删除、修改和查询。

l 完成用户管理模块的相关功能,如用户的注册、登录、权限管理等。

202375日:

l 开发图书借阅管理模块,包括借阅记录的添加、查询和归还功能。

l 实现用户权限管理功能,根据用户角色限制不同操作的权限。

l 完善前端页面的布局和样式。

202376日:

l 添加搜索功能,根据关键字查询图书信息。

l 完善系统的异常处理和错误提示,提高系统的健壮性和用户体验。

l 进行系统的测试和调试,修复存在的Bug和问题。

202377日:

l 进行项目的总结和评估,总结开发过程中的经验和教训。

l 准备项目的演示文稿和演示材料,用于项目的答辩。

l 进行项目的答辩,展示系统的功能和设计思路,回答相关问题。

6    设计总结

在这次实训课中,我们小组设计并成功开发了一个图书数字化管理系统。这个系统的目标是提供一个高效、便捷的图书管理平台,使图书馆管理员能够轻松管理图书的借阅、归还和库存等操作。通过本次实训课的设计和实现,我们小组实现了图书的录入、借阅、归还和查询等功能,并且系统设计合理、功能完善,用户界面友好。同时,我们对数据库设计、编程技术和系统集成有了更深入的理解和实践。

在这次实训课的经历中,我们小组的成员有了一些共同的感悟和收获。

实践是学习的关键。实训课为我们提供了一个实践的机会,让我们能够将课堂上学到的理论知识应用到实际项目中。通过亲身实践,我们深刻理解了许多概念和原则,并学会了解决实际问题的方法。

团队合作的重要性。在实训课中,我们小组的成员一起组成团队,共同完成项目。团队合作是非常关键的,通过分工合作和协作交流,我们能够高效地完成任务。我们学到了如何与他人合作,倾听和尊重他人的意见,共同追求项目的成功。

面对挑战要有耐心和毅力。在实训过程中,我们遇到了各种各样的挑战,如技术难题、时间压力等。但是,我们学会了保持耐心和毅力,积极寻找解决方案,不断尝试和学习。这让我们明白到,在面对困难时,坚持不懈的努力是能够克服障碍并取得进步的关键。

要注重细节和质量。在实训课中,我们意识到细节的重要性。一个小小的错误或遗漏可能会导致系统的不稳定或功能缺失。因此,我们学会了注重细节,审慎检查代码和设计,以确保系统的质量和可靠性。

持续学习和自我提升。实训课只是学习的起点,我们意识到在不断发展的技术领域,学习是一个持续的过程。我们要时刻保持学习的心态,跟上最新的技术和趋势,不断提升自己的能力和知识水平。

规划和时间管理。在实训课开始之前我们制定了详细的项目计划和时间表这有助于我们合理分配任务和时间,避免了项目进度的拖延。我们学会了如何有效地规划和管理我们的时间,以便在限定的时间内完成任务。

沟通和协作能力。团队合作是实训课的关键要素。我们需要与团队成员密切合作共同制定方案讨论问题并解决挑战,通过与他人的沟通和协作,我们提高了我们的沟通能力和团队合作技巧。我们学会了倾听他人的观点尊重不同的意见并在团队中扮演积极的角色。

解决问题的能力。在实训过程中我们遇到了许多技术和设计上的问题,有时候我们需要独立解决问题,也有时候需要团队共同努力。我们学会了如何分析问题,寻找解决方案并采取适当的行动来解决问题,这让我们对问题解决的过程有了更深入的了解并增强了我们解决问题的能力。

学习与实践的结合。实训课提供了一个理论与实践相结合的学习环境,通过将所学的理论知识应用到实际项目中,我们深化了对课程内容的理解,并掌握了实际应用的技能这种学习方式,让我们在实践中不断成长,并将知识转化为实际能力。

自我反思和持续改进。在实训课的过程中,我们不断反思自己的表现和学习进展,我们意识到自己的优点和不足并积极采取措施改进自己。通过持续的自我反思和改进,我们能够不断提升自己的技能和能力。

通过这次实训课我们小组不仅获得了实际项目开发的经验,还培养了自我管理团队合作和问题解决的能力。这些宝贵的经验将对我们小组的成员未来的学习和职业发展产生长远的影响,我们期待将这些经验应用于未来的项目和挑战中,并不断成长和提升自己。

编码不易,有偿分享代码和原文档,有意私聊。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/39634.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Elasticsearch】DSL查询文档

目录 1.DSL查询文档 1.1.DSL查询分类 1.2.全文检索查询 1.2.1.使用场景 1.2.2.基本语法 1.2.3.示例 1.2.4.总结 1.3.精准查询 1.3.1.term查询 1.3.2.range查询 1.3.3.总结 1.4.地理坐标查询 1.4.1.矩形范围查询 1.4.2.附近查询 1.5.复合查询 1.5.1.相关性算分 …

LabVIEW开发惯性测量系统

LabVIEW开发惯性测量系统 惯性导航系统是通过将惯性传感器直接绑定在载体主体上来完成制导和导航任务的系统。所以惯性测量系统主要是动态静态地测试陀螺仪和加速度计的性能。测试点和计算点数众多&#xff0c;对测试速度和精度要求高。基于上述特点&#xff0c;基于虚拟仪器软…

Docker安装ElasticSearch/ES

目录 前言准备拉取ElasticSearch镜像安装ElasticSearch拉取elasticsearch-head镜像安装elasticsearch-head参考 前言 TencentOS Server 3.1Docker version 19.03.14, build 5eb3275d40 准备 docker 已安装。 安装 docker 参考&#xff1a;【Centos 8】【Centos 7】安装 docke…

gitbash2.41安装教程——2023.07

文章目录 1、下载安装包2、安装 1、下载安装包 进入官网下载&#xff0c;官网链接 上面有多种系统可以选择&#xff0c;我是windows&#xff0c;点击windows进行下载 这里可以直接下载最新版本的git 2.41.0 64位。 下载可能有点慢&#xff0c;耐心等待。 2、安装 下载完…

三种视频字幕提取工具让你更好地阅读和学习

视频字幕提取技术是指通过计算机算法自动从视频中提取出字幕文本的技术。这项技术能够大大提高视频的可用性&#xff0c;使得聋哑人士、语言学习者以及听力不佳的观众可以更好地理解视频内容。那么你知道视频字幕提取工具免费有哪些吗&#xff1f;接下来我将分享三款我亲测好用…

Oracle 的视图

Oracle 的视图 源数据&#xff1a; -- Create table create table STU_INFO (id NUMBER not null,name VARCHAR2(8),score NUMBER(4,1),class VARCHAR2(2) ) tablespace STUDENTpctfree 10initrans 1maxtrans 255storage(initial 64Knext 1Mminextents 1maxextents unlim…

单片机尽力少用位域操作

1、在51单片机中少用uint32_t类型&#xff0c;查看汇编真的好多条指令&#xff0c;尽力避免少用。 2、在32位单片机中&#xff0c;u8、u16、u32类型操作起来基本没有什么影响&#xff0c;下图是我做的测试&#xff0c;可能测试不全面&#xff0c;按照当前测试&#xff0c;在32…

使用Postman+JMeter进行简单的接口测试

以前每次学习接口测试都是百度&#xff0c;查看相关人员的实战经验&#xff0c;没有结合自己公司项目接口真正具体情况。 这里简单分享一下公司项目Web平台的一个查询接口&#xff0c;我会使用2种工具Postman和JMeter如何对同一个接口做调试。 准备工作 首先&#xff0c;登录公…

再开源一款轻量内存池

前两天已开源线程池&#xff0c;开源一款轻量线程池项目&#xff0c;本节继续开源另一个孪生兄弟&#xff1a;内存池。 本节的线程池与内存池代码解析会在我的星球详细讲解。 内存池&#xff1a;https://github.com/Light-City/light-memory-pool 线程池&#xff1a;https://gi…

【数据结构】图解八大排序(下)

文章目录 一、前言二、快速排序1. hoare 版2. 挖坑法3. 前后指针法4. 快排的非递归实现5. 时空复杂度分析 三、归并排序1. 递归实现2. 非递归实现 四、计数排序 一、前言 在上一篇文章中&#xff0c;我们已经学习了五种排序算法&#xff0c;还没看过的小伙伴可以去看一下&…

python将dataframe数据导入MongoDB非关系型数据库

文章目录 pymongo连接新建数据库和集合pandas导入数据插入数据数据查看 pymongo连接 import pymongo client pymongo.MongoClient("mongodb://localhost:27017/") dblist client.list_database_names() for db in dblist:print(db) #查看已有数据库admin bilibil…

接口测试 react+unittest+flask 接口自动化测试平台

目录 1 前言 2 框架 2-1 框架简介 2-2 框架介绍 2-3 框架结构 3 平台 3-1 平台组件图 1 新建用例 2 生成测试任务 3 执行并查看测试报告 3-2 用例管理 3-2-1 用例设计 3-3 任务管理 3-3-1 创建任务 3-3-2 执行任务 3-3-3 测试报告 3-3-4 邮件通知 1 前言 构建…

科技资讯|Apple Vision Pro新专利,关于相对惯性测量系统的校正

美国专利商标局正式授予苹果一项 Apple Vision Pro 相关专利&#xff0c;该专利涵盖了具有视觉校正功能的相对惯性测量系统。这样的系统用于弥补头显内的眼前庭不匹配&#xff0c;当 VR 头显中发生的事情与现实世界环境中发生的运动不匹配时&#xff0c;可能会导致恶心。 苹果…

怎么用Midjourney制作表情包

要使用Midjourney制作表情包&#xff0c;可以按照以下步骤进行操作&#xff1a; 1. 打开Midjourney的官方网站或下载Midjourney应用程序&#xff0c;并登录你的账户。 2. 在Midjourney中&#xff0c;选择创建新项目或表情包。 3. 在项目中&#xff0c;你可以选择使用预设的模…

笔记本电脑的电池健康:确保长时间使用和优异性能的关键

笔记本电脑已经成为我们日常生活中不可或缺的工具&#xff0c;无论是办公、学习还是娱乐&#xff0c;我们都依赖着它的便携性和高效性能。而在所有的硬件组件中&#xff0c;电池健康被认为是确保长时间使用和良好性能的关键因素之一。一块健康的电池不仅能提供持久的续航时间&a…

list模拟实现

一、结点的定义 有三个成员&#xff0c;2个指向前面和后面的指针&#xff0c;一个表示结点存储T类型的值。 对于_prev和_next&#xff0c;类型是 list_node<T>*&#xff0c;不是list_node*&#xff0c;加上类型参数T之后&#xff0c;才是模板类的类型。 构造函数中&am…

大模型时代,腾讯云“复制”腾讯|WAIC2023

点击关注 文&#xff5c;郝鑫 编&#xff5c;刘雨琦 刚过去的WAIC&#xff08;世界人工智能大会&#xff09;俨然成为了大模型厂商的成果汇报大会。 百度文心大模型升级到3.5版本&#xff0c;训练速度提升2倍&#xff0c;推理速度提升30倍&#xff1b;华为云发布盘古大模型3…

【数学建模】统计分析方法

文章目录 1.回归分析2. 逻辑回归3. 聚类分析4. 判别分析5. 主成分分析6. 因子分析7. 对应分析 1.回归分析 数据量要多&#xff0c;样本总量n越大越好——>保证拟合效果更好&#xff0c;预测效果越好 一般n>40/45较好 方法 建立回归模型 yiβ0β1i……βkxkiεi 所估计的…

❤️创意网页:HTML5,canvas创作科技感粒子特效(科技感粒子、js鼠标跟随、粒子连线)

✨博主&#xff1a;命运之光 &#x1f338;专栏&#xff1a;Python星辰秘典 &#x1f433;专栏&#xff1a;web开发&#xff08;简单好用又好看&#xff09; ❤️专栏&#xff1a;Java经典程序设计 ☀️博主的其他文章&#xff1a;点击进入博主的主页 前言&#xff1a;欢迎踏入…

Gateway网关组件(在Spring Cloud整合Gateway(idea19版本))

Spring Cloud Gateway官网:Spring Cloud Gateway 局域网中就有网关这个概念&#xff0c;局域网接收数据或发送数据都要通过网关&#xff0c;比如使用VMware虚拟机软件搭建虚拟机集群的时候&#xff0c;往往我们需要选择IP段中的⼀个IP作为网关地址,网关可以对请求进行控制,提升…