SpringBoot + Vue 简单前后端分离项目的增删改查

SpringBoot 是提供一种快速整合的方式


前期准备

新建数据库

drop table if exists emp;

create table emp
(
    empno int primary key auto_increment,
    ename varchar(20),
    job   varchar(9),
    hiredate date,
    sal  double
);

新建项目

新建SpringBoot项目,这里是第三种,项目建好后查看 main/java文件夹下的Application

@SpringBootApplication:主启动类

相当于@Configuration配置类、@EnableAutoConfiguration开启自动配置、@CommponentScan 组件扫描(默认扫描的是主启动类所在包及子包)

在主启动类中还需要在类的上面加两个注解

@MapperScan("com.ssm.mapper") //mapper包的限定名
@EnableTransactionManagement  //开启事务管理

提示:以下是本篇文章正文内容,下面案例可供参考

config 配置包

MvcConfig 类

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

@Configuration
public class MvcConfig implements WebMvcConfigurer {
    
    
 
	 /**
     * 跨域访问设置
     */
    public void addCorsMappings(CorsRegistry registry) {
    
    
       registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods(new String[]{
    
    "GET", "POST", "PUT", "DELETE"})
                .allowedHeaders("*")
                .exposedHeaders("*");
    }
 
}

application.yml

application.properties重命名为:application.yml

server:
  port: 1234   # 配置内嵌Tomcat端口号
  servlet:      
    context-path: /ssm   # 配置应用名


# 配置数据库    
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver # mysql驱动程序类名 8-com.mysql.cj.jdbc.Driver 5-com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/ssm?characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    
# 配置日志输出级别    
logging:
  level:
    # 项目包名
    com.ssm: debug  

# 配置mybatis实体类的别名包
mybatis:
  type-aliases-package: com.ssm.po

后端业务开发

po 类

@Data:默认自动生成Getter、Setter、toString
@AllArgsConstructor:默认生成有参构造方法(需要有参的时候两个都加上)
项目中默认就有无参的
@NoArgsConstructor:默认生成无参构造方法

import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data  // 默认自动生成Getter、Setter、toString
// 需要有参的就加下面两个注解,因为默认就有无参的
@AllArgsConstructor // 默认生成有参构造方法
@NoArgsConstructor  // 默认生成无参构造方法
public class Emp {
    
    
	private Integer empno;
	private String ename;
	private String job;
	@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
	private Date hiredate;
	private Double sal;
	
}

mapper 接口

增加和修改用的参数是实体类,删除和 id 查询用的是 int 主键
查询所有数据用List
简单语句写注解里:

@Mapper
public interface EmpMapper {
    
    
	// 主键自增,这里不用写
	@Insert("insert into emp (ename,job,hiredate,sal) values(#{ename},#{job},#{hiredate},#{sal})")
	int insert(Emp emp);
	
	@Delete("delete from emp where empno=#{no}")
	int delete(int empno);
	
	@Update("update emp set ename=#{ename},job=#{job},hiredate=#{hiredate},sal=#{sal} where empno=#{empno}")
	int update(Emp emp);
	// 查询所有数据的时候,把所有属性都写出来
	@Select("select empno,ename,job,hiredate,sal from emp")
	List<Emp> queryAllEmps();
	
}

service 接口

public interface EmpService {
    
    
	
	String insert(Emp emp);
	String delete(int empno);
	String update(Emp emp);
	List<Emp> queryAllEmps();
}

service 实现类

@Service
public class EmpServiceImpl implements EmpService{
    
    
	// 添加依赖注入的注解
	@Autowired
	// 依赖关系,service依赖mapper
	private EmpMapper mapper;
	
	@Override
	public String insert(Emp emp) {
    
    
		// 添加未实现的方法
		return mapper.insert(emp)>0?"增加员工数据成功":"增加员工数据失败";
	}

	@Override    // int类型可以随意起名,这里是主键方便区分
	public String delete(int empno) {
    
    
		return mapper.delete(empno)>0?"删除员工数据成功":"删除员工数据失败";
	}

	@Override
	public String update(Emp emp) {
    
    
		return mapper.update(emp)>0?"修改员工数据成功":"修改员工数据失败";
	}

