龙空技术网

书籍管理系统源代码及开发文档和演示视频JavaEE框架与应用开发课

科大云炬 53

前言:

而今同学们对“javaee图书管理系统类设计”大致比较关注,看官们都需要学习一些“javaee图书管理系统类设计”的相关资讯。那么小编也在网络上网罗了一些有关“javaee图书管理系统类设计””的相关文章,希望朋友们能喜欢,大家快快来学习一下吧!

中北大学软件学院

实验报告

专业:

软件工程

方向:

云计算与大数据

课程名称:

JavaEE框架与应用开发

班 级:

学 号:

姓 名:

辅导教师:

成绩:

实验时间

年 月 日 时 至 时

学时数

4学时

1.实验名称

开发NUCSELL图书管理系统

2.实验目的

1.图书管理:包括图书类型管理、每本图书详细信息管理

(1)图书类型管理:图书类型信息增、删、改、查询;

(2)图书详细信息管理:图书信息的增、删、改、查询;

a.其中图书信息包括图书编号、图书名称、图书类型、图书价格、图书封皮图片

b.查询要求可以按单条件查询(例如按图书编号或图书类型查询);按多条件查询,同时满足多个条件查询,例如上面5个条件中选择3个(图书名称、图书类型、图书价格(价格按某一范围))或选择两个条件(图书类型、图书价格(价格按某一范围)),查询结果满足条件的可能有多条数据。

c.图书类型管理及每本图书信息增、删、改操作必须由具有系统管理员权限的用户完成,具有普通权限的用户不能执行管理操作。

2.用户管理:包括两类用户:具有普通权限的用户和具有系统管理员权限的用户。

(1)用户权限分为0和1两种,0表示系统管理员权限,1表示普通用户权限。

例如:张三可以登录到系统,以系统管理员身份登录进去,可以进行图书管理;以普通用户身份登录,则只能浏览图书信息,查询图书信息(简单查询和高级查询)。

(2)普通用户、系统管理员用户均可有多个。

(3)用户信息(包括用户ID、用户名称、密码、用户权限)管理:增、删、改、查操作。

3.具有普通用户权限的用户可以完成注册、登录,信息浏览、查询功能;

具有系统管理员权限的用户可以完成图书管理、用户管理功能。

4.退出系统,用户注销。

二、系统其他要求:

1. 数据存储需使用数据库管理系统软件;

2. 使用Spring Boot整合MyBatis开发;

3. 前台界面采用UI框架。

3.实验内容

1.NUCSELL是一个图书网站

2.用户可以登录,注册,查看分类书籍并查询

3.管理员登录后可以在后台对图书进行增删改查

4.管理员登录后可以在后台对图书类型进行增删改查

5.管理员登录后可以在后台对用户进行增删改查

6. 希望可以对此项目进行更多的优化和扩展

本项目由18130Y03张振东独立开发,本项目基于IDEA进行开发,使用到了Swagger接口文档进行开发,使用Github进行协同开发,使用SpringBoot+BootStrapUI进行开发,数据库使用云端数据库进行搭建并开发,使用nginx进行反向代理(本项目域名为:8080),本项目曾使用docker部署到阿里云服务器上,基本使用Restful风格的接口,符合阿里巴巴开发规范。

系统架构解读:

整个系统可以分为两部分:后台管理系统,前台展示系统。

后台管理:

①对图书的管理:包括图书封面,图书类型,图书价格等信息的管理

②对图书类型的管理:对多种类型的图书分类进行管理

③对用户的管理:包括用户的类型,用户的姓名,生日等进行管理。

后台系统采用SpringBoot+BootStrap进行开发,后台页面使用thymeleaf进行展示。

预览图:

前台展示:

前台门户面向的是普通用户,包含与用户交互的一切功能。例如:注册,登录,查看书籍,查询书籍等。

前台使用了BootstrapUI+SpringBoot,使用Ajax进行异步交互。

预览图:

技术选型:

前端技术:

①基础的HTML、CSS、JavaScript(基于ES6标准)

②使用Ajax进行异步交互

③使用Jquery和BootStrapUI美化页面和简化开发

后端技术:

①基础的SpringMVC、Spring 5.0和MyBatis Plus

②Spring Boot 2.3.4.RELEASE版本

③nginx-1.10.2 进行反向代理

