图书管理系统(四)图书管理系统实战(二)

简介: 图书管理系统(四)图书管理系统实战(二)

1. 前言

前一篇文章 图书管理系统实战(一) 中,我们已经编写了 pojo、dao 层以及配置 dao 层对应的 mapper,从现在开始,我们开始编写 service 层和 controller 层。


2. service 层

2.1 预约业务操作码

在正式编写 service 层之前,我们先定义一个预约图书操作返回码的数据字段,用于反馈给客户信息;


返回码 说明

1 预约成功

0 预约失败

-1 预约重复

-2 系统异常


package com.cunyu.utils;
import com.cunyu.dto.AppointDto;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
 * @author : cunyu
 * @version : 1.0
 * @className : AppointStateEnum
 * @date : 2020/7/24 10:50
 * @description : 定义预约业务的数据字典
 */
@Getter
@AllArgsConstructor
public enum AppointStateEnum {
    SUCCESS(1, "预约成功"), FAILURE(0, "预约失败"), REPEAT(-1, "预约重复"), SYSTEMERROR(-2, "系统异常");
    private int state;
    private String stateInfo;
    /**
     * @param stat 状态码
     * @return
     * @description 获取状态码对应 enum
     * @date 2020/7/24 10:57
     * @author cunyu1943
     * @version 1.0
     */
    public static AppointStateEnum stateOf(int stat) {
        for (AppointStateEnum state : values()
        ) {
            if (stat == state.getState()) {
                return state;
            }
        }
        return null;
    }
}

3.2 数据传输层

定义好预约业务的数据字典之后,新建一个数据传输类用来传输我们的预约结果;

package com.cunyu.dto;
import com.cunyu.pojo.Appointment;
import com.cunyu.utils.AppointStateEnum;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * @author : cunyu
 * @version : 1.0
 * @className : AppointDto
 * @date : 2020/7/24 10:46
 * @description : 用于数据传输,封装
 */
@Data
@NoArgsConstructor
public class AppointDto {
    private int bookId;
    // 状态码
    private int state;
    // 状态信息
    private String stateInfo;
    // 预约成功的对象
    private Appointment appointment;
    //    预约失败的构造器
    public AppointDto(int bookId, AppointStateEnum appointStateEnum) {
        this.bookId = bookId;
        this.state = appointStateEnum.getState();
        this.stateInfo = appointStateEnum.getStateInfo();
    }
    //    预约成功的构造器
    public AppointDto(int bookId, AppointStateEnum appointStateEnum, Appointment appointment) {
        this.bookId = bookId;
        this.state = appointStateEnum.getState();
        this.stateInfo = appointStateEnum.getStateInfo();
        this.appointment = appointment;
    }
}

2.3 service 业务代码编写

2.3.1 BookService.java

package com.cunyu.service;
import com.cunyu.dto.AppointDto;
import com.cunyu.pojo.Book;
import java.util.List;
/**
 * @author : cunyu
 * @version : 1.0
 * @className : BookService
 * @date : 2020/7/24 10:44
 * @description : Book 业务接口
 */
public interface BookService {
    /**
     * @param bookId 图书 ID
     * @return 对应 ID 的图书
     * @description 根据图书 id 查询图书
     * @date 2020/7/24 11:41
     * @author cunyu1943
     * @version 1.0
     */
    Book getById(int bookId);
    /**
     * @param
     * @return 所有图书的列表
     * @description 获取图书列表
     * @date 2020/7/24 11:41
     * @author cunyu1943
     * @version 1.0
     */
    List<Book> getList();
    /**
     * @param bookId    图书 id
     * @param studentId 学生 Id
     * @return
     * @description 返回预约结果
     * @date 2020/7/24 11:39
     * @author cunyu1943
     * @version 1.0
     */
    AppointDto appoint(int bookId, int studentId);
}

2.3.2 BookServiceImpl.java

package com.cunyu.service.impl;
import com.cunyu.dao.AppointmentDao;
import com.cunyu.dao.BookDao;
import com.cunyu.dto.AppointDto;
import com.cunyu.pojo.Appointment;
import com.cunyu.pojo.Book;
import com.cunyu.service.BookService;
import com.cunyu.utils.AppointStateEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * @author : cunyu
 * @version : 1.0
 * @className : BookServiceImpl
 * @date : 2020/7/24 11:43
 * @description : Book 业务接口实现类
 */
