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

news2024/11/24 10:04:31

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

文章目录

  • 前期准备
    • 新建数据库
    • 新建项目
    • config 配置包
    • application.yml
  • 后端业务开发
    • po 类
    • mapper 接口
    • service 接口
    • service 实现类
    • controller 类
  • 测试
    • 增加数据测试
    • 删除数据测试
    • 修改数据测试
    • 查新数据测试
  • 前端页面开发
    • 查询页面
    • 删除功能
    • 添加页面
    • 修改页面


前期准备

新建数据库

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 类

@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.neuedu.ssm: debug  

# 配置mybatis实体类的别名包
mybatis:
  type-aliases-package: com.neuedu.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>

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/857258.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年国内低代码平台盘点:TOP 10活跃领军者,助力企业智能应用快速构建

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

实战实例 | 郑航无人驾驶航空器系统工程专业综合实验平台建设项目

郑州航空工业管理学院 无人驾驶航空器系统工程专业综合实验平台建设项目 关键词&#xff1a;飞控开发、仿真训练、组装调试、无人机集群 解决方案&#xff1a;多智能体协同创新实验室解决方案 | 项目背景 无人机行业是当前发展迅速、技术综合性强和应用前景好的朝阳行业。基…

CCLINK IE FIELD BASIC转MODBUS-TCP网关cclink与以太网的区别

协议的不同&#xff0c;数据读取困难&#xff0c;这是很多生产管理系统的难题。但是现在&#xff0c;捷米JM-CCLKIE-TCP通讯网关&#xff0c;让这个问题变得非常简单。这款通讯网关可以将各种MODBUS-TCP设备接入到CCLINK IE FIELD BASIC网络中&#xff0c;连接到MODBUS-TCP总线…

echo用法、linxu课堂练习题、作业题

一、课堂练习 练习一&#xff1a; 4、普通用户修改密码&#xff1a; root修改密码&#xff1a; 5、修改主机名&#xff1a;hostnamectl hostname 主机名 查看&#xff1a;hostnamectl或者cat etc/hostname 练习二&#xff1a; 1、 mkdir /root/html touch /root/html/index.…

基于摄影测量的数字孪生建设

在这篇博文中&#xff0c;我们将了解如何使用无人机拍摄的照片在数字孪生中创建现实世界环境的 3D 模型。 数字孪生是物理系统的虚拟表示&#xff0c;定期更新数据以模仿其所表示的资产的结构、状态和行为。 数字孪生可以通过在单一管理平台中连接多个数据源并提供可行的见解来…

十一、结合数字孪生与时间技术进行多维分析设计与实施

大数据可视化中心以主题为分析对象,选择业务分类下的某个主题,可以在数据面板中展示其二维图表,在地图中标记其空间分布,并叠加其相应的二维或三维图层。 1、界面设计 其主界面设计详上图,各部分功能介绍如下: 1.1、主题与图层面板,从上到下,从左到右分别是: ①折…

Linux--core dump打开的情况下,运行下面的代码,会发生什么?

代码&#xff1a; #include <iostream> #include <signal.h> #include <unistd.h>using namespace std;void catchSig(int signum) {cout<< "进程捕捉到了一个信号&#xff0c;正在处理中&#xff1a; "<< signum << " p…

基于Spring Boot的招聘网站的设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的招聘网站的设计与实现&#xff08;Javaspring bootMySQL&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;Java springboot框…

Linux 进程间通信, 管道

文章目录 前言一、常见的进程间通信方式二、如何实现管道通信三、示例代码解析四、管道的读写行为总结 前言 在多进程编程中&#xff0c;进程间通信&#xff08;Inter-Process Communication&#xff0c;IPC&#xff09;是一种重要的技术手段&#xff0c;它使得不同进程可以安…

函数的声明和定义

1、函数声明 //告诉编译器有一个函数叫什么&#xff0c;参数是什么&#xff0c;返回类型是什么。但是具体是不是存在&#xff0c;函数声明决定不了。 //函数的声明一般出现在函数的使用之前。要满足先声明后使用。 //函数的声明一般要放在头文件中的。 2、函数的定义 //函数…