④Thymeleaf 简化开发HTML页面

⑤Swagger 进行编写接口文档,开发标准的Restful风格的接口

⑥devtools 热部署开发工具

4.文件描述

java

common: 下面有dto类体现了表现层与Model层之间的解耦

config:下面有关于mybatisplus的配置类,MVC的配置类,swagger的配置类

Controller:控制器类的包,负责处理DispatcherServlet 分发的请求

entity:实体类的包

handle:处理器的类,里面包括用户和管理员登录拦截的处理,i18n国际化拦截的处理和阿里巴巴规范中create_time和 update_time的处理

mapper:数据访问层

service:服务层

BookmanagersystemApplication:启动类

resources

mapper:存放mapper数据访问层的配置文件等

i18n:国际化配置类

static:存放css,js,img文件

Templates:存放html文件

application.properties:主配置文件

nucsell.sql:数据库的sql文件

5.实验源代码

数据库设计

数据库环境设置过程如下:

在阿里云服务器安装MySQL;

创建数据库、用户权限、数据库表和测试数据; 数据库文件存放在文件夹中,请开发者在MySQL中 按照顺序运行以下脚本:

nucsell.sql,用于创建数据库、用户详细信息和权限表,用来创建书籍目录表,用来创建书籍表及其关联关系。

图片(Navicat):

表 5.1 对象设计表

用户表

表 5.2 user表设计

目录表

表 5.3 category表设计

书籍表

在进行多表查询的时候,对目录表和书籍表进行了关联。

表 5.4 book表设计

Spring Boot开发环境

安装JDK8(可以是Oracle JDK或者OpenJDK)

安装Maven

安装Git(可选)

安装IDEA Community,建议安装Maven插件和Git插件。

IDEA

采用Maven命令安装依赖库

1.Common文件

① BookDto :表现层与Model层之间的解耦

@Data

public class BookDto implements Serializable {

private Long id;

/**

* 书籍名称

*/

@ApiModelProperty("书籍名称")

private String name;

/**

* 书籍价格

*/

@ApiModelProperty("书籍价格")

private String price;

/**

* 书籍介绍

*/

@ApiModelProperty("书籍介绍")

private String description;

/**

* 书籍名称

*/

@ApiModelProperty("书籍类型ID")

private int cid;

}

②GlobalExceptionHandler:全局异常处理器

@Slf4j

@RestControllerAdvice

public class GlobalExceptionHandler {

@ResponseStatus(HttpStatus.BAD_REQUEST)

@ExceptionHandler(value = MethodArgumentNotValidException.class)

public Result handler(MethodArgumentNotValidException e) {

log.error("实体校验异常:----------------{}", e);

BindingResult bindingResult = e.getBindingResult();

ObjectError objectError = bindingResult.getAllErrors().stream().findFirst().get();

return Result.fail(objectError.getDefaultMessage());

}

@ResponseStatus(HttpStatus.BAD_REQUEST)

@ExceptionHandler(value = IllegalArgumentException.class)

public Result handler(IllegalArgumentException e) {

log.error("Assert异常:----------------{}", e);

return Result.fail(e.getMessage());

}

@ResponseStatus(HttpStatus.BAD_REQUEST)

@ExceptionHandler(value = RuntimeException.class)

public Result handler(RuntimeException e) {

log.error("运行时异常:----------------{}", e);

return Result.fail(e.getMessage());

}

}

③Result:对前台返回结果的封装类

@Data

public class Result implements Serializable {

private int code; // 200是正常,非200表示异常

private String msg;

private Object data;

public static Result succ(Object data) {

return succ(200, "操作成功", data);

}

public static Result succ(int code, String msg, Object data) {

Result r = new Result();

r.setCode(code);

r.setMsg(msg);

r.setData(data);

return r;

}

public static Result fail(String msg) {

return fail(400, msg, null);

}

public static Result fail(String msg, Object data) {

return fail(400, msg, data);

}

public static Result fail(int code, String msg, Object data) {

Result r = new Result();

r.setCode(code);

r.setMsg(msg);

r.setData(data);

return r;

}

}

config目录

①MyMvcConfig

@Configuration

