目录
1、项目简介
2、适用人群
3、使用技术
前端:
后端:
数据库:
测试:
4、功能简介
5、工具介绍
(1)mevan项目搭建
(2)Spring Boot项目搭建
(3)Java版本显示
(4)Lombook项目搭建
(5)日志配置
(6)端口设置(三种方式)
(7)Junit项目搭建
(8)Mybatis项目搭建(IDEA系统自带)
(9)MybatisPlus项目搭建(手动配置)
(10)项目搭建
(11)Vue介绍
(12)Element介绍
(13)Postman介绍
(14)Axios 介绍
(15)SpringMVC 介绍
(16)Springboot介绍
(17)……
6、后端相关代码介绍
目录
(1)拦截器
(2)分页操作
(3)实体类开发
(4)交互功能
(5)数据层开发
(6)数据库应用
(7)查询操作
(8)业务层开发
(10)前后端数据协议:
(11)异常处理
7、前端相关代码介绍
目录:
(1)头部定义
(2)盒子定义
(3)分页组件
(4)新增标签弹层
(5)编辑标签弹层
(6)引入组件库
(7)分页查询
(8)发送异步请求
(9)切换页码
(10)弹出添加窗口
(11)重置表单
(12)添加
(13)取消
(14)删除
(15)弹出编辑窗口
(16)修改
8、项目展示及相关测试
8、项目打包,无IDEA等环境下运行
一个简单的图书管理系统,周期为5天的一个系统,一个可以作为的模板的系统。
有一定Java+前端基础的学习者,想快速了解Spring Boot项目框架的学习者和开发者,想回忆起某一技术的开发与运维人员。
Vue+Element-UI+axios
Spring Boot 2 + MybatisPlus + SpringMVC + Juint + Druid+Lombook
MySql5.5+
Restful+Postman
图书管理的查询、添加、修改、删除、异常处理与分页操作。
若您未使用过 Spring Boot 工程或不会创建 Spring Boot项目,请参考此篇文章,有详细介绍
《Spring Boot开发实践》之Spring Boot 入门_初尘屿风的博客-CSDN博客
Java框架入门——SpringBoot框架_初尘屿风的博客-CSDN博客
org.springframework.boot
spring-boot-maven-plugin
org.springframework.boot
spring-boot-starter-parent
2.5.4
1.8
org.projectlombok
lombok
spring.main.banner-mode=off
1、默认方式
server.port=80
2、.yml:推荐使用
server:
port:
3、.yaml
server:
port:
2与3是有一定的差别,2是主流;
注意事项:
大小写敏感
属性层级关系使用多行描述,每行结尾使用冒号结束
使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用Tab键)
属性值前面添加空格(属性名与属性值之间使用冒号+空格作为分隔)
核心规则:数据前面要加空格与冒号隔开
@SpringBootTest
class Springboot07JunitApplicationTests {
@Autowired
private BookService bookService;
@Test
public void testSave(){
bookService.save();
} }
springboot_05_mybatis
0.0.1-SNAPSHOT
springboot_05_mybatis
Demo project for Spring Boot
com.test
springboot_06_mybatis_plus
0.0.1-SNAPSHOT
springboot_06_mybatis_plus
Demo project for Spring Boot
com.alibaba
druid-spring-boot-starter
1.2.6
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。
Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。
Postman is an API platform for building and using APIs. Postman simplifies each step of the API lifecycle and streamlines collaboration so you can create better APIs—faster.
Spring web MVC 框架提供了模型-视图-控制的体系结构和可以用来开发灵活、松散耦合的 web 应用程序的组件。MVC 模式导致了应用程序的不同方面(输入逻辑、业务逻辑和 UI 逻辑)的分离,同时提供了在这些元素之间的松散耦合。
官网:
Spring | Home
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".
等等
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
//作为springmvc的异常处理器
//@ControllerAdvice
@RestControllerAdvice
public class ProjectExceptionAdvice {
//拦截所有的异常信息
@ExceptionHandler(Exception.class)
public R doException(Exception ex){
//记录日志
//通知运维
//通知开发
ex.printStackTrace();
return new R("服务器故障,请稍后再试!");
}
@GetMapping("{currentPage}/{pageSize}")
public R getPage(@PathVariable int currentPage,@PathVariable int pageSize,Book book){
// System.out.println("参数==>"+book);
IPage
page = bookService.getPage(currentPage, pageSize,book); //如果当前页码值大于了总页码值,那么重新执行查询操作,使用最大页码值作为当前页码值
if( currentPage > page.getPages()){
page = bookService.getPage((int)page.getPages(), pageSize,book);
}
return new R(true, page);
}
@Test
void testGetPage(){
IPage page = new Page(1,5);
bookDao.selectPage(page,null);
}
@Override
public IPage
getPage(int currentPage, int pageSize) { IPage page = new Page(currentPage,pageSize);
bookDao.selectPage(page,null);
return page;
}
@Override
public IPage
getPage(int currentPage, int pageSize, Book book) { LambdaQueryWrapper
lqw = new LambdaQueryWrapper (); lqw.like(Strings.isNotEmpty(book.getType()),Book::getType,book.getType());
lqw.like(Strings.isNotEmpty(book.getName()),Book::getName,book.getName());
lqw.like(Strings.isNotEmpty(book.getDescription()),Book::getDescription,book.getDescription());
IPage page = new Page(currentPage,pageSize);
bookDao.selectPage(page,lqw);
return page;
}
import lombok.Data;
@Data
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}
@PostMapping
public R save(@RequestBody Book book) throws IOException {
// R r = new R();
// boolean flag = bookService.save(book);
// r.setFlag(flag);
if (book.getName().equals("123") ) throw new IOException();
boolean flag = bookService.save(book);
return new R(flag, flag ? "添加成功^_^" : "添加失败-_-!");
}
@PutMapping
public R update(@RequestBody Book book) throws IOException {
if (book.getName().equals("123") ) throw new IOException();
boolean flag = bookService.modify(book);
return new R(flag, flag ? "修改成功^_^" : "修改失败-_-!");
}
@DeleteMapping("{id}")
public R delete(@PathVariable Integer id){
return new R(bookService.delete(id));
}
@GetMapping("{id}")
public R getById(@PathVariable Integer id){
return new R(true, bookService.getById(id));
}
com.baomidou mybatis-plus-boot-starter 3.4.3
com.alibaba druid-spring-boot-starter 1.2.6
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
username: root
password: 123
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
id-type: auto
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
@Test
void testGetByCondition(){
IPage page = new Page(1,10);
LambdaQueryWrapper
lqw = new LambdaQueryWrapper (); lqw.like(Book::getName,"Spring");
bookDao.selectPage(page,lqw);
}
@Test
void testGetByCondition(){
QueryWrapper
qw = new QueryWrapper (); qw.like("name","Spring");
bookDao.selectList(qw);
}
支持动态拼写查询条件:
@Test
void testGetByCondition(){
String name = "Spring";
IPage page = new Page(1,10);
LambdaQueryWrapper
lqw = new LambdaQueryWrapper (); lqw.like(Strings.isNotEmpty(name),Book::getName,"Spring");
bookDao.selectPage(page,lqw);
}
public interface BookService {
boolean save(Book book);
boolean delete(Integer id);
boolean update(Book book);
Book getById(Integer id);
List
getAll(); IPage
getByPage(int currentPage,int pageSize); }
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
public Boolean save(Book book) {
return bookDao.insert(book) > 0; }
public Boolean delete(Integer id) {
return bookDao.deleteById(id) > 0; }
public Boolean update(Book book) {
return bookDao.updateById(book) > 0; } }
(9)表现层开发
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private IBookService bookService;
@GetMapping
public List
getAll(){ return bookService.list();
} }
初始界面:
测试界面:
设计表现层返回结果的模型类,用于后端与前端进行数据格式统一,也称为前后端数据协议
import lombok.Data;
@Data
public class R {
private Boolean flag;
private Object data;
private String msg;
public R(){}
public R(Boolean flag){
this.flag = flag;
}
public R(Boolean flag,Object data){
this.flag = flag;
this.data = data;
}
public R(Boolean flag,String msg){
this.flag = flag;
this.msg = msg;
}
public R(String msg){
this.flag = false;
this.msg = msg;
}
}
@RestControllerAdvice
public class ProjectExceptionAdvice { @ExceptionHandler(Exception.class)
public R doOtherException(Exception ex){
//记录日志
//发送消息给运维
//发送邮件给开发人员,ex对象发送给开发人员
ex.printStackTrace();
return new R(false,null,"系统错误,请稍后再试!");
} }
//添加
handleAdd () {
//发送ajax请求
axios.post("/books",this.formData).then((res)=>{
//如果操作成功,关闭弹层,显示数据
if(res.data.flag){
this.dialogFormVisible = false;
this.$message.success("添加成功");
}else {
this.$message.error(res.data.msg);
}
}).finally(()=>{
this.getAll();
});
},
@PostMapping
public R save(@RequestBody Book book) throws IOException {
Boolean flag = bookService.insert(book);
return new R(flag , flag ? "添加成功^_^" : "添加失败-_-!"); }
目的:国际化
SpringBoot2案例
查询
新建
编辑
删除
(3)分页组件
class="pagiantion"
@current-change="handleCurrentChange"
:current-page="pagination.currentPage"
:page-size="pagination.pageSize"
layout="total, prev, pager, next, jumper"
:total="pagination.total">
(4)新增标签弹层
(5)编辑标签弹层
var vue = new Vue({
el: '#app',
data:{
dataList: [],//当前页要展示的列表数据
dialogFormVisible: false,//添加表单是否可见
dialogFormVisible4Edit:false,//编辑表单是否可见
formData: {},//表单数据
rules: {//校验规则
type: [{ required: true, message: '图书类别为必填项', trigger: 'blur' }],
name: [{ required: true, message: '图书名称为必填项', trigger: 'blur' }]
},
pagination: {//分页相关模型数据
currentPage: 1,//当前页码
pageSize:10,//每页显示的记录数
total:0,//总记录数
type: "",
name: "",
description: ""
}
},
//钩子函数,VUE对象初始化完成后自动执行
created() {
//调用查询全部数据的操作
this.getAll();
},
methods: {
//列表
// getAll() {
// //发送异步请求
// axios.get("/books").then((res)=>{
// // console.log(res.data);
// this.dataList = res.data.data;
// });
// },
//分页查询
getAll() {
//组织参数,拼接url请求地址
// console.log(this.pagination.type);
param = "?type="+this.pagination.type;
param +="&name="+this.pagination.name;
param +="&description="+this.pagination.description;
// console.log(param);
//发送异步请求
axios.get("/books/"+this.pagination.currentPage+"/"+this.pagination.pageSize+param).then((res)=>{
this.pagination.pageSize = res.data.data.size;
this.pagination.currentPage = res.data.data.current;
this.pagination.total = res.data.data.total;
this.dataList = res.data.data.records;
});
//切换页码
handleCurrentChange(currentPage) {
//修改页码值为当前选中的页码值
this.pagination.currentPage = currentPage;
//执行查询
this.getAll();
},
//弹出添加窗口
handleCreate() {
this.dialogFormVisible = true;
this.resetForm();
},
this.$message.success("修改成功");
}else{
this.$message.error("修改失败");
}
}).finally(()=>{
//2.重新加载数据
this.getAll();
});
//重置表单
resetForm() {
this.formData = {};
},
//添加
handleAdd () {
axios.post("/books",this.formData).then((res)=>{
//判断当前操作是否成功
if(res.data.flag){
//1.关闭弹层
this.dialogFormVisible = false;
this.$message.success(res.data.msg);
}else{
this.$message.error(res.data.msg);
}
}).finally(()=>{
//2.重新加载数据
this.getAll();
});
},
//取消
cancel(){
this.dialogFormVisible = false;
this.dialogFormVisible4Edit = false;
this.$message.info("当前操作取消");
},
// 删除
handleDelete(row) {
// console.log(row);
this.$confirm("此操作永久删除当前信息,是否继续?","提示",{type:"info"}).then(()=>{
axios.delete("/books/"+row.id).then((res)=>{
if(res.data.flag){
this.$message.success("删除成功");
}else{
this.$message.error("数据同步失败,自动刷新");
}
}).finally(()=>{
//2.重新加载数据
this.getAll();
});
}).catch(()=>{
this.$message.info("取消操作");
});
},
//弹出编辑窗口
handleUpdate(row) {
axios.get("/books/"+row.id).then((res)=>{
if(res.data.flag && res.data.data != null ){
this.dialogFormVisible4Edit = true;
this.formData = res.data.data;
}else{
this.$message.error("数据同步失败,自动刷新");
}
}).finally(()=>{
//2.重新加载数据
this.getAll();
});
},
//修改
handleEdit() {
axios.put("/books",this.formData).then((res)=>{
//判断当前操作是否成功
if(res.data.flag){
//1.关闭弹层
this.dialogFormVisible4Edit = false;
this.$message.success("修改成功");
}else{
this.$message.error("修改失败");
}
}).finally(()=>{
//2.重新加载数据
this.getAll();
});
比较详细,以为后来编辑其他项目打基础,做备份。
界面:
跳转页面:
删除数据:
新增数据:
查询数据:
基础操作完成。
页面比较简单,但技术很新,有巨大潜在价值,当然作为一个基础与备份的后台系统,足够了。
最后,若您也也需要此系统,关注公众号:计算机基础与编程
主页回复“基础项目”;