后端工作部分

2021/10/7 23:15:58

本文主要是介绍后端工作部分,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

前言

这一章就是在上一章提到的的简易后台管理系统的后端部分了,学习!冲冲冲!

创建SpringBoot工程

创建一个Module:
在这里插入图片描述
选择Spring initializr在这里插入图片描述
配置好这些东西,点击next:
在这里插入图片描述
选择我们需要的jar包依赖:
在这里插入图片描述
给这个Module取个名字,我们就叫springboot好了,点击finish:
在这里插入图片描述
可以看到,此时已经创建完了springboot项目:
在这里插入图片描述
准备一下数据库(其中id为主键自增):
在这里插入图片描述

第一件事情需要做的就是我们的前端Vue默认的端口是8080,后端springboot默认的也是8080,所以我们需要改一下后端的端口号在application.yml中:
在这里插入图片描述
在主程序中启动运行springboot项目,访问9090端口可以看到:
在这里插入图片描述
说明正常。
然后我们在程序包下创建一个common类,这个包作为我们常用的配置类;对了,还要用到mybatis-plus,引入一下mp的依赖:

		<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>

然后在common包下写上我们的第一个分页配置的类:MybatisPlusConfig
在这里插入图片描述

然后在这个包下再写一个Result的配置类,这个类的作用就是返回给前台数据的一个包装类,因为后台返回给前台的数据一般都是json格式,json里面会包含这么几个数据,一个是code,code告诉前台这次返回的数据呢是成功还是失败,如果失败呢code就不会是0,因为我们定义的0是成功,非0则是失败;还有一个就是msg,这个就是告知前台每个码对应的成功或者失败的信息,data则就是拿来包装各种类型的信息。

package com.why.demo.common;

public class Result<T> {
    private String code;
    private String msg;
    private T data;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Result(){

    }

    public Result(T data) {
        this.data = data;
    }

    public static Result success(){
        Result result = new Result<>();
        result.setCode("0");
        result.setMsg("成功");
        return result;
    }

    public static <T> Result<T> success(T data){
        Result<T> result = new Result<>(data);
        result.setCode("0");
        result.setMsg("成功");
        return result;
    }

    public static Result error(String code,String msg){
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }
}

然后我们需要在MybatisPlusConfig这个配置类中加上包扫描,专门扫描另一个包(mapper,同样创建在demo包下)下的东西:
在这里插入图片描述

创建一个web层的controller包,位于demo包下,并写上一个UserController的控制类:
在这里插入图片描述
这个时候因为新增的用户数据是从前台通过json字符串格式传过来的,所以必然要先转化为一个实体才能封装到我们后台的数据库当中,所以我们还需要创建一个实体包entity,在包中写上User对应数据库中的数据表的字段:
在这里插入图片描述
现在我们可以返回去写我们的controller层的东西了:
在这里插入图片描述

现在我们要做的就是将上传过来的数据插入数据库了,依然使用Mp的一些语法操作,先定义一个UserMapper接口继承BaseMapper:
在这里插入图片描述
然后我们就可以使用Mp为我们准备的CRUD的操作了:
在这里插入图片描述
现在后台的一个接口就已经写好了,我们接下来就去前台进行相应的配置。因为前台的Home.vue中还有很多杂乱的数据,所以我们先整理一下,让其变成我们需要的样子:

<template>
  <!--padding设置一点内边距-->
  <div style="padding: 10px">
    <!--功能区域-->
    <div style="margin: 10px 0">
      <el-button type="primary">新增</el-button>
      <el-button type="primary">导入</el-button>
      <el-button type="primary">导出</el-button>
    </div>

    <!--搜索区域-->
    <div style="margin: 10px 0">
      <el-input v-model="search" placeholder="请输入关键字" style="width: 20%"/>
      <el-button type="primary" style="margin-left: 5px">搜索</el-button>
    </div>


    <!--后面的width可以不写,浏览器会自适应
    stripe是斑马纹效果-->
    <el-table :data="tableData" border stripe style="width: 100%">
      <!--sortable让日期排序-->
      <el-table-column prop="id" label="ID" sortable/>
      <el-table-column prop="username" label="用户名"/>
      <el-table-column prop="nickName" label="昵称" />
      <el-table-column prop="age" label="年龄"/>
      <el-table-column prop="sex" label="性别"/>
      <el-table-column prop="address" label="地址"/>

      <el-table-column fixed="right" label="操作">
        <template #default="scope">
          <el-button size="mini" @click="handleEdit(scope.$index,scope.row)">编辑</el-button>

          <!--弹出消息确认框-->
          <el-popconfirm
                  confirm-button-text="是的,没错"
                  cancel-button-text="妈的,我再想想"
                  icon="el-icon-info"
                  icon-color="red"
                  title="确定删除吗?">
            <template #reference>
              <el-button size="mini" type="danger" @click="handleDelete(scope.$index,scope.row)">删除</el-button>
            </template>
          </el-popconfirm>
      </template>
    </el-table-column>
    </el-table>

    <!--分页功能区域-->
    <div style="margin: 10px 0">
      <el-pagination
              v-model:currentPage="currentPage4"
              :page-sizes="[5,10,20]"
              :page-size="10"
              layout="total, sizes, prev, pager, next, jumper"
              :total="total"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange">
      </el-pagination>
    </div>
  </div>