public class MyMvcConfig implements WebMvcConfigurer {

@Override

public void addViewControllers(ViewControllerRegistry registry) {

registry.addViewController("/admin.html").setViewName("admin");

registry.addViewController("/index.html").setViewName("index");

registry.addViewController("/main.html").setViewName("dashboard");

registry.addViewController("/register.html").setViewName("register");

registry.addViewController("/header.html").setViewName("header");

registry.addViewController("/footer.html").setViewName("footer");

registry.addViewController("/login.html").setViewName("login");

registry.addViewController("/book_list.html").setViewName("book_list");

}

@Override

public void addResourceHandlers(ResourceHandlerRegistry registry) {

registry.addResourceHandler("/asserts/img/**").

addResourceLocations("file:D:/360MoveData/Users/张振东/Desktop/图书管理系统/bookmanagersystem/src/main/resources/static/asserts/img/");

}

@Override

public void addInterceptors(InterceptorRegistry registry) {

// 2.0以前不会过滤.css,.js

registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").

excludePathPatterns("/admin.html","/","/login.html","/register.html", "/webjars/**", "/asserts/**", "/js/**", "/css/**");

registry.addInterceptor(new UserLoginHandlerInterceptor()).addPathPatterns("/**")

.excludePathPatterns("/admin.html","/", "/webjars/**", "/asserts/**", "/js/**", "/css/**");

}

@Bean

public LocaleResolver localeResolver() {

return new MyLocalResolver();

}

}

3.Controller目录

①AdminController

@Controller

@Api("管理员控制类")

@RequestMapping("/admin")

public class AdminController {

@Autowired

UserService userService;

@ApiOperation("管理员登录")

@PostMapping("/login")

public String login(@ApiParam("管理员账号") @RequestParam("username") String username, @ApiParam("管理员密码")@RequestParam("password") String password, Map<String, Object> map, HttpSession session) {

User admin = userService.getOne(new QueryWrapper<User>().eq("username", username).eq("password", password));

if (admin != null&&admin.getAuthority()==0) {

// 为防止表单重复提交,可以重定向到主页

session.setAttribute("loginUser", username);

return "redirect:/main.html";

} else {

map.put("msg", "用户名密码错误");

return "admin";

}

}

@ApiOperation("登出")

@GetMapping("/loginout")

public String loginOut(HttpSession session){

session.removeAttribute("loginUser");

return "redirect:/admin.html";

}

}

②BookController

@Controller

@Api("书籍控制类")

public class BookController {

@PostMapping("name")

@ApiOperation("返回书籍名称")

public String toBook(@ApiParam("书籍名称") @RequestBody String bookname) {

return bookname;

}

@Autowired

BookService bookService;

@ApiOperation("查询所有书籍返回列表页面")

@GetMapping("/books")

public String list(Model model) {

Collection<Book> all = bookService.list();

model.addAttribute("books", all);

return "book/list";

}

@ApiOperation("到书籍添加页面")

@GetMapping("/book")

public String toAddPage() {

return "book/add";

}

// springmvc自动将请求参数和入参对象的属性一一对应:要求请求参数的名字和javabean入参的对象里面的属性名是一样的

@ApiOperation("书籍添加")

@PostMapping("/book")

public String addBook(@ApiParam("书籍dto类") BookDto book, @ApiParam("书籍封面文件") @RequestParam(value = "cover", required = false) MultipartFile photo) {

Book book1 = bookService.addCover(book, photo);

System.out.println(book1);

bookService.save(book1);

// redirect:表示重定向到一个地址 / 表示当前项目路径

// forward:表示转发一个地址

return "redirect:/books";

}

@ApiOperation("获取单个书籍的信息")

@GetMapping("/book/{id}")

public String toEditPage(@ApiParam("书籍id") @PathVariable("id") Integer id, Model model) {

Book book = bookService.getById(id);

model.addAttribute("book", book);

// 回到修改页面(add是一个修改添加二合一的)

return "book/add";

}

@ApiOperation("修改书籍信息")

@PutMapping("/book")

public String updateBook(@ApiParam("书籍dto类") BookDto book, @RequestParam(value = "cover", required = false) MultipartFile photo) {

Book book1 = bookService.addCover(book, photo);

bookService.updateById(book1);

return "redirect:/books";

}

@ApiOperation("删除书籍信息")

@DeleteMapping("/book/{id}")

public String deleteBook(@ApiParam("书籍id") @PathVariable("id") Integer id) {

bookService.removeById(id);

return "redirect:/books";

}

@ApiOperation("查询本类型书籍返回列表页面")

@GetMapping("/booksInC/{id}")

@ResponseBody

public List<Book> list(@ApiParam("书籍类型id") @PathVariable("id") Integer id) {

List<Book> all = bookService.list(new QueryWrapper<Book>().eq("cid", id));

return all;

}

@ApiOperation("查询所有书籍")

@GetMapping("/getbooks")

@ResponseBody

public List<Book> getBooks() {

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

return all;

}

@ApiOperation("根据书籍类型和书籍最低价格查询书籍")

@GetMapping("/getBooks1")

@ResponseBody

public List<Book> getBooksByCidAndPrice(@ApiParam("书籍类型id") Integer cid, @ApiParam("书籍价格") String price) {

List<Book> all = bookService.list(new QueryWrapper<Book>().eq("cid", cid).gt("price", price));

return all;

}

}

