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依赖
 
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <scope>runtimescope>
        dependency>
        
        <dependency>
            <groupId>org.mybatis.spring.bootgroupId>
            <artifactId>mybatis-spring-boot-starterartifactId>
            <version>2.1.1version>
        dependency>
        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druid-spring-boot-starterartifactId>
            <version>1.1.21version>
        dependency>
        
        <dependency>
            <groupId>com.github.pagehelpergroupId>
            <artifactId>pagehelper-spring-boot-starterartifactId>
            <version>1.2.3version>
        dependency>
  1. 项目结构
    SpringBoot+Vue+Element-ui前后端分离(增删改查)(八)_第1张图片
  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


<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项目
效果图
SpringBoot+Vue+Element-ui前后端分离(增删改查)(八)_第2张图片
SpringBoot+Vue+Element-ui前后端分离(增删改查)(八)_第3张图片
SpringBoot+Vue+Element-ui前后端分离(增删改查)(八)_第4张图片
安装axiox(npm i axios)
在这里插入图片描述
安装element-ui
SpringBoot+Vue+Element-ui前后端分离(增删改查)(八)_第5张图片
在 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. 项目结构
    SpringBoot+Vue+Element-ui前后端分离(增删改查)(八)_第6张图片
  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>

数据库字段
SpringBoot+Vue+Element-ui前后端分离(增删改查)(八)_第7张图片

你可能感兴趣的:(SpringBoot)