</template>

<script>


export default {
  name: 'Home',
  components: {

  },
    data() {
        return {
            search: '',
            //当前页
            currentPage4: 1,
            total: 10,
            tableData: [

            ],
        }
    },
    methods: {
        handleEdit(){

        },
        handleDelete(){

        },
        handleSizeChange(){
        //    改变页码时触发函数

        },
        handleCurrentChange(){
        //  当前页改变时触发代码
        }
    }
}
</script>

此时访问:
在这里插入图片描述
现在整理完之后,我们去写刚刚在后台写的用户插入接口对应的前台需要执行的操作。首先为“新增”按钮绑定事件add:

<el-button type="primary" @click="add">新增</el-button>

然后在下面的方法区写上add:
在这里插入图片描述
新增时我们应该需要有一个弹窗,新增的操作就放在这个弹窗里面,也就是录入数据,依旧是老方法去copy样式,然后放进来就行了。调试这个的过程也很繁杂,所以我直接贴出源码了,反正调到最后自己满意了的就行:

<template>
  <!--padding设置一点内边距-->
  <div style="padding: 10px">
    <!--功能区域-->
    <div style="margin: 10px 0">
      <el-button type="primary" @click="add">新增</el-button>
      <el-button type="primary">导入</el-button>
      <el-button type="primary">导出</el-button>
    </div>

    <!--搜索区域-->
    <div style="margin: 10px 0">
      <el-input v-model="search" placeholder="请输入关键字" style="width: 20%"/>
      <el-button type="primary" style="margin-left: 5px">搜索</el-button>
    </div>


    <!--后面的width可以不写,浏览器会自适应
    stripe是斑马纹效果-->
    <el-table :data="tableData" border stripe style="width: 100%">
      <!--sortable让日期排序-->
      <el-table-column prop="id" label="ID" sortable/>
      <el-table-column prop="username" label="用户名"/>
      <el-table-column prop="nickName" label="昵称" />
      <el-table-column prop="age" label="年龄"/>
      <el-table-column prop="sex" label="性别"/>
      <el-table-column prop="address" label="地址"/>

      <el-table-column fixed="right" label="操作">
        <template #default="scope">
          <el-button size="mini" @click="handleEdit(scope.$index,scope.row)">编辑</el-button>

          <!--弹出消息确认框-->
          <el-popconfirm
                  confirm-button-text="是的,没错"
                  cancel-button-text="妈的,我再想想"
                  icon="el-icon-info"
                  icon-color="red"
                  title="确定删除吗?">
            <template #reference>
              <el-button size="mini" type="danger" @click="handleDelete(scope.$index,scope.row)">删除</el-button>
            </template>
          </el-popconfirm>
      </template>
    </el-table-column>
    </el-table>

    <!--分页功能区域-->
    <div style="margin: 10px 0">
      <el-pagination
              v-model:currentPage="currentPage4"
              :page-sizes="[5,10,20]"
              :page-size="10"
              layout="total, sizes, prev, pager, next, jumper"
              :total="total"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange">
      </el-pagination>
    </div>

    <!--弹窗输入用户信息-->
    <el-button type="text" @click="dialogVisible = true">click to open the Dialog</el-button>

    <el-dialog v-model="dialogVisible" title="提示" width="30%">
      <!--定义表单在这个弹出框内以收集新增的用户信息-->
      <el-form :model="form" label="用户名">
        <el-form-item label="用户名">
          <el-input v-model="form.username" style="width: 80%"></el-input>
        </el-form-item>
        <el-form-item label="昵称">
          <el-input v-model="form.nickName" style="width: 80%"></el-input>
        </el-form-item>
        <el-form-item label="年龄">
          <el-input v-model="form.age" style="width: 80%"></el-input>
        </el-form-item>
        <el-form-item label="性别">
          <el-radio v-model="form.sex" labei="男">男</el-radio>
          <el-radio v-model="form.sex" labei="女">女</el-radio>
        </el-form-item>
        <el-form-item label="地址">
          <el-input v-model="form.address" style="width: 80%"></el-input>
        </el-form-item>

      </el-form>
      <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="save">确 定</el-button>
      </span>
      </template>
    </el-dialog>
  </div>