③CategoryController

④UserController

4.entity目录

①Book:书籍实体类

@Data

@EqualsAndHashCode(callSuper = false)

@Accessors(chain = true)

@ApiModel("书籍实体")

public class Book implements Serializable {

private static final long serialVersionUID = 1L;

/**

* 主键ID

*/

@TableId(value = "id")

private Long id;

/**

* 书籍名称

*/

@ApiModelProperty("书籍名称")

private String name;

/**

* 书籍名称

*/

@ApiModelProperty("书籍类型ID")

private int cid;

/**

* 书籍价格

*/

@ApiModelProperty("书籍价格")

private String price;

/**

* 书籍封面

*/

@ApiModelProperty("书籍封面")

private String cover;

/**

* 创建时间

*/

@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")

@ApiModelProperty("书籍加入时间")

@TableField(fill = FieldFill.INSERT)

private Date createTime;

/**

* 更新时间

*/

@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")

@ApiModelProperty("书籍更新时间")

@TableField(fill = FieldFill.INSERT_UPDATE)

private Date updateTime;

/**

* 书籍介绍

*/

@ApiModelProperty("书籍介绍")

private String description;

}

②category:实际类型实体类

@Data

@EqualsAndHashCode(callSuper = false)

@Accessors(chain = true)

public class Category implements Serializable {

private static final long serialVersionUID = 1L;

@TableId(value = "cid")

private Integer cid;

private String cname;

/**

* 创建时间

*/

@TableField(fill = FieldFill.INSERT)

private Date createTime;

/**

* 更新时间

*/

@TableField(fill = FieldFill.INSERT_UPDATE)

private Date updateTime;

}

③User

5.handle目录

①LoginHandlerInterceptor:登录拦截

public class LoginHandlerInterceptor implements HandlerInterceptor {

// 目标方法执行之前

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

Object loginUser = request.getSession().getAttribute("loginUser");

if (loginUser==null){

// 未登录

request.setAttribute("msg","没有权限请先登录");

request.getRequestDispatcher("/index.html").forward(request,response);

return false;

}else{

return true;

}

}

@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

}

@Override

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

}

}

②MyLocalResolver:启用国际化配置

public class MyLocalResolver implements LocaleResolver {

@Override

public Locale resolveLocale(HttpServletRequest httpServletRequest) {

String l = httpServletRequest.getParameter("l");

Locale locale =Locale.getDefault();

if(!StringUtils.isEmpty(l)){

String [] spilt = l.split("_");

locale = new Locale(spilt[0],spilt[1]);

}

return locale;

}

@Override

public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {

}

}

③MyMetaObjectHandler

④UserLoginHandlerInterceptor

6.mapper

①BookMapper

②CategoryMapper

③UserMapper

7.service

①BookServiceImpl

@Service

public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService {

public Book addCover(BookDto book,MultipartFile photo) {

String path = "D:/360MoveData/Users/张振东/Desktop/图书管理系统/bookmanagersystem/src/main/resources/static/asserts/img/"; // 保存路径

String fileName = null;

if (!photo.isEmpty()) {

fileName = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());

String suffix = photo.getOriginalFilename()

.substring(photo.getOriginalFilename().lastIndexOf("."));

System.out.println(suffix);

if (!suffix.equals(".jpg") || !suffix.equals(".png") || !suffix.equals(".gif")) {

}

try {

// Spring提供了文件操作类FileCopyUtils

FileCopyUtils.copy(photo.getInputStream(), new FileOutputStream( path + fileName + suffix));

fileName = "; + fileName + suffix;

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

// return dealResultMap(false, "上传失败");

}

}

System.out.println(path);

Book book1 = new Book();

book1.setId(book.getId());

book1.setName(book.getName());

book1.setPrice(book.getPrice());

book1.setCover(fileName);

book1.setDescription(book.getDescription());

book1.setCid(book.getCid());

return book1;

}

}

