SpringBoot 前后台交互 -- CRUD
下面几个文章呢,带大家小小的实战一下,通过SpringBoot整合SSM实现怎删改查,异常处理以及使用SpringMvc拦截器完成业务,话不多说,咱直接开始~
首先再带大家实现一下SSM整合,步骤如下:
1. SSM整合
1.1创建工程项目
这里我使用的是Maven原生构建项目
1.2 导依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.ityang</groupId><artifactId>ssm2</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><!-- Spring Boot 父项目依赖,提供默认配置和管理Spring Boot相关依赖的版本 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.4</version><relativePath/> <!-- 不使用本地路径,直接从Maven仓库查找父POM --></parent><!-- 依赖--><dependencies><!-- web依赖,内置tomcat--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!-- springboot 整合jdbc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- mybatis --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.7</version></dependency><!-- druid --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-3-starter</artifactId><version>1.2.23</version></dependency><!-- junit测试 +springboot --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><!-- 指定版本号 --><version>1.18.24</version><scope>provided</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency></dependencies>
</project>
1.3 yml配置文件配置
server:port: 8080
spring:datasource:username: rootpassword: 1234url: jdbc:mysql:///db1type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driver
1.4 功能业务
- 数据库
- Emps实体类
package com.it.pojo;import lombok.Data;@Data
public class Emps {private int id;private String username;private String password;private String addr;private int age;private String phone;}
- EmpsMapper接口层
package com.it.mapper;import com.it.pojo.Emps;
import org.apache.ibatis.annotations.*;import java.util.List;@Mapper
public interface EmpsMapper {
// 查询所有@Select("select * from emps")List<Emps> findAll();
// 根据id查询@Select("select * from emps where id=#{id}")Emps findById(int id);
// 新增@Insert("insert into emps(id,username,password,addr,age,phone) values(null,#{username},#{password},#{addr},#{age},#{phone})")int save(Emps emps);
// 修改@Update("update emps set username=#{username},password=#{password}" +",addr=#{addr},age=#{age},phone=#{phone} where id=#{id}")int update(Emps emps);
// 删除@Delete("delete from emps where id=#{id}")int deleteById(int id);
}
- EmpsService
package com.it.service;import com.it.pojo.Emps;import java.util.List;public interface EmpsService {// 查询所有List<Emps> findAll();// 根据id查询Emps findById(int id);// 新增int save(Emps emps);// 修改int update(Emps emps);// 删除int deleteById(int id);}
- EmpsServiceImpl实现类
package com.it.service.impl;import com.it.mapper.EmpsMapper;
import com.it.pojo.Emps;
import com.it.service.EmpsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class EmpsServiceImpl implements EmpsService {
// @Autowired 遵循先按照接口类型注入,如果没有,再按照接口名称注入@Autowiredprivate EmpsMapper empsMapper;@Overridepublic List<Emps> findAll() {return empsMapper.findAll();}@Overridepublic Emps findById(int id) {return empsMapper.findById(id);}@Overridepublic int save(Emps emps) {return empsMapper.save(emps);}@Overridepublic int update(Emps emps) {return empsMapper.update(emps);}@Overridepublic int deleteById(int id) {return empsMapper.deleteById(id);}
}
- EmpsController层
package com.it.controller;import com.it.pojo.Emps;
import com.it.service.EmpsService;
import org.apache.ibatis.annotations.Delete;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;//@Controller
//@ResponseBody
@RestController
@RequestMapping("/emps")
public class EmpsController {@Autowiredprivate EmpsService empsService;@GetMappingpublic List<Emps> findAll() {return empsService.findAll();}@GetMapping("/{id}")public Emps findById(@PathVariable int id) {return empsService.findById(id);}@PostMappingpublic int save(@RequestBody Emps emps) {return empsService.save(emps);}@PutMappingpublic int update(@RequestBody Emps emps) {return empsService.update(emps);}// ?挂参数@DeleteMappingpublic int deleteById(@RequestParam int id) {return empsService.deleteById(id);}}
使用Apipost测试增删改查都是ok的✌
2. 前端整合
2.1 页面放行
在resourse下的page包下放入前端页面资料
浏览器输入路径查看页面是不行的,是因为把资料复制过来之后没有进行重新编译,SpringBoot项目并不知道我们提供的资料是项目的,所以需要我们自己进行编译并配置静态资源放行
- 停掉项目,进行重新编译
- SpringMvcConfig 配置静态资源放行
package com.it.config;import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;// 声明是配置类
@Configuration
// mvc配置注解
@EnableWebMvc
// 日志注解
@Slf4j
public class SpringMvcConfig implements WebMvcConfigurer {/*** Spring MVC配置类,用于配置Web相关的设置。* 实现了WebMvcConfigurer接口以自定义MVC配置。*/// 添加静态资源过滤@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {
// 拦截下路径/pages/** 放行到 /pages/registry.addResourceHandler("/pages/**").addResourceLocations("classpath:/pages/");
// 打印日志log.info("静态资源已经放行");}}
页面放行成功✌
2.2 前后端请求响应
修改前端请求路径,对应到后端,后端从而响应数据给前端,前端渲染展示,前端代码如下:
methods: {init() {// 初始化查询axios.get("/emps").then(resp => {if (resp.data.code == "200") {// 数据封装this.tableData = resp.data.data// 总条数赋值// this.page.total = resp.data.total}})},// 条目数发生改变handleSizeChange(val) {console.log(`每页 ${val} 条`);this.page.pageSize = valthis.init()},// 页码发生改变handleCurrentChange(val) {console.log(`当前页: ${val}`);this.page.currentPage = valthis.init()},// 打开新增弹框savedialog() {this.form = {}this.dialogFormVisible = true},// 查看单条数据详情handleClick(row) {console.log(row);},// 新增submitsaveEmp() {console.log(this.form)/*请求后台 json格式数据发送到后台*/axios.post("/emps",this.form).then(resp => {if (resp.data.code == "200"){/*清空form*/this.form = {}/*重新查询*/this.init()/*关闭天窗*/this.dialogFormVisible = false/*提示*/this.$message({message: resp.data.msg,type: 'success'})}})},// 删除deleteEmp(val) {console.log(val)/*请求后台 删除数据 刷新页面*/this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', {confirmButtonText: '删除',cancelButtonText: '取消',type: 'warning'}).then(() => {// 确定处理逻辑axios.delete("/emps?id="+val.id).then(resp => {if (resp.data.code== "200") {this.$message({message: '恭喜你,删除成功',type: 'success'});/*重新加载数据*/this.init()} else {this.$message('删除失败');}})}).catch(() => {// 取消的处理逻辑this.$message({type: 'info',message: '已取消删除'});});},// 修改回显updateEmp(val) {console.log(val)/*控制弹框*/this.dialogUpdateVisible = true/*数据赋值*/var str = JSON.stringify(val)var data = JSON.parse(str)this.form = data},// 修改提交updateEmpSubmit() {console.log(this.form)/*请求后台 json格式数据发送到后台*/axios.put("/emps", this.form).then(resp => {if (resp.data.code == "200") {/*把弹框隐藏掉*/this.dialogUpdateVisible = false/*把form清空*/this.form = {}this.$message({message: '恭喜你,修改成功',type: 'success'});/*重新加载数据*/this.init()} else {this.$message(resp.data.msg);}})},
3. 结果集封装
在项目开发中,为了明确记录各种返回码和数据结构,支持后端向前端响应不同类型的数据,可以进行统一结果集封装
3.1 结果集
package com.gaohe.ssm1.common;import lombok.Data;@Data
public class R {private String code;private String msg;private Object data;public static R success(String msg){R r = new R();r.code = "200";r.msg = msg;return r;}public static R success(Object data){R r = new R();r.code = "200";r.data = data;r.msg = "查询成功";return r;}public static R fail(String msg){R r = new R();r.code = "500";r.msg = msg;return r;}
}
3.2 controller层响应数据
那EmpsController可以进一步优化:
package com.gaohe.ssm1.controller;import com.gaohe.ssm1.common.R;
import com.gaohe.ssm1.pojo.Emps;
import com.gaohe.ssm1.service.EmpsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/emps")
public class EmpsController {@Autowiredprivate EmpsService empsService;@GetMappingpublic R list() {System.out.println("this handler");List<Emps> emps = empsService.list();return R.success(emps);}@GetMapping("/{id}")public R findById(@PathVariable int id) {Emps byId = empsService.findById(id);return R.success(byId);}@PostMappingpublic R save(@RequestBody Emps emps) {int i = empsService.save(emps);return i > 0 ? R.success("新增成功") : R.fail("新增失败");}@PutMappingpublic R update(@RequestBody Emps emps) {int i = empsService.update(emps);return i > 0 ? R.success("修改成功") : R.fail("修改失败");}@DeleteMappingpublic R delete(@RequestParam int id) {int i = empsService.delete(id);return i > 0 ? R.success("删除成功") : R.fail("删除失败");}
}