目录

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等环境下运行


1、项目简介

一个简单的图书管理系统,周期为5天的一个系统,一个可以作为的模板的系统。

2、适用人群

有一定Java+前端基础的学习者,想快速了解Spring Boot项目框架的学习者和开发者,想回忆起某一技术的开发与运维人员。

3、使用技术

前端:

Vue+Element-UI+axios

后端:

Spring Boot 2 + MybatisPlus + SpringMVC + Juint + Druid+Lombook

数据库:

MySql5.5+

测试:

Restful+Postman

4、功能简介

图书管理的查询、添加、修改、删除、异常处理与分页操作。

5、工具介绍

若您未使用过 Spring Boot 工程或不会创建 Spring Boot项目,请参考此篇文章,有详细介绍

《Spring Boot开发实践》之Spring Boot 入门_初尘屿风的博客-CSDN博客

Java框架入门——SpringBoot框架_初尘屿风的博客-CSDN博客

(1)mevan项目搭建

<build>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>            </plugin>        </plugins>    </build>

(2)Spring Boot项目搭建

<parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>2.5.4</version>    </parent>

(3)Java版本显示

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

(4)Lombook项目搭建

<!--lombok-->        <dependency>            <groupId>org.projectlombok</groupId>            <artifactId>lombok</artifactId>        </dependency>

(5)日志配置

spring.main.banner-mode=off

(6)端口设置(三种方式)

1、默认方式

server.port=80

2、.yml:推荐使用

server:
  port: 
 

3、.yaml

server:  port:

2与3是有一定的差别,2是主流;

注意事项:

  • 大小写敏感

  • 属性层级关系使用多行描述,每行结尾使用冒号结束

  • 使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用Tab键)

  • 属性值前面添加空格(属性名与属性值之间使用冒号+空格作为分隔)

  • 核心规则:数据前面要加空格与冒号隔开

(7)Junit项目搭建

@SpringBootTestclass Springboot07JunitApplicationTests {@Autowiredprivate BookService bookService;@Testpublic void testSave(){bookService.save();} }

(8)Mybatis项目搭建(IDEA系统自带)

<artifactId>springboot_05_mybatis</artifactId>    <version>0.0.1-SNAPSHOT</version>    <name>springboot_05_mybatis</name>    <description>Demo project for Spring Boot</description>    <properties>

(9)MybatisPlus项目搭建(手动配置)

<groupId>com.test</groupId>    <artifactId>springboot_06_mybatis_plus</artifactId>    <version>0.0.1-SNAPSHOT</version>    <name>springboot_06_mybatis_plus</name>    <description>Demo project for Spring Boot</description>    <properties>

(10)项目搭建

 <dependency>            <groupId>com.alibaba</groupId>            <artifactId>druid-spring-boot-starter</artifactId>            <version>1.2.6</version>        </dependency>

(11)Vue介绍

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。

(12)Element介绍

Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。

(13)Postman介绍

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.

(14)Axios 介绍

Axios 是一个基于 promise 的网络请求库,可以用于浏览器和 node.js。

(15)SpringMVC 介绍

Spring web MVC 框架提供了模型-视图-控制的体系结构和可以用来开发灵活、松散耦合的 web 应用程序的组件。MVC 模式导致了应用程序的不同方面(输入逻辑、业务逻辑和 UI 逻辑)的分离,同时提供了在这些元素之间的松散耦合。

(16)Springboot介绍

官网:

Spring | Home

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".

(17)……

等等

6、后端相关代码介绍

目录

(1)拦截器

 @Bean    public MybatisPlusInterceptor mybatisPlusInterceptor(){        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());        return interceptor;    }
//作为springmvc的异常处理器//@ControllerAdvice@RestControllerAdvicepublic class ProjectExceptionAdvice {    //拦截所有的异常信息    @ExceptionHandler(Exception.class)    public R doException(Exception ex){        //记录日志        //通知运维        //通知开发        ex.printStackTrace();        return new R("服务器故障,请稍后再试!");    }

(2)分页操作

