SpringBoot+Vue+Element-ui前后端分离(增删改查)(八)

本文主要是想通过后端 Spring Boot 技术和前端 Vue 技术来简单开发一个增删改查demo,该demo以简单、方便理解的方式来记录前后端结合使用的过程,方便正式开发复杂项目时能提前整体理解流程,资源链接链接:https://pan.baidu.com/s/1xQ3R-IoGRK7KxAZEgENhUg
提取码:vase
复制这段内容后打开百度网盘手机App,操作更方便哦
demo最终实现的效果如下图:
一,后台

  1. properties配置
server.port=8080
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/db01?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
#扫描xml
mybatis.mapper-locations= classpath:mapper/*.xml
#分页
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.pageSizeZero=true
pagehelper.params=countSql
  1. pom.xml依赖
 <!--web依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--mysql依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--mybatis依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>
        <!--druid连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.21</version>
        </dependency>
        <!--加入分页依赖-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.3</version>
        </dependency>
  1. 项目结构
    4
  2. 实体类
public class Dept {
    private Integer deptno;
    private String dname;
    private String loc;

    @Override
    public String toString() {
        return "Dept{" +
                "deptno=" + deptno +
                ", dname='" + dname + '\'' +
                ", loc='" + loc + '\'' +
                '}';
    }

    public Integer getDeptno() {
        return deptno;
    }

    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }

    public String getDname() {
        return dname;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }

    public String getLoc() {
        return loc;
    }

    public void setLoc(String loc) {
        this.loc = loc;
    }
}
  1. mapper接口
@Mapper
public interface DeptMapper {
    int addDept(Dept dept);
    int deleteById(Integer deptno);
    int updateDeptById(Dept dept);
    List<Dept> findAllDept(@Param("keywords") String keywords);
}
  1. service
public interface DeptService {
    int addDept(Dept dept);
    int deleteById(Integer id);
    int updateDeptById(Dept dept);
    List<Dept> findAllDept(String keywords);
}
  1. serviceimpl
@Service
public class DeptServiceImpl implements DeptService {
    @Autowired
    private DeptMapper deptMapper;
    @Override
    public int addDept(Dept dept) {
        return deptMapper.addDept(dept);
    }

    @Override
    public int deleteById(Integer id) {
        return deptMapper.deleteById(id);
    }

    @Override
    public int updateDeptById(Dept dept) {
        return deptMapper.updateDeptById(dept);
    }

    @Override
    public List<Dept> findAllDept(String keywords) {
        return deptMapper.findAllDept(keywords);
    }
}

  1. controller接口
@RestController
@RequestMapping("/dept")
public class DeptController {
    @Autowired
    private DeptService deptService;

    /**
     * 分页查询
     * @param page
     * @param size
     * @param keywords
     * @return
     */
    @GetMapping("/")
    public RespPageBean findAll(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer size, String keywords){
        PageHelper.startPage(page, size);
        List<Dept> list = deptService.findAllDept(keywords);
        PageInfo pageInfo = new PageInfo(list);
        RespPageBean bean = new RespPageBean();
        bean.setData(pageInfo.getList());
        bean.setTotal(pageInfo.getTotal());
        return bean;
    }

    /**
     * 删除
     * @param deptno
     * @return
     */
    @DeleteMapping("/{deptno}")
    public RespBean deleteDept(@PathVariable Integer deptno){

       if(deptService.deleteById(deptno)==1){
            return RespBean.DELETE_SUCCESS;//删除成功
       }
        return RespBean.DELETE_ERROR;//删除失败
    }

    /**
     * 添加
     * @param dept
     * @return
     */
    @PostMapping("/")
    public RespBean addDept(@RequestBody Dept dept){
        if(deptService.addDept(dept)==1){
            return RespBean.ADD_SUCCESS;//添加成功
        }
        return RespBean.ADD_ERROR;//添加失败
    }

    /**
     * 更新
     * @param dept
     * @return
     */
    @PutMapping("/")
    public RespBean updateDept(@RequestBody Dept dept){
         if(deptService.updateDeptById(dept)==1){
              return RespBean.UPDATE_SUCCESS;//添加成功
           }
        return RespBean.UPDATE_ERROR;//添加失败
    }
  1. 还有两个帮助类
public class RespBean {
    private Integer status;
    private String msg;
    private Object obj;

    public RespBean(Integer status, String msg) {
        this.status = status;
        this.msg = msg;
    }

    public static final RespBean DELETE_SUCCESS = new RespBean(200,"删除成功");
    public static final RespBean DELETE_ERROR = new RespBean(-1,"删除失败");

    public static final RespBean ADD_SUCCESS = new RespBean(200,"添加成功");
    public static final RespBean ADD_ERROR = new RespBean(-1,"添加失败");