</template>

<script>


export default {
  name: 'Home',
  components: {

  },
    data() {
        return {
            form: {},
            dialogVisible: false,
            search: '',
            //当前页
            currentPage4: 1,
            total: 10,
            tableData: [

            ],
        }
    },
    methods: {
        add(){
          this.dialogVisible = true;
          //清空表单域
          this.form = {};
        },
        save(){
          //这里我们就需要将保存起来的数据传入到后台中,运用Axios
        },
        handleEdit(){

        },
        handleDelete(){

        },
        handleSizeChange(){
        //    改变页码时触发函数

        },
        handleCurrentChange(){
        //  当前页改变时触发代码
        }
    }
}
</script>

现在就涉及到了前后端交互了,是一个重点,也就是上面代码中的save方法内部应该有与后端交互的功能,接下来就是实现这个事情。
第一步我们在Vue项目下新建一个文件夹叫utils,一个工具类的文件夹,在里面写上一个文件夹叫request.js,这个js文件就是我们用来封装处理前后端交互请求的文件:
在这里插入图片描述

交互功能的实现我们一般情况下使用Axios,但是在使用这个之前我们需要先安装一个Axios组件,打开控制器端,输入命令安装Axios:
在这里插入图片描述

等待安装完后,我们就可以在request.js文件中写代码了,内容如下一般都是固定的变化不大:

import axios from 'axios'

const request = axios.create({
    timeout: 5000
})

// request 拦截器
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {
    config.headers['Content-Type'] = 'application/json;charset=utf-8';
  
 // config.headers['token'] = user.token;  // 设置请求头
    return config
}, error => {
    return Promise.reject(error)
});

// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
    response => {
        let res = response.data;
        // 如果是返回的文件
        if (response.config.responseType === 'blob') {
            return res
        }
        // 兼容服务端返回的字符串数据
        if (typeof res === 'string') {
            res = res ? JSON.parse(res) : res
        }
        return res;
    },
    error => {
        console.log('err' + error) // for debug
        return Promise.reject(error)
    }
)


export default request


然后我们现在可以去写用户数据保存下来的逻辑了,在save方法中:

 save(){
          //这里我们就需要将保存起来的数据传入到后台中,运用Axios
            request.post("http://localhost:9090/user",this.form).then(res =>{
                console.log(res)
            })
        },

但是直接访问的话,会报跨域错误:
在这里插入图片描述
而Vue已经给我们提供好了关于跨域错误的解决方案,我们要做的就是创建一个vue.config.js的配置文件就可以了。
这个文件我们要创建在Vue项目的文件夹下,和src文件夹同级才行。
在这里插入图片描述
这段代码也是固定死的,直接copy拿来用就好了。

// 跨域配置
module.exports = {
    devServer: {                //记住,别写错了devServer//设置本地默认端口  选填
        port: 9876,
        proxy: {                 //设置代理,必须填
            '/api': {              //设置拦截器  拦截器格式   斜杠+拦截器名字,名字可以自己定
                target: 'http://localhost:9999',     //代理的目标地址
                changeOrigin: true,              //是否设置同源,输入是的
                pathRewrite: {                   //路径重写
                    '/api': ''                     //选择忽略拦截器里面的单词
                }
            }
        }
    }
}

注意上面的代理地址要改成自己后端程序设置的端口,比如我们这里的是9090,那么上面的端口9999就应该改成9090,同理原来的save方法中前面的那一段localhost就不再需要了,改变成/api:
在这里插入图片描述
因为新增了vue.config.js文件,所以需要重新启动,并且重启之后我们也不能通过访问8080端口来进入页面了,需要通过上面设置的本地默认端口9876,记得同时springboot项目也要启动,这样两个进程之间才可以进行通信,否则就报错(一开始我还为了这个找了好久bug),访问之后可以看到页面。然后点击新增按钮,输入用户信息:
在这里插入图片描述

可以看到数据库中已经出现了被插入的数据:
在这里插入图片描述
至此我们就已经完成阶段性胜利啦!由于篇幅过长,剩下的将在下一章节进行展示。



这篇关于后端工作部分的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程