@GetMapping("{currentPage}/{pageSize}")    public R getPage(@PathVariable int currentPage,@PathVariable int pageSize,Book book){//        System.out.println("参数==>"+book);        IPage<Book> page = bookService.getPage(currentPage, pageSize,book);        //如果当前页码值大于了总页码值,那么重新执行查询操作,使用最大页码值作为当前页码值        if( currentPage > page.getPages()){            page = bookService.getPage((int)page.getPages(), pageSize,book);        }        return new R(true, page);    }    @Testvoid testGetPage(){IPage page = new Page(1,5);bookDao.selectPage(page,null);}

@Override    public IPage<Book> getPage(int currentPage, int pageSize) {        IPage page = new Page(currentPage,pageSize);        bookDao.selectPage(page,null);        return page;    }    @Override    public IPage<Book> getPage(int currentPage, int pageSize, Book book) {        LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();        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;    }

(3)实体类开发

import lombok.Data;@Datapublic class Book {    private Integer id;    private String type;    private String name;    private String description;}

(4)交互功能

@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));    }

(5)数据层开发

<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.3</version></dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.6</version></dependency>

(6)数据库应用

spring:  datasource:    druid:      driver-class-name: com.mysql.cj.jdbc.Driver      url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC      username: root      password: 123mybatis-plus:  global-config:    db-config:      table-prefix: tbl_      id-type: auto  configuration:    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

(7)查询操作

@Testvoid testGetByCondition(){IPage page = new Page(1,10);LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();lqw.like(Book::getName,"Spring");bookDao.selectPage(page,lqw);}@Testvoid testGetByCondition(){QueryWrapper<Book> qw = new QueryWrapper<Book>();qw.like("name","Spring");bookDao.selectList(qw);}

支持动态拼写查询条件:

@Testvoid testGetByCondition(){String name = "Spring";IPage page = new Page(1,10);LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();lqw.like(Strings.isNotEmpty(name),Book::getName,"Spring");bookDao.selectPage(page,lqw);}

(8)业务层开发

public interface BookService {boolean save(Book book);boolean delete(Integer id);boolean update(Book book);Book getById(Integer id);List<Book> getAll();IPage<Book> getByPage(int currentPage,int pageSize);}@Servicepublic class BookServiceImpl implements BookService {@Autowiredprivate 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 {@Autowiredprivate IBookService bookService;@GetMappingpublic List<Book> getAll(){return bookService.list();} }

初始界面:

测试界面:

(10)前后端数据协议:

设计表现层返回结果的模型类,用于后端与前端进行数据格式统一,也称为前后端数据协议

import lombok.Data;@Datapublic 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;    }}

(11)异常处理

@RestControllerAdvicepublic 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();});},@PostMappingpublic R save(@RequestBody Book book) throws IOException {Boolean flag = bookService.insert(book);return new R(flag , flag ? "添加成功^_^" : "添加失败-_-!"); }

目的:国际化

7、前端相关代码介绍

目录:

(1)头部定义

<head>    <!-- 页面meta -->    <meta charset="utf-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <title>SpringBoot2案例</title>    <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">    <!-- 引入样式 -->    <link rel="stylesheet" href="../plugins/elementui/index.css">    <link rel="stylesheet" href="../plugins/font-awesome/css/font-awesome.min.css">    <link rel="stylesheet" href="../css/style.css"></head>

(2)盒子定义

 <div class="box">            <div class="filter-container">                <el-input placeholder="图书类别" v-model="pagination.type" style="width: 200px;" class="filter-item"></el-input>                <el-input placeholder="图书名称" v-model="pagination.name" style="width: 200px;" class="filter-item"></el-input>                <el-input placeholder="图书描述" v-model="pagination.description" style="width: 200px;" class="filter-item"></el-input>                <el-button @click="getAll()" class="dalfBut">查询</el-button>                <el-button type="primary" class="butT" @click="handleCreate()">新建</el-button>            </div>            <el-table size="small" current-row-key="id" :data="dataList" stripe highlight-current-row>                <el-table-column type="index" align="center" label="序号"></el-table-column>                <el-table-column prop="type" label="图书类别" align="center"></el-table-column>                <el-table-column prop="name" label="图书名称" align="center"></el-table-column>                <el-table-column prop="description" label="描述" align="center"></el-table-column>                <el-table-column label="操作" align="center">                    <template slot-scope="scope">                        <el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>                        <el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>                    </template>                </el-table-column>            </el-table>

(3)分页组件

<!--分页组件-->            <div class="pagination-container">                <el-pagination                        class="pagiantion"                        @current-change="handleCurrentChange"                        :current-page="pagination.currentPage"                        :page-size="pagination.pageSize"                        layout="total, prev, pager, next, jumper"                        :total="pagination.total">                </el-pagination>            </div>