@Service
public class BookServiceImpl implements BookService {
    //    依赖注入
    @Autowired
    private BookDao bookDao;
    @Autowired
    private AppointmentDao appointmentDao;
    public Book getById(int bookId) {
        return bookDao.queryById(bookId);
    }
    public List<Book> getList() {
        return bookDao.queryAll(0, 3);
    }
    public AppointDto appoint(int bookId, int studentId) {
        AppointDto appointDto = null;
        try {
            // 减库存
            int update = bookDao.reduceNumber(bookId);
            if (update <= 0) {
                System.out.println(AppointStateEnum.FAILURE);
            } else {
                // 执行预约操作
                int insert = appointmentDao.insertAppointment(bookId, studentId);
                if (insert <= 0) {
                    System.out.println(AppointStateEnum.REPEAT);
                } else {
                    Appointment appointment = appointmentDao.queryByKeyWithBook(bookId, studentId);
                    appointDto = new AppointDto(bookId, AppointStateEnum.SUCCESS, appointment);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return appointDto;
    }
}

2.4 测试

package com.cunyu.service.impl;
import com.cunyu.service.BookService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
 * @author : cunyu
 * @version : 1.0
 * @className : BookServiceImplTest
 * @date : 2020/7/24 11:53
 * @description : BookServiceImpl 测试类
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/spring-*.xml")
public class BookServiceImplTest {
    @Autowired
    private BookService bookService;
    @Test
    public void testAppoint() {
        int bookId = 1;
        int studentId = 18301343;
        System.out.println(bookService.appoint(bookId, studentId));
    }
}

下图是我们测试后数据库中的数据,说明此时我们的 service 层接口测试成功。

image.png

2.5 封装结果

既然我们的 service 层接口和实现类都编写好了,我们就需要将结果进行封装成 json 格式,方便我们传到 controller 交互使用。

package com.cunyu.dto;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * @author : cunyu
 * @version : 1.0
 * @className : ResultDto
 * @date : 2020/7/24 12:11
 * @description : 封装结果为 json
 */
@Data
@NoArgsConstructor
public class ResultDto<T> {
    // 是否预约成功
    private boolean success;
    // 预约成功返回的数据
    private T data;
    // 错误信息
    private String error;
    // 预约成功的构造器
    public ResultDto(boolean success, T data) {
        this.success = success;
        this.data = data;
    }
    // 预约失败的构造器
    public ResultDto(boolean success, String error) {
        this.success = success;
        this.error = error;
    }
}

3. controller 层

编写好 service 层之后,我们就剩下最后的 controller 层了;

package com.cunyu.controller;
import com.cunyu.dto.AppointDto;
import com.cunyu.dto.ResultDto;
import com.cunyu.pojo.Book;
import com.cunyu.service.BookService;
import com.cunyu.utils.AppointStateEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * @author : cunyu
 * @version : 1.0
 * @className : BookController
 * @date : 2020/7/24 12:20
 * @description : Book controller 层
 */
@Controller
@RequestMapping("/book")
public class BookController {
    @Autowired
    private BookService bookService;
    // url:ip:port:/book/list
    @GetMapping("/list")
    private String list(Model model) {
        List<Book> bookList = bookService.getList();
        model.addAttribute("bookList", bookList);
        return "list";
    }
    @GetMapping(value = "/{bookId}/detail")
    private String detail(@PathVariable("bookId") Integer bookId, Model model) {
        if (bookId == null) {
            return "redirect:/book/list";
        }
        Book book = bookService.getById(bookId);
        if (book == null) {
            return "forward:/book/list";
        }
        model.addAttribute("book", book);
        return "detail";
    }
    //ajax 传递 json 数据到前端
    @RequestMapping(value = "/{bookId}/appoint", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    private ResultDto<AppointDto> appoint(@PathVariable("bookId") Integer bookId, @RequestParam("studentId") Integer studentId) {
        if (studentId == null || studentId.equals("")) {
            return new ResultDto<>(false, "学号不能为空");
        }
        AppointDto appointDto = null;
        try {
            appointDto = bookService.appoint(bookId, studentId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResultDto<AppointDto>(true, appointDto);
    }
}

4. 前端

好了,我们的后台就开发完毕了,接下来就可以去编写前端页面了。然后启动 Tomcat,访问对应 url 即可。

4.1 list.jsp

<%--
  Created by IntelliJ IDEA.
  User: cunyu
  Date: 2020/7/23
  Time: 9:47
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>图书列表页</title>
</head>
<body>
<h1>${bookList}</h1>
</body>
</html>

image.png

4.2 detail.jsp

<%--
  Created by IntelliJ IDEA.
  User: cunyu
  Date: 2020/7/23
  Time: 10:02
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>图书详情页</title>
</head>
<body>
    <h1>${book.name}</h1>
    <h2>${book.bookId}</h2>
    <h2>${book.number}</h2>
</body>
</html>

image.png

5. 总结

到此,我们的后台所有服务都写好了,SSM 框架整合配置,与应用实例部分已经结束,前端部分就简单写了个数据展示页面。

目录
相关文章
|
6月前
|
C++
图书管理系统(C++)
图书管理系统(C++)
45 0
|
6月前
|
Java 关系型数据库 MySQL
毕业设计|课程设计|SSM开发实现图书管理系统(一)
毕业设计|课程设计|SSM开发实现图书管理系统
|
1月前
|
C语言 Python
图书管理系统
【10月更文挑战第11天】图书管理系统。
47 5
|
6月前
|
存储 安全 Java
图书管理系统的设计与实现
图书管理系统的设计与实现
|
6月前
|
前端开发 Java 数据库
【JavaEE进阶】 图书管理系统开发日记——伍
【JavaEE进阶】 图书管理系统开发日记——伍
|
6月前
|
前端开发 JavaScript Java
毕业设计|课程设计|SSM开发实现图书管理系统
毕业设计|课程设计|SSM开发实现图书管理系统
100 1
|
6月前
|
人工智能 前端开发 JavaScript
毕业设计|课程设计|SSM开发实现图书管理系统(二)
毕业设计|课程设计|SSM开发实现图书管理系统
|
Java 关系型数据库 MySQL
0021Java程序设计-SSM框架图书管理系统
0021Java程序设计-SSM框架图书管理系统
56 0
|
C# 数据库
C#图书管理系统
C#图书管理系统
86 0
图书管理系统1
图书管理系统
161 1