文章目录
- 1.开发项目流程
- 1.1开发开发
- 1.2数据库的设计
- 2.MySQL数据库相关代码
- 3.构造图书结构
- 3.1用户登录
- 3.2图书列表
- 3.3图书添加
- 3.4图书删除
- 3.4.1批量删除
- 3.5图书查询(翻页)
- 4.页面展示
- 4.1登录页面
- 4.2列表页面
- 4.3增加图书页面
- 4.4修改图书信息页面
- 5.功能展示
- 5.1增加图书信息
- 5.2修改图书信息
- 5.3删除单个图书
- 5.4批量删除图书
- 5.5翻页功能
- 7.拓展知识
- 7.1SpringBoot 中的mapper,service,controller,model 分别有什么用?
- 7.2DAO层、Service层和Controller层的区别
- 7.3 SSM系统架构
- 7.4MySQL(关系型数据库)和mongodb(非关系型数据库)的区别
- 7.5redis(非关系型数据库)
大家好,我是晓星航。今天为大家带来的是 相关的讲解!😀
1.开发项目流程
1.1开发开发
1.需求确认阶段:需求分析,需求评审
2.开发
1)方案设计
2)接口定义
3)开发业务代码
4)测试(自测+联调) - 和其他团队一起联合测试
3.提测阶段 - 测试人员
4.上线(发布)阶段
1.2数据库的设计
数据库编码:
1.安装时修改
2.建表时修改
2.MySQL数据库相关代码
1.建库
create databases book_test default character set utf8mb4;
2.建表
用户表:
DROP TABLE IF EXISTS user_info;
CREATE TABLE user_info (
id INT NOT NULL AUTO_INCREMENT,
user_name VARCHAR(128) NOT NULL,
password VARCHAR(128) NOT NULL,
delete_flag TINYINT(4) NULL DEFAULT 0,
create_time DATETIME DEFAULT now(),
update_time DATETIME DEFAULT now() ON UPDATE now(),
PRIMARY KEY(id),
UNIQUE INDEX user_name_UNIQUE (user_name ASC)) ENGINE = INNODB DEFAULT CHARACTER SET = utf8mb4 COMMENT ='用户表';
图书表:
DROP TABLE IF EXISTS book_info;
CREATE TABLE book_info (
id INT(11) NOT NULL AUTO_INCREMENT,
book_name VARCHAR(127) NOT NULL,
author VARCHAR(127) NOT NULL,
count INT(11) NOT NULL,
price DECIMAL(7,2) NOT NULL,
publish VARCHAR(256) NOT NULL,
status TINYINT(4) DEFAULT 1 COMMENT '0-无效,1-正常,2-不允许借阅',
create_time DATETIME DEFAULT noW(),
update_time DATETIME DEFAULT now() ON UPDATE now(),
PRIMARY KEY (id)
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
3.插入数据检验
用户表插入数据:
-- 初始化数据
INSERT INTo user_info (user_name,PASSWORD) VALUES ("admin","admin");
INSERT INTO user_info( user_name,PASSWORD) VALUES ("zhangsan","123456");
图书表插入数据:
-- 初始化图书数据
INSERT INTO book_info (book_name,author,count,price, publish) VALUES ('活着','余华',29,22.00,'北京文艺出版社');
INSERT INTO book_info (book_name,author,count,price, publish) VALUES ('平凡的世界','路遥',5,98.56,'北京十月文艺出版社');
INSERT INTO book_info (book_name,author,count,price,publish) VALUES ('三体','刘慈欣',9,102.67,'重庆出版社');
INSERT INTO book_info (book_name,author,count,price,publish) VALUES ('金字塔原理','麦肯锡',16,178.00,'民主与建设出版社');
批量化构造数据:
INSERT INTO book_info (book_name,author,count,price,publish) VALUES ('图书2','作者2',29,22.00,'出版社2'),('图书3','作者2',29,22.00,'出版社3'),('图书4','作者2',29,22.00,'出版社4'),('图书5','作者2',29,22.00,'出版社5'),('图书6','作者2',29,22.00,'出版社6'),('图书7','作者2',29,22.00,'出版社7'),('图书8','作者2',29,22.00,'出版社8'),('图书9','作者2',29,22.00,'出版社9'),('图书10','作者2',29,22.00,'出版社10'),('图书11','作者2',29,22.00,'出版社11');
INSERT INTO book_info (book_name,author,count,price,publish) VALUES ('图书12','作者2',29,22.00,'出版社12'),('图书13','作者2',29,22.00,'出版社13'),('图书14','作者2',29,22.00,'出版社14'),('图书15','作者2',29,22.00,'出版社15'),('图书16','作者2',29,22.00,'出版社16'),('图书17','作者2',29,22.00,'出版社17'),('图书18','作者2',29,22.00,'出版社18'),('图书19','作者2',29,22.00,'出版社19'),('图书20','作者2',29,22.00,'出版社20'),('图书21','作者2',29,22.00,'出版社21');
3.构造图书结构
3.1用户登录
约定前后端交互接口
[请求]
/user/login
Content-Type:application/x-www-form-urlencoded; charset-UTF-8
[参数]
name=zhangsan&password=123456
[响应]
true //账号密码验证正确,否则返回false
实现服务器代码
控制层:
从数据库中,根据名称查询用户,如果可以查到,并且密码一致,就认为登录成功
import com.example.demo.model.UserInfo;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.stringutils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.Restcontroller;
import javax.servlet.http.HttpSession;
@RequestMapping("/user")
@Restcontrnller
model层 - 存放实体类:
UserInfo.java:
package com.example.book.model;
import lombok.Data;
import java.util.Date;
@Data
public class UserInfo {
private Integer id;
private String userName;
private String password;
private Integer deleteFlag;
private Date createTime;
private Date updateTime;
}
Controller层:
UserController.java:
package com.example.book.controller;
import com.example.book.constant.Constants;
import com.example.book.model.UserInfo;
import com.example.book.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
@RequestMapping("/user")
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/login")
public Boolean login(String userName, String password, HttpSession session){
//校验参数
if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)){
return false;
}
//验证账号密码是否正确
/**
* if (userName.equals("admin")){ } 这种写法, 如果userName为null, 会报空指针异常
* 开发习惯, 养成
*/
//1. 根据用户名去查找用户信息
UserInfo userInfo = userService.getUserInfoByName(userName);
//2. 比对密码是否正确
if (userInfo==null || userInfo.getId()<=0){
return false;
}
if (password.equals(userInfo.getPassword())){
//账号密码正确
//存Session
userInfo.setPassword("");
session.setAttribute(Constants.SESSION_USER_KEY,userInfo);
return true;
}
return false;
}
}
根据用户名查用户信息,比对验证密码是否正确,账号密码正确后存Session,登录成功!
service层 - 主要是针对具体的问题的操作,把一些数据层的操作进行组合,间接与数据库打交道:
UserService.java:
package com.example.book.service;
import com.example.book.mapper.UserInfoMapper;
import com.example.book.model.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserInfoMapper userInfoMapper;
public UserInfo getUserInfoByName (String name) {
return userInfoMapper.selectUserByName(name);
}
}
Mapper层(Dao层):
UserInfoMapper.java:
package com.example.book.mapper;
import com.example.book.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface UserInfoMapper {
/**
* 根据用户名称查询用户信息
* @param name
* @return
*/
@Select("select * from user_info where user_name=#{name}")
UserInfo selectUserByName(String name);
}
3.2图书列表
可以由前端完成也可以由后端完成
前端完成:
后端完成:
model层 - 存放实体类:
PageResult.java:
package com.example.book.model;
import lombok.Data;
import java.util.List;
@Data
public class PageResult<T> {
/**
* 当前页的记录
*/
private List<T> records;
/**
* 总记录数
*/
private Integer total;
private PageRequest pageRequest;
public PageResult(List<T> records, Integer total,PageRequest pageRequest) {
this.records = records;
this.total = total;
this.pageRequest = pageRequest;
}
}
PageRequest.java:
package com.example.book.model;
import lombok.Data;
@Data
public class PageRequest {
/**
* 当前页码
*/
private Integer currentPage=1;
/**
* 每页显示条数
*/
private Integer pageSize=10;
private Integer offset;
public Integer getOffset() {
return (currentPage-1) * pageSize;
}
}
controller层:
BookController.java
package com.example.book.controller;
import com.example.book.model.*;
import com.example.book.service.BookService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
import java.util.List;
@Slf4j
@RequestMapping("/book")
@RestController
public class BookController {
@Autowired
private BookService bookService;
@RequestMapping("/getBookListByPage")
public Result getBookListByPage(PageRequest pageRequest, HttpSession session){
log.info("查询翻页信息, pageRequest:{}",pageRequest);
// //用户登录校验
// UserInfo userInfo = (UserInfo) session.getAttribute(Constants.SESSION_USER_KEY);
// if (userInfo==null|| userInfo.getId()<=0 || "".equals(userInfo.getUserName())){
// //用户未登录
// return Result.unlogin();
// }
//校验成功
if (pageRequest.getPageSize()<0 || pageRequest.getCurrentPage()<1){
return Result.fail("参数校验失败");
}
PageResult<BookInfo> bookInfoPageResult = null;
try {
bookInfoPageResult = bookService.selectBookInfoByPage(pageRequest);
return Result.success(bookInfoPageResult);
}catch (Exception e){
log.error("查询翻页信息错误,e:{}",e);
return Result.fail(e.getMessage());
}
}
}
service层:
BookService.java:
package com.example.book.service;
import com.example.book.enums.BookStatusEnum;
import com.example.book.mapper.BookInfoMapper;
import com.example.book.model.BookInfo;
import com.example.book.model.PageRequest;
import com.example.book.model.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Slf4j
@Service
public class BookService {
@Autowired
private BookInfoMapper bookInfoMapper;
public PageResult<BookInfo> selectBookInfoByPage(PageRequest pageRequest) {
if (pageRequest == null) {
return null;
}
//获取总记录数
Integer count = bookInfoMapper.count();
//获取当前记录
List<BookInfo> bookInfos = bookInfoMapper.selectBookInfoByPage(pageRequest.getOffset(), pageRequest.getPageSize());
if (bookInfos != null && bookInfos.size() > 0) {
for (BookInfo bookInfo : bookInfos) {
//根据status 获取状态的定义
bookInfo.setStatusCN(BookStatusEnum.getNameByCode(bookInfo.getStatus()).getName());
}
}
return new PageResult<>(bookInfos, count, pageRequest);
}
/**
* 添加图书
*
* @param bookInfo
* @return
*/
public Integer addBook(BookInfo bookInfo) {
Integer result = 0;
try {
result = bookInfoMapper.insertBook(bookInfo);
} catch (Exception e) {
log.error("添加图书出错, e:{}", e);
}
return result;
}
public BookInfo queryBookInfoById(Integer id) {
return bookInfoMapper.queryBookInfoById(id);
}
/**
* 更新图书
* @param bookInfo
* @return
*/
public Integer updateBook(BookInfo bookInfo) {
Integer result = 0;
try {
result = bookInfoMapper.updateBook(bookInfo);
} catch (Exception e) {
log.error("更新图书失败, e:{}", e);
}
return result;
}
public Integer batchDelete(List<Integer> ids){
Integer result =0;
try {
result = bookInfoMapper.batchDelete(ids);
}catch (Exception e){
log.error("批量删除图书失败, ids:{}",ids);
}
return result;
}
}
mapper层:
BookInfoMapper.java:
package com.example.book.mapper;
import com.example.book.model.BookInfo;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface BookInfoMapper {
/**
* 获取当前页的信息
* @param offset
* @param pageSize
* @return
*/
@Select("select * from book_info where status !=0 " +
"order by id desc limit #{offset},#{pageSize}")
List<BookInfo> selectBookInfoByPage(Integer offset, Integer pageSize);
/**
* 获取总记录数
* @return
*/
@Select("select count(1) from book_info where status !=0")
Integer count();
@Insert("insert into book_info (book_name,author, count, price, publish, status) " +
"values(#{bookName}, #{author}, #{count}, #{price},#{publish}, #{status})")
Integer insertBook(BookInfo bookInfo);
@Select("select * from book_info where id =#{id}")
BookInfo queryBookInfoById(Integer id);
Integer updateBook(BookInfo bookInfo);
Integer batchDelete(List<Integer> ids);
}
3.3图书添加
前端代码:
Controller层:
service层:
mapper层(Dao层):
3.4图书删除
企业中很少使用delete语句
delete语句通常是在进行数据修复时才会使用
pg.测试人员进行测试,手工造一些数据,测试完成之后,这条数据就是脏数据了
这个脏数据(假数据) 没有任何价值的,需要把数据删掉,使用delete语句
逻辑删除,物理删除
前端代码:
3.4.1批量删除
Controller层:
service层:
mapper层(Dao层):
3.5图书查询(翻页)
Controller层:
service层:
mapper层(Dao层):
4.页面展示
4.1登录页面
登录失败:
登录成功:
4.2列表页面
4.3增加图书页面
4.4修改图书信息页面
5.功能展示
5.1增加图书信息
5.2修改图书信息
5.3删除单个图书
5.4批量删除图书
5.5翻页功能
7.拓展知识
7.1SpringBoot 中的mapper,service,controller,model 分别有什么用?
MSCM:
- controller - 控制层
相当于MVC的C层,controller通过service的接口来控制业务流程,也可通过接收前端传过来的参数进行业务操作。
- model - 数据模型层
相当于MVC的M层,存放实体类,与数据库中的属性值基本保持一致。
- service - 业务逻辑层
主要是针对具体的问题的操作,把一些数据层的操作进行组合,间接与数据库打交道(提供操作数据库的方法)。
要做这一层的话,要先设计接口,在实现类。
- mapper - 数据存储对象 (Dao)
相当于DAO层,mapper层直接与数据库打交道(执行SQL语句),接口提供给service层。
图书管理系统目录:
7.2DAO层、Service层和Controller层的区别
简化理解:
图书管理系统目录:
7.3 SSM系统架构
7.4MySQL(关系型数据库)和mongodb(非关系型数据库)的区别
MySQL:
mongodb:
7.5redis(非关系型数据库)
感谢各位读者的阅读,本文章有任何错误都可以在评论区发表你们的意见,我会对文章进行改正的。如果本文章对你有帮助请动一动你们敏捷的小手点一点赞,你的每一次鼓励都是作者创作的动力哦!😘