Linux(进程间通信详解)

进程间通信&#xff0c;顾名思义&#xff0c;就是进程与进程之间互通信交流&#xff0c;OS保证了各进程之间相互独立&#xff0c;但这不意味着进程与进程之间就互相隔离开&#xff0c;在不少的情况下&#xff0c;进程之间需要相互配合共同完成某项6任务&#xff0c;这就要求各进…

8月9日算法刷题【6道题】

8月9日算法刷题 一、排序1. 成绩排序&#xff08;清华大学考研机试题&#xff09;考点&#xff1a;结构体排序在结构体中定义排序使用比较器定义排序 注意问题&#xff1a;需要处理 值相等时 先后顺序 2. 成绩排序2( 清华大学考研机试题 )1. 从尾到头打印链表本题考点栈 2. 在O…

hgdbdevelop弹窗无法使用

瀚高数据库 目录 环境 文档用途 详细信息 环境 系统平台&#xff1a;Microsoft Windows (64-bit) 10 版本&#xff1a;4.5 文档用途 解决双击exe程序出现弹窗&#xff0c;点击Disable Modules and Continue没反应 详细信息 1.打开管理工具exe程序&#xff0c;出现弹窗如下图&…

【运维小能手】交换机二层环路问题如何处理

1 网络业务故障&#xff0c;如何确认存在环路&#xff1f; 网络业务故障后&#xff0c;如发生二层环路&#xff0c;通常会存端口流量数据风暴和反复大量的MAC漂移现象。因此&#xff0c;在骨干链路所在的节点&#xff0c;通过如下三步操作&#xff1a; 图1&#xff1a;环…

向量检索在大模型应用场景的技术和实践

一、向量检索应用简介 向量是多维数学空间里的一个点&#xff0c;在各维度上的坐标的一串数字。这个点就是来源于真实世界的物体进行数字化之后在数学空间的投影。那么不同点之间有一个数学关系&#xff0c;就是距离&#xff0c;距离远近就代表两个物体的相似程度。 非结构化数…

Semantic and Syntactic Enhanced Aspect Sentiment Triplet Extraction

创新点 图-序列双重表示: 通过将句子中的语义和句法关系表示为图&#xff0c;并使用图神经网络&#xff08;GNNs&#xff09;进行编码&#xff0c;同时保留原始句子的顺序信息&#xff0c;S3E2能够更精确地捕捉三元组元素之间的复杂关系。许多传统方法可能只依赖于线性或浅层表…

分支和循环语句(1)(C语言)

目录 什么是语句&#xff1f; 分支语句&#xff08;选择结构&#xff09; if语句 悬空else if书写形式的对比 switch语句 在switch语句中的 break default子句 循环语句 while循环 while语句中的break和continue for循环 语法 break和continue在for循环中 for语句和…

vue3 vite gzip

1、首先前端项目里安装 vite-plugin-compression 插件 yarn add vite-plugin-compression 2、在 vite.config.js 中 import vue from vitejs/plugin-vue import { defineConfig } from vite import compressPlugin from vite-plugin-compressionexport default defineConf…

【TI毫米波雷达笔记】sdk传参时的type避坑

【TI毫米波雷达笔记】sdk传参时的type避坑 这个函数要传一个结构体进去 然后结构体里面有个adcoutcfg结构体变量 adcoutcfg结构体里面共有三个变量 一个adcbitformat结构体 另外两保留 点开adcbitformat结构体发现是个32位段 一共四级结构体 那么请问 为什么adcoutcfg变量不直…

管理类联考——逻辑——论证逻辑——汇总篇——真题和典例——支持

支持 没有特点的 199-2017-1-30——支持论点 离家300米的学校不能上&#xff0c;却被安排到2千米外的学校就读&#xff0c;某市一位适龄儿童在上小学时就遭遇了所在区教育局这样的安排&#xff0c;而这一安排是区教育局根据儿童户籍所在施教区做出的。根据该市教育局规定的“…