②CategoryServiceImpl

③UserServiceImpl

④BookService

⑤CategoryService

⑥UserService

pom.xml

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

<project xmlns="; xmlns:xsi=";

xsi:schemaLocation=" ;>

<modelVersion>4.0.0</modelVersion>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.3.4.RELEASE</version>

<relativePath/> <!-- lookup parent from repository -->

</parent>

<groupId>com.zzd</groupId>

<artifactId>bookmanagersystem</artifactId>

<version>0.0.1-SNAPSHOT</version>

<name>bookmanagersystem</name>

<description>Demo project for Spring Boot</description>

<properties>

<java.version>1.8</java.version>

</properties>

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<!-- 热部署工具-->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-devtools</artifactId>

<scope>runtime</scope>

<optional>true</optional>

</dependency>

<!-- 简化开发-->

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<optional>true</optional>

</dependency>

<!-- 数据库驱动-->

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

</dependency>

<!-- 导入mybatis——plus 是自己开放的,不是官方的-->

<dependency>

<groupId>com.baomidou</groupId>

<artifactId>mybatis-plus-boot-starter</artifactId>

<version>3.0.5</version>

</dependency>

<!--mybatis代码生成器-->

<dependency>

<groupId>com.baomidou</groupId>

<artifactId>mybatis-plus-generator</artifactId>

<version>3.2.0</version>

</dependency>

<!-- 代码生成里面需要模板,so加上了freemarker-->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-freemarker</artifactId>

</dependency>

<!--集成swagger2,生成接口文档并调试-->

<!-- 引入swagger-bootstrap-ui包 /doc.html-->

<dependency>

<groupId>com.github.xiaoymin</groupId>

<artifactId>swagger-bootstrap-ui</artifactId>

<version>1.9.1</version>

</dependency>

<!-- -->

<dependency>

<groupId>io.springfox</groupId>

<artifactId>springfox-swagger2</artifactId>

<version>2.9.2</version>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-validation</artifactId>

<version>2.3.4.RELEASE</version>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-thymeleaf</artifactId>

</dependency>

<dependency>

<groupId>org.webjars</groupId>

<artifactId>jquery</artifactId>

<version>3.5.1</version>

</dependency>

<dependency>

<groupId>org.webjars</groupId>

<artifactId>bootstrap</artifactId>

<version>4.5.0</version>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

</plugins>

</build>

</project>

以上为项目的基本介绍和部分代码

6.运行截图

接口文档页面:

图6.1接口文档页面

登录界面

(1)普通用户登录界面

图6.2 普通用户登录界面

管理员登录界面(i18n)

图6.3 管理员登录界面(zh)

图6.4 管理员登录界面(en)

注册页面

图6.5注册界面

用户前台主界面

图6.6 用户前台主界面

查询分类界面(如编程)

图6.7查询分类界面

后台管理主界面

图6.8后台管理主界面

书籍管理主界面

图6.9查询书籍

图6.10增加书籍

图6.11 修改书籍

书籍类型管理主界面

图6.12查询书籍类型

图6.13增加书籍类型

图6.14修改书籍类型

用户管理主界面

图6.15查询用户

图6.16增加用户

图6.17修改用户

6.实验结论及心得

这次实验花了我5天时间完成,在这期间我学到了好多东西,在通宵熬夜的时候,感觉只要做出来一切都是值得的。我使用到了Swagger接口文档进行开发,使用Github进行协同开发,使用SpringBoot+BootStrapUI进行开发,数据库使用云端数据库进行搭建并开发,使用nginx进行反向代理(本项目域名为:8080),本项目曾使用docker部署到阿里云服务器上,基本使用Restful风格的接口,符合阿里巴巴开发规范。

标签: #javaee图书管理系统类设计