	@Override
	public List<Emp> queryAllEmps() {
    
    
		return mapper.queryAllEmps();
	}

}

controller 类

基于rest风格

@RequestBody注解作用:提示SpringMVC框架客户端发送的请求数据格式是JSON
@PathVariable("主键")表示获取请求路径中的主键参数,并将其绑定到方法的主键参数上。

@RestController
@RequestMapping("/emp")
public class EmpController {
    
    
	@Autowired
	// controller依赖service接口
	private EmpService service;
	
	@PostMapping
	// @RequestBody注解作用:提示SpringMVC框架客户端发送的请求数据格式是JSON
	public String add(@RequestBody Emp emp) {
    
    
		// 返回service处理的结果
		return service.insert(emp);
	}
	
	@DeleteMapping("/{empno}")
	public String delete(@PathVariable("empno")int empno) {
    
    
		return service.delete(empno);
	}
	
	@PutMapping
	public String update(@RequestBody Emp emp) {
    
    
		return service.update(emp);
	}
	
	@GetMapping
	public List<Emp> query(){
    
    
		return service.queryAllEmps();
	}
}

测试

在后端程序中右键主启动类启动 Spring Boot App

增加数据测试

POST请求
请添加图片描述
回到数据库可以看到增加了一条数据

删除数据测试

DELETE 方法,链接后面跟主键
在这里插入图片描述
回到数据库可以看到 2号数据被删除

修改数据测试

PUT 请求
Headers 里面的值不删,在Body里面加上要修改的主键,及对应要修改的数据
在这里插入图片描述

回到数据库可以看到 1号数据被修改

查新数据测试

GET请求
在这里插入图片描述

前端页面开发

vue新建项目后删掉无用代码

新建增加、修改、查询视图

接下来在 index.js 文件内配置路由

import Query from '@/views/Query'
import Add from '@/views/Add'
import Update from '@/views/Update'

const routes = [
  {
    
    
    path:'/',
    name:'query',
    component:Query
  },
  {
    
    
    path:'/add',
    name:'add',
    component:Add
  },
  {
    
    
    path:'/update',
    name:'update',
    component:Update
  }
]

查询页面

在查询视图中

看到按钮就加上@click=" "
数据的表格要加vfor指令和插值语法

<template>
  <div>
    <button @click="query">查询</button>
    <button @click="goAdd">增加</button>
    <table>
        <tr>
            <th>员工编号</th>
            <th>员工姓名</th>
            <th>员工岗位</th>
            <th>入职日期</th>
            <th>员工工资</th>
            <th>修改</th>
            <th>删除</th>
        </tr>
        <tr v-for="(item, index) in items" :key="index">
            <th>{
   
   { item.empno }}</th>
            <th>{
   
   { item.ename }}</th>
            <th>{
   
   { item.job }}</th>
            <th>{
   
   { item.hiredate }}</th>
            <th>{
   
   { item.sal }}</th>
            <th><button @click="goUpdate(index)">修改</button></th>
            <th><button @click="del(index)">删除</button></th>
        </tr>
    </table>
  </div>
</template>

接下来现配数据:vfor指令中的items

  data () {
    
    
    return {
    
    
        items:[]
    }
  },

接下来重点是方法,差所有数据,前后端要联系起来,导入 Ajax 的库axios

import axios from 'axios'

methods内配置查询方法:

    query(){
    
    
        axios.get('http://localhost:1234/ssm/emp')
        
    },

因为删除、增加、修改都要发请求,地址都是http://localhost:1234/ssm/emp,有点麻烦

接下来配置一个代理服务器,简化路径

在项目最后一个文件vue.config.js里面配置:

// 最后一行})前回车,前面代码后加逗号
devServer: {
    
    
     proxy:{
    
    
       '/api':{
    
    
         //target: 'http://localhost',
         //target: 'http://localhost:端口号/后端文件名/'
         target: 'http://localhost:1234/ssm/',
         ws: true,
         changeOrigin: true,
         pathRewrite: {
    
    
           '^/api': ''
         }
       }
     }
   }

以后再发请求这个路径就可以被/api替代