    public static final RespBean UPDATE_SUCCESS = new RespBean(200,"更新成功");
    public static final RespBean UPDATE_ERROR = new RespBean(-1,"更新失败");

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String getMsg() {
        return msg;
    }

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

    public Object getObj() {
        return obj;
    }

    public void setObj(Object obj) {
        this.obj = obj;
    }

    private RespBean(Integer status, String msg, Object obj) {
        this.status = status;
        this.msg = msg;
        this.obj = obj;
    }

    private RespBean() {
    }
}

public class RespPageBean {
    private Long total;
    private List<?> data;

    public Long getTotal() {
        return total;
    }

    public void setTotal(Long total) {
        this.total = total;
    }

    public List<?> getData() {
        return data;
    }

    public void setData(List<?> data) {
        this.data = data;
    }
}

  1. mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.song.mapper.DeptMapper">

<insert id="addDept" parameterType="com.song.entity.Dept">
    insert into dept(dname,loc)values (#{dname},#{loc})
</insert>

<delete id="deleteById">
    delete from dept where deptno=#{deptno}
</delete>

<update id="updateDeptById" parameterType="com.song.entity.Dept">
    update dept set dname=#{dname},loc=#{loc} where deptno=#{deptno}
</update>

<select id="findAllDept" resultType="com.song.entity.Dept" >
    select*from dept where 1=1
    <if test="keywords!=null">
        and dname like concat('%',#{keywords},'%')
    </if>
</select>
</mapper>

二 前端,首先构建vue项目
效果图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
安装axiox(npm i axios)
在这里插入图片描述
安装element-ui
在这里插入图片描述
在 main.js 中写入以下内容:



import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';

Vue.use(ElementUI);

new Vue({
  el: '#app',
  render: h => h(App)
});
  1. 项目结构
    在这里插入图片描述
  2. 添加vue.config配置跨域代理
//跨域代理
let proxyObj={};

proxyObj['/']={
    ws: false, //webstock
    target:'http://localhost:8080',//代理对象
    changeOrigin: true,
    pathRewrite: {
        '^/': ''
    }
}
//vue项目启动端口
module.exports={
    devServer:{
        host: 'localhost',
        port: 8085,
        proxy: proxyObj
    }
}

3.添加api.js封装 get,put,post,delete请求

import axios from 'axios'
import {Message} from 'element-ui';

//结果拦截
axios.interceptors.response.use(success => {
    //data.msg 是后端RespBean中响应的信息
    if (success.status && success.status == -1 && success.data.status == 500) {
        Message.error({message: success.data.msg})
        return;
    }
    //data.msg 是后端RespBean中响应的信息
    if (success.data.msg) {
        Message.success({message: success.data.msg})
    }
    return success.data;
}, error => {
        //data.msg 是后端RespBean中响应的信息
        if (error.response.data.msg) {
            Message.error({message: error.response.data.msg})
        } else {
            Message.error({message: '未知错误!'})
        }
    return;
})
/**
 * post请求
 * @param url  请求地址
 * @param params 请求参数
 * @returns {AxiosPromise}
 */
export const postRequest=(url,params)=>{
    return axios({
        method:'post',
        url:`${url}`,
        data:params
    })
}
/**
 *  get请求
 * @param url  请求地址
 * @param params  请求参数
 * @returns {AxiosPromise}
 */
export const getRequest=(url,params)=>{
    return axios({
        method:'get',
        url:`${url}`,
        data:params
    })
}
/**
 * put请求
 * @param url  请求地址
 * @param params  请求参数
 * @returns {AxiosPromise}
 */
export const putRequest=(url,params)=>{
    return axios({
        method:'put',
        url:`${url}`,
        data:params
    })
}
/**
 * delete请求
 * @param url  请求地址
 * @param params  请求参数
 * @returns {AxiosPromise}
 */
export const deleteRequest=(url,params)=>{
    return axios({
        method:'delete',
        url:`${url}`,
        data:params
    })
}

  1. 路由
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  }
]

const router = new VueRouter({
  routes
})

export default router
  1. 编写页面