(4)新增标签弹层

<!-- 新增标签弹层 -->            <div class="add-form">                <el-dialog title="新增图书" :visible.sync="dialogFormVisible">                    <el-form ref="dataAddForm" :model="formData" :rules="rules" label-position="right" label-width="100px">                        <el-row>                            <el-col :span="12">                                <el-form-item label="图书类别" prop="type">                                    <el-input v-model="formData.type"/>                                </el-form-item>                            </el-col>                            <el-col :span="12">                                <el-form-item label="图书名称" prop="name">                                    <el-input v-model="formData.name"/>                                </el-form-item>                            </el-col>                        </el-row>                        <el-row>                            <el-col :span="24">                                <el-form-item label="描述">                                    <el-input v-model="formData.description" type="textarea"></el-input>                                </el-form-item>                            </el-col>                        </el-row>                    </el-form>                    <div slot="footer" class="dialog-footer">                        <el-button @click="cancel()">取消</el-button>                        <el-button type="primary" @click="handleAdd()">确定</el-button>                    </div>                </el-dialog>            </div>

(5)编辑标签弹层

<!-- 编辑标签弹层 -->            <div class="add-form">                <el-dialog title="编辑检查项" :visible.sync="dialogFormVisible4Edit">                    <el-form ref="dataEditForm" :model="formData" :rules="rules" label-position="right" label-width="100px">                        <el-row>                            <el-col :span="12">                                <el-form-item label="图书类别" prop="type">                                    <el-input v-model="formData.type"/>                                </el-form-item>                            </el-col>                            <el-col :span="12">                                <el-form-item label="图书名称" prop="name">                                    <el-input v-model="formData.name"/>                                </el-form-item>                            </el-col>                        </el-row>                        <el-row>                            <el-col :span="24">                                <el-form-item label="描述">                                    <el-input v-model="formData.description" type="textarea"></el-input>                                </el-form-item>                            </el-col>                        </el-row>                    </el-form>                    <div slot="footer" class="dialog-footer">                        <el-button @click="cancel()">取消</el-button>                        <el-button type="primary" @click="handleEdit()">确定</el-button>                    </div>                </el-dialog>            </div>        </div>    </div></div></body>

(6)引入组件库

<!-- 引入组件库 --><script src="../js/vue.js"></script><script src="../plugins/elementui/index.js"></script><script type="text/javascript" src="../js/jquery.min.js"></script><script src="../js/axios-0.18.0.js"></script><script>    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;            //     });            // },

(7)分页查询

//分页查询            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);

(8)发送异步请求

      //发送异步请求                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;                });

(9)切换页码

//切换页码            handleCurrentChange(currentPage) {                //修改页码值为当前选中的页码值                this.pagination.currentPage = currentPage;                //执行查询                this.getAll();            },

(10)弹出添加窗口

            //弹出添加窗口            handleCreate() {                this.dialogFormVisible = true;                this.resetForm();            },           this.$message.success("修改成功");                    }else{                        this.$message.error("修改失败");                    }                }).finally(()=>{                    //2.重新加载数据                    this.getAll();                });

(11)重置表单

 //重置表单            resetForm() {                this.formData = {};            },

(12)添加

 //添加            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();                });            },

(13)取消

  //取消            cancel(){                this.dialogFormVisible = false;                this.dialogFormVisible4Edit = false;                this.$message.info("当前操作取消");            },

(14)删除

// 删除            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("取消操作");                });            },

(15)弹出编辑窗口

//弹出编辑窗口            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();                });            },

(16)修改

//修改            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();                });

比较详细,以为后来编辑其他项目打基础,做备份。

8、项目展示及相关测试

界面:

跳转页面:

删除数据:

新增数据:

​ 

查询数据:

9、项目打包,

可以在无IDEA等环境下运行

基础操作完成。

页面比较简单,但技术很新,有巨大潜在价值,当然作为一个基础与备份的后台系统,足够了。

若您发现了错误,还请不吝赐教,谢谢。

最后,若您也也需要此系统,关注公众号:计算机基础与编程

主页回复“基础项目”;

 

如果您觉得文章不错,可以点赞+收藏+转发

Logo

前往低代码交流专区

更多推荐