兄弟们!jvm与线程已经差不多了,接下来的10天时间要放在中间件的学习上了,而且对于spring源码的研究也还没有开始呢!今天上午在图书馆实现了springboot框架写的图书管理系统,很简单的小东西,增删改查以及登录验证。页面没有渲染所以勉强看吧!
用户登录界面
管理员登录界面
用户查看的图书界面
添加新书界面
一、数据表设计
图书列表:
用户列表:
管理员列表:
二、application.yml文件配置
由于我使用的是Druid数据源所以配置的也是Druid,后续也可以在业务逻辑层添加Redis缓存,小项目的话配置Redis没什么作用。这里采用的是thymeleaf模板引擎加载html文件。
server:
port: 80
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
# 提供的模板引擎设置热部署,不使用cache,部署的文件类型是HTML5
thymeleaf:
cache: false
mode: HTML5
mvc:
static-path-pattern: /static/**
三、pojo层(使用lombok插件实现快速开发)
1、user实体类
import lombok.Data;
@Data
public class User {
private int userId;
private String password;
}
2、book实体类
import lombok.Data;
@Data
public class Book {
private int bookId;
private String bookName;
private String bookPrice;
private String bookType;
}
3、manager实体类
import lombok.Data;
/*管理员账户,可以管理对不规范用户注销,可以删除图书信息*/
@Data
public class Manager {
private int ManagerId;
private String password;
}
四、数据持久层(使用mybatis)
1、bookdao
import com.hlc.pojo.Book;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface BookDao {
// 利用mybatis框架写好需要使用的数据库操作方法
/*查看全部*/
@Select("select * from test.bootsm_book")
List<Book> allBook();
/*按条件查询*/
@Select("select * from test.bootsm_book where bookId = #{bookId}")
Book queryById(Integer bookId);
/*修改*/
@Update("update test.bootsm_book set bookName=#{bookName},bookPrice=#{bookPrice},bookType=#{bookType} where bookId=#{bookId}")
Boolean update(Book book);
/*插入*/
@Insert("insert into test.bootsm_book values (#{bookId},#{bookName},#{bookPrice},#{bookType})")
Boolean save(Book book);
/*按条件删除*/
@Delete("delete from test.bootsm_book where bookId=#{bookId}")
Boolean delete(Integer bookId);
/*实现登录*/
@Select("select * from test.bootsm_book where bookId=#{bookId} and bookName=#{bookName}")
Boolean login(Integer bookId,String bookName);
}
2、userdao
import com.hlc.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface UserDao {
/*登录权限赋予用户接口*/
@Select("select * from test.bootsm_user where userId=#{userId} and password=#{password}")
Boolean login(int userId,String password);
/*注册*/
@Insert("insert into test.bootsm_user values (#{userId},#{password}) ")
Boolean saveU(User user);
}
3、managerDao
@Mapper
public interface ManagerDao {
/*实现管理员主页面元素的加载:管理员信息表,用户表,图书表,用户留言表等*/
@Select("select * from test.bootsm_manager")
List<Manager> ManagerList();
@Select("select * from test.bootsm_user")
List<User> UserList();
@Select("select * from test.bootsm_book")
List<Book> BookList();
/*实现管理员账户的注册*/
@Insert("insert into test.bootsm_manager values (#{managerId},#{password})")
Boolean save(Manager manager);
/*实现管理员窗口的登录*/
@Select("select * from test.bootsm_manager where managerId=#{managerId} and password=#{password}")
Boolean login(int managerId,String password);
/*实现对用户的注销*/
@Delete("delete from test.bootsm_user where userId=#{userId}")
Boolean deleteUser(int userId);
/*实现对管理员账户的注销*/
@Delete("delete from test.bootsm_manager where managerId=#{managerId}")
Boolean deleteManager(int managerId);
/*修改密码*/
@Update("update test.bootsm_manager set password=#{password} where managerId=#{managerId}")
Boolean updateM(int managerId,String password);
}
五、业务层
1、bookservice与它的实现类
import com.hlc.pojo.Book;
import java.util.List;
public interface BookService {
List<Book> allBook();
Book queryById(Integer bookId);
Boolean update(Book book);
Boolean save(Book book);
Boolean delete(Integer bookId);
Boolean login(Integer bookId,String bookName);
}
import com.hlc.dao.BookDao;
import com.hlc.pojo.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("BookService")
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
@Override
public List<Book> allBook() {
return bookDao.allBook();
}
@Override
public Book queryById(Integer bookId) {
return bookDao.queryById(bookId);
}
@Override
public Boolean update(Book book) {
return bookDao.update(book);
}
@Override
public Boolean save(Book book) {
return bookDao.save(book);
}
@Override
public Boolean delete(Integer bookId) {
return bookDao.delete(bookId);
}
@Override
public Boolean login(Integer bookId, String bookName) {
return bookDao.login(bookId,bookName);
}
}
2、userservice与它的实现类
import com.hlc.pojo.User;
public interface UserService {
Boolean login(int userId,String password);
Boolean saveU(User user);
}
import com.hlc.dao.UserDao;
import com.hlc.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("UserService")
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userDao;
@Override
public Boolean login(int userId, String password) {
return userDao.login(userId,password);
}
@Override
public Boolean saveU(User user) {
return userDao.saveU(user);
}
}
3、managerService与它的实现类
public interface ManagerService {
Boolean save(Manager manager);
Boolean login(int managerId,String password);
Boolean deleteUser(int userId);
Boolean deleteManager(int managerId);
List<Manager> ManagerList();
List<User> UserList();
List<Book> BookList();
Boolean updateM(int managerId,String password);
}
@Service("ManagerService")
public class ManagerServiceImpl implements ManagerService{
@Autowired
private ManagerDao managerDao;
@Override
public Boolean save(Manager manager) {
return managerDao.save(manager);
}
@Override
public Boolean login(int managerId, String password) {
return managerDao.login(managerId,password);
}
@Override
public Boolean deleteUser(int userId) {
return managerDao.deleteUser(userId);
}
@Override
public Boolean deleteManager(int managerId) {
return managerDao.deleteManager(managerId);
}
@Override
public List<Manager> ManagerList() {
return managerDao.ManagerList();
}
@Override
public List<User> UserList() {
return managerDao.UserList();
}
@Override
public List<Book> BookList() {
return managerDao.BookList();
}
@Override
public Boolean updateM(int managerId, String password) {
return managerDao.updateM(managerId,password);
}
}
六、控制层
1、bookcontrller
@RestController
public class BookController {
@Autowired
private BookService bookService;
/*-----------------------------------------------------------------*/
/*我想这个路由很不合理:不合理的点在于从端口访问主页直接成功,会导致隐私泄露,待优化!*/
@RequestMapping("books")
public ModelAndView allBook(){
ModelAndView modelAndView = new ModelAndView();
List<Book> bookList = bookService.allBook();
modelAndView.addObject("bookList",bookList);
modelAndView.setViewName("BookList");
return modelAndView;
}
/*-----------------------------------------------------------------*/
@RequestMapping("query")
/*这里的查询结果就是一条没有页面的json数据*/
@ResponseBody
public Book query(Integer bookId){
return bookService.queryById(bookId);
}
/*先到add页面提交保存数据,再由真正的save方法接收数据并操作数据库*/
@RequestMapping("add")
public ModelAndView add(){
return new ModelAndView("addB");
}
@RequestMapping("save")
public ModelAndView save(Book book){
if(book!=null) {
bookService.save(book);
return allBook();
}
/*待优化:耦合问题,前端的跳转应该交给前端,而不是创造新的对象实例损耗内存开销*/
return new ManagerController().indexM();
}
/*删除的思路就是前端携带参数传递给后端,直接进行数据库操作后再进行加载列表显示!*/
@RequestMapping("delete/{bookId}")
public ModelAndView del(@PathVariable("bookId") Integer bookId){
bookService.delete(bookId);
return allBook();
}
/*修改操作的实现也是一样,先跳转到修改的表单页面,再通过访问路由调用修改方法*/
@RequestMapping("uForm")
public ModelAndView uForm(){
return new ModelAndView("updateB");
}
@RequestMapping("update")
public ModelAndView update(Book book){
bookService.update(book);
return allBook();
}
}
2、usercontroller
@RestController
public class UserController {
@Autowired
private UserService userService;
/*------------------------------------------------------------------------------------*/
/*这个复写就是为了实现登录成功返回书籍列表的操作,待优化!*/
/*目前的优化方案:
* 1,我们可以给userDao增添全部图书显示的功能
*
* 2.就是直接注入使用,优化内部代码。
*
* 3.创建BookController对象直接调用它的allBook方法
*
* */
@Autowired
private BookService bookService;
public ModelAndView allBook(){
ModelAndView modelAndView = new ModelAndView();
List<Book> bookList = bookService.allBook();
modelAndView.addObject("bookList",bookList);
modelAndView.setViewName("BookList");
return modelAndView;
}
/*----------------------------------------------------------------------------------*/
/*实现登录功能,原理很简单,登录成功就可以访问,不成功就不能进入其他页面,跳转错误提示页面*/
@RequestMapping("login")
public ModelAndView login(){
return new ModelAndView("loginU");
}
@RequestMapping("index")
public ModelAndView index(Integer userId,String password){
/*这里登陆失败会跳转错误页面,但是!有一点问题,在数据库查询空会报空指针异常,来处理一下?*/
/*先判断是否userId与password是否为null,如果为null则直接跳过调用的业务逻辑代码*/
/*小知识点Integer类型与int类型有本质的区别,Integer是一个对象类型,存储在堆内存*/
if((userId!=null)&&(password!=null)) {
Boolean login = userService.login(userId, password);
if (login) {
return allBook();
}
return new ModelAndView("error");
}
/*这样的判断杜绝了前段登录表单不输入直接点击的情况,不输入完整一直停留在登录页面*/
return new ModelAndView("loginU");
}
/*实现注册功能*/
@RequestMapping("addU")
public ModelAndView add(ModelAndView modelAndView){
modelAndView.setViewName("addU");
return modelAndView;
}
@RequestMapping("saveU")
public ModelAndView saveU(User user){
ModelAndView modelAndView =new ModelAndView();
Boolean save = userService.saveU(user);
if(save) {
modelAndView.setViewName("loginU");
return modelAndView;
}
return new ModelAndView("addU");
}
/*实现用户密码的更改*/
@RequestMapping("updateU")
public ModelAndView updateU(){
return new ModelAndView("updateU");
}
@RequestMapping("updateUed")
public ModelAndView updateUed(Integer userId,String password){
userService.updateP(userId,password);
return login();
}
}
3、managerController
@RestController
public class ManagerController {
@Autowired
private ManagerService managerService;
/*管理员主页页面需要展示的元素在此方法下根据数据链路去调用方法数据库获取*/
/*这个因为从登录进而不从端口直接访问,这样合理性好一些,与BookController里的大部分方法返回书籍列表的方式相比而且减少代码复用。
* 这里我没有注册请求的路由映射,但是,我该怎么设计页面里返回主页面的逻辑?*/
@RequestMapping("manager")
public ModelAndView indexM(){
ModelAndView modelAndView = new ModelAndView();
List<Manager> managerList = managerService.ManagerList();
List<User> userList = managerService.UserList();
List<Book> bookList = managerService.BookList();
modelAndView.addObject("managerList",managerList);
modelAndView.addObject("userList",userList);
modelAndView.addObject("bookList",bookList);
modelAndView.setViewName("ManagerIndex");
return modelAndView;
}
/*实现管理员账户的注册功能,这个页面的逻辑也是先从一个表单提交数据,再从表单访问路由下的方法*/
@RequestMapping("addM")
public ModelAndView addM(){
return new ModelAndView("addM");
}
@RequestMapping("saveM")
public ModelAndView saveM(Manager manager){
managerService.save(manager);
/*返回管理员登录页面*/
return new ModelAndView("loginM");
}
/*实现管理员窗口的登录*/
@RequestMapping("loginM")
public ModelAndView loginM(){
return new ModelAndView("loginM");
}
@RequestMapping("indexM")
public ModelAndView indexM(Integer managerId,String password ){
if(managerId!=null && password!=null) {
Boolean login = managerService.login(managerId, password);
if (login){
return indexM();
}else return new ModelAndView("error");
}
return new ModelAndView("loginM");
}
/*实现对用户的注销*/
@RequestMapping("deleteU/{userId}")
public ModelAndView deleteU(@PathVariable("userId") int userId){
managerService.deleteUser(userId);
return indexM();
}
/*实现对管理员账户的注销*/
@RequestMapping("delete/{managerId}")
public ModelAndView deleteM(@PathVariable("managerId")int managerId){
managerService.deleteManager(managerId);
return indexM();
}
/*实现密码的修改*/
@RequestMapping("updateM")
public ModelAndView updateM(){
return new ModelAndView("updateM");
}
@RequestMapping("updateMed")
public ModelAndView updateMed(Integer managerId,String password){
managerService.updateM(managerId,password);
return loginM();
}
}
七、web层(篇幅太大,只展示利用th标签遍历BookList的列表页面)
BookList.html
<!DOCTYPE html>
<html lang="zh" xmlns:th="Thymeleaf 官网网址">
<head>
<meta charset="UTF-8">
<title>用户查看的主页</title>
</head>
<style type="text/css">
body{
margin: 5px;
padding: 5px;
background-image: url("../static/img/hist.jpg");
background-attachment: fixed;
background-position: center;
background-size: cover;
}
nav{
height: 100px;
}
div{
/*字体样式斜体*/
font-style: italic;
color: white;
margin: 15px;
text-align: center;
font-size: 25px;
}
input[type=text],input[type=password]{
height: 30px;
width: 200px;
/*这是输入框的背景颜色*/
background-color: aliceblue;
/*输入的文本颜色*/
color: green;
font-size: 20px;
/*边框*/
border: 2px solid black;
/*圆角边框*/
border-radius: 4px;
}
input:focus{
background-color: white;
}
.button1{
height: 30px;
width: 150px;
}
a{
color: black;
text-decoration: none;
}
.a1{
color: white;
text-decoration: none;
}
table{
width: 100%;
text-align: center;
border: 2px white solid;
border-radius: 2px;
}
th{
margin: 20px;
}
</style>
<body>
<div>
<div><h2>书目列表</h2></div>
<!-- <div>
<form action="/query" method="post">
<div>搜索书籍:<input type="text" name="bookId"> <input type="submit"></div>
</form>
</div>-->
<div>
<table>
<thead>
<tr>
<th>图书编号</th>
<th>图书名称</th>
<th>图书类型</th>
<th>图书价格</th>
<th>用户操作</th>
</tr>
</thead>
<tbody>
<tr th:each="book:${bookList}" >
<td th:text="${book.bookId}"></td>
<td th:text="${book.bookName}"></td>
<td th:text="${book.bookType}"></td>
<td th:text="${book.bookPrice}"></td>
<td><a class="a1" href="">借</a> or <a class="a1" href="">还</a></td>
</tr>
</tbody>
</table>
<div>
<button class="button1"><a href="">确定</a></button>
<button class="button1"><a href="/login">返回</a> </button>
<button class="button1"><a href="">搜索书籍</a></button>
</div>
</div>
</div>
</body>
</html>
八、导入的依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--导入静态加载的模板引擎坐标-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>