<template>
  <div class="home">
      <div>
          <el-input placeholder="请输入部门进行搜索,可以直接回车搜索..."
                    @clear="initAllDept"
                    prefix-icon="el-icon-search"
                    style="width: 350px;margin-right: 10px"
                    clearable
                    :clear="initAllDept"
                    v-model="keywords"
                    @keydown.enter.native="initAllDept"
          >
          </el-input>
          <el-button icon="el-icon-search" size="small" type="primary" @click="initAllDept" >
              搜索
          </el-button>
          <div style="display: flex;justify-content: space-between">
              <el-button type="primary" icon="el-icon-plus" size="small" @click="addDept">添加部门</el-button>
          </div>
      </div>
      <!--表格开始-->
      <div style="margin-top: 8px">
      <el-table
              :data="depts"
              border
              style="width: 100%">
          <el-table-column
                  prop="deptno"
                  label="编号"
                  width="180">
          </el-table-column>
          <el-table-column
                  prop="dname"
                  label="部门名称"
                  width="180">
          </el-table-column>
          <el-table-column
                  prop="loc"
                  label="地址">
          </el-table-column>
          <el-table-column label="操作">
              <template slot-scope="scope">
                  <el-button size="small" @click="updateDept(scope.row)">编辑</el-button>
                  <el-button size="small" type="danger" @click="deleteDept(scope.row)">删除</el-button>
              </template>
          </el-table-column>
      </el-table>
          <div style="display:flex;justify-content:flex-end ">
              <el-pagination
                      background
                      layout="sizes, prev, pager, next, jumper, ->, total, slot"
                      @current-change="currentChange"
                      @size-change="sizeChange"
                      :total="total">
              </el-pagination>
          </div>
      </div>
      <!--表格结束-->
      <!--弹出层开始-->
      <el-dialog
              :title="dialogTitle"
              :visible.sync="dialogVisible"
              width="50%">
          <el-form ref="form" :model="dept" label-width="80px">
              <el-form-item label="部门名称">
                  <el-input v-model="dept.dname"></el-input>
              </el-form-item>
              <el-form-item label="部门地址">
                  <el-input v-model="dept.loc"></el-input>
              </el-form-item>
              <el-form-item>
                  <el-button type="primary" @click="onSubmit">提交</el-button>
              </el-form-item>
          </el-form>
      </el-dialog>
      <!--弹出层结束-->
  </div>


</template>

<script>
// 导入封装的请求
import {getRequest} from "../uitls/api";
import {postRequest} from "../uitls/api";
import {putRequest} from "../uitls/api";
import {deleteRequest} from "../uitls/api";

export default {
  name: 'Home',
    data() {
        return {
            keywords:'',
            depts:[],//显示数据
            total:0,
            dialogTitle:"添加",
            dialogVisible:false,
            size:10,//分页每页10条数据
            page:1,//从第一页开始
            dept:{
                dname:'',
                loc:''
             }
        }
    },
    methods:{
       //分页
        currentChange(currentChange){
            this.page=currentChange
            this.initAllDept()
        },
        sizeChange(sizeChange){
            this.size=sizeChange
            this.initAllDept()
        },
        /**
         * /dept  请求地址
         */
        initAllDept(){
            //调用get请求
          getRequest("/dept/?keywords="+this.keywords+"&page="+this.page+"&size="+this.size).then(res=>{
              if(res){
                  this.depts=res.data
                  this.total=res.total
              }
          })
      },
        onSubmit(){
          if(this.dept.deptno){//this.dept.deptno有值就是修改,否则就是删除

              //修改
              //调用put请求
              putRequest("/dept/",this.dept).then(res=>{
                  if(res){
                      this. dialogVisible=false
                      //修改成功刷新数据
                      this.initAllDept()
                      //清空弹出层数据
                      this.dept.dname='';
                      this.dept.loc='';
                  }
              })
          }else{
              //添加
              //调用post请求
              postRequest("/dept/",this.dept).then(res=>{
                  if(res){
                      this. dialogVisible=false
                      //添加成功刷新数据
                      this.initAllDept()
                      //清空弹出层数据
                      this.dept.dname='';
                      this.dept.loc='';
                  }
              })
          }
        },
        addDept(){
            //打开弹出层
            this.dialogVisible=true
            //改变弹出成title
            this.dialogTitle="添加"
            //清空弹出层数据
            this.dept.dname='';
            this.dept.loc='';
        },
        updateDept(data){
            //填充数据  数据回显
            this.dept=data
            //打开弹出层
            this.dialogVisible=true
            //改变弹出成title
            this.dialogTitle="修改"
        },
        deleteDept(data){
            this.$confirm('此操作将永久删除【' + data.dname + '】, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                //调用delete请求
                deleteRequest("/dept/"+data.deptno).then(res=>{
                    if(res){
                        this.initAllDept()
                    }
                })
            }).catch(() => {
                this.$message({
                    type: 'info',
                    message: '已取消删除'
                });
            });
        }
    },
    //初始化数据
    mounted(){
      this.initAllDept();
    }

}
</script>
<style>
    .home{
        width: 800px;
        margin: 20px auto;
    }
</style>

数据库字段
在这里插入图片描述

  • 23
    点赞
  • 106
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值