路径后面跟上.then(),里面加上箭头函数,里面写响应(resp),最后写赋值

所以最后查询视图的路径及代码:

    query(){
    
    
        axios.get('/api/emp')
        .then((resp)=> {
    
    
            this.items = resp.data
        })
    },

启动项目:点击查询
在这里插入图片描述

删除功能

在查询视图内

复制上面删除按钮中的方法,加在methods方法内:

直接发请求

// i代表数组下标
    del(i){
    
    
        axios.delete(`/api/emp/${
      
      this.items[i].empno}`)
        .then( (resp)=>{
    
    
            alert(resp.data)
            // 删完后查询一下
            this.query()
        })
    },

请添加图片描述

添加页面

首先在首页视图中加上添加的方法,以便跳转

不需要传参,只需要跳转的路径

    goAdd(){
    
    
        this.$router.push('/add')
    },

这时候可以跳转,但是大白屏

在添加视图内

<template>
  <div>
    员工姓名:<input type="text" v-model="emp.ename"> <br>
    员工岗位:<input type="text" v-model="emp.job"> <br>
    入职日期:<input type="date" v-model="emp.hiredate"> <br>
    员工工资:<input type="number" v-model="emp.sal"> <br>
    <button @click="add">提交</button>
  </div>
</template>

先导入axios

import axios from 'axios'

data数据中:

  data () {
    
    
    return {
    
    
        emp:{
    
    
            ename: '',
            job: '',
            hiredate: '',
            sal: ''
        }
    }
  },

最后添加methods方法

  methods: {
    
    
    add(){
    
    
    // 增加post请求,方法里面两个参,一个地址一个数据
        axios.post('/api/emp',this.emp)
        // 响应
        .then( (resp)=>{
    
    
        // 弹窗
            alert(resp.data)
        })
    }
  },

在查询页面点击添加:
在这里插入图片描述

修改页面

在查询视图内的methods方法内加上修改方法

会话传参方法:

    goUpdate(i){
    
    
    					//起个名字,数组数据用JSON格式格式化一下
        sessionStorage.setItem('emp',JSON.stringify(this.items[i]))
        // 跳转
        this.$router.push('/update')
    }

在修改视图内:

修改代码结构基本和增加一样,这里可以直接复制增加的代码,然后修改部分代码

修改的话需要指定编号,但是编号不能被修改(设置只读)

<input type="text" v-model="emp.empno" readonly> <br>

然后修改按钮的方法名

<button @click="update">修改</button>

修改的话要把之前会话的数据从钩子函数中取出来

    mounted () {
    
    
      // 按照名字取出数据
        let s = sessionStorage.getItem('emp')
      // 恢复成对象形式,再赋值给emp表
        this.emp = JSON.parse(s)
    }

methods方法里面的修改方法名(update)和请求类型需要改(put)

    methods: {
    
    
        update(){
    
    
          axios.put('/api/emp',this.emp)
          .then( (resp)=>{
    
    
              alert(resp.data)
          })
      }
    },

最后修改视图的完整代码:

<template>
    <div>
      <input type="text" v-model="emp.empno" readonly> <br>
      <input type="text" v-model="emp.ename"> <br>
      <input type="text" v-model="emp.job"> <br>
      <input type="date" v-model="emp.hiredate"> <br>
      <input type="number" v-model="emp.sal"> <br>
      <button @click="update">修改</button>
    </div>
  </template>
  
  <script>
  import axios from 'axios'
  export default {
    
    
    data () {
    
    
      return {
    
    
          emp:{
    
    
              ename: '',
              job: '',
              hiredate: '',
              sal: ''
          }
      }
    },
    methods: {
    
    
        update(){
    
    
          axios.put('/api/emp',this.emp)
          .then( (resp)=>{
    
    
              alert(resp.data)
          })
      }
    },
    components: {
    
    },
    computed: {
    
    },
    watch: {
    
    },
    mounted () {
    
    
      // 取出数据
        let s = sessionStorage.getItem('emp')
        this.emp = JSON.parse(s)
    }
  }
  </script>
<style scoped>
</style>

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/rej177/article/details/132174411