当前位置: 首页 > news >正文

前后端分离: vue3+SpringBoot+ElementPlus+Axios+MyBatisPuls

前后端分离: vue3+SpringBoot

  • 项目介绍
  • 搭建Vue前端工程
    • axios请求响应拦截
    • 跨域
  • 搭建后端
    • @TableId,@TableName
    • 分页显示
    • 配置Druid数据源
    • 带条件的分页查询
    • 后端校验
    • lambda表达式说明

项目介绍

🌟项目页面

在这里插入图片描述


🌟技术栈:
1.前端技术栈: Vue3+Axios+ElementPlus
2.后端技术栈: SpringBoot+MyBatisPlus
3.数据库: MySQL
4.项目依赖管理: Maven
5.分页: MyBatisPlus的分页插件
6.切换数据源DruidDataSource
7.在LambdaQueryWrapper 引出知识点 lambda方法引用的 类名::实例方法
8.前端使用了axios关于request和respones的拦截器, 并且解决了跨域问题

gitee网址: https://gitee.com/zhao-zhiwei521/vue-springboot

搭建Vue前端工程

一,SSM整合-前后端分离(项目环境搭建)
二,SSM项目-前后端分离(搭建Vue前端工程)

vue create springboot_vue

axios请求响应拦截

//重要提示: 如果在启动前端项目时, 提示找不到axios, 把光标放在 import axios from "axios"的'axios', 会有一个修复提示, 导入axios, 导入即可正常使用.
import axios from 'axios'const axios_ = axios.create({timeout: 5000
})//添加请求拦截器
axios_.interceptors.request.use(config => {//在请求之前请求头转为json数据config.headers['Content-Type'] = 'application/json;charset=utf-8'return config
}, error => {return Promise.reject(error)
})//添加响应拦截器
axios_.interceptors.response.use(response => {console.log('response======>', JSON.stringify(response))let res = response.data;//如果返回的是文件if (response.config.responseType === 'blob') {return res;}//如果是string类型, 就转为jsonif (typeof res === 'string') {res = res ? JSON.parse(res) : res;}return res;
}, error => {return Promise.reject(error);
})export default axios_

跨域

module.exports = {devServer: {port: 10000, // 前端开发服务器运行端口(通过 http://localhost:10000 访问)proxy: {      // 代理配置(用于解决开发环境跨域问题)'/api': {   // 拦截所有以 /api 开头的请求target: 'http://localhost:9090/', // 后端服务地址(对应您的 Spring Boot 应用)changeOrigin: true, // 修改请求头中的 Origin 为目标地址(模拟同源请求)pathRewrite: {'^/api': '' // 路径重写:移除请求路径中的 /api 前缀}}}}
}

搭建后端

SSM整合-前后端分离(实现增删改查)

在这里插入图片描述

@TableId,@TableName

//如果SysUser实体类名和数据库表名一致,或者经过驼峰换转后一致, 则不需要加@TableName注解
@Data
//@TableName("sys_user")
public class SysUser {//这里我们使用@TableId, 表主键标识//当我们在private Integer id上标识了@TableId, 说明id对应的就是表的id字段, 而且是主键@TableId(value = "id", type = IdType.AUTO)private Integer id;
}

分页显示

思路:
1.后台使用mybatis-plus分页插件
2.前端使用vue分页组件

实现
1.src/main/java/com/zzw/springboot/config/MybatisPlusConfig.java

@Configuration
public class MybatisPlusConfig {/*** 1.注入MybatisPlusInterceptor 对象/bean* 2.在MybatisPlusInterceptor bean 加入分页插件 PaginationInnerInterceptor*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();//这里的分页要指定数据库的类型,因为不同的数据库,分页的sql语句不一样mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return mybatisPlusInterceptor;}
}

2.SysUserController 分页查询

//前后端分离, 前端发出请求, 后端返回json数据
@Slf4j
@RestController
@RequestMapping("/sysUser")
public class SysUserController {@Autowiredprivate SysUserService sysUserService;/**** @param pageNum 显示第几页, 默认为 1* @param pageSize 每页有多少条 默认为10* @return*/@GetMapping("listByPage")public Result listByPage(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {//1.在javaweb中, 分页查询已经学过Page<SysUser> page = sysUserService.page(new Page<>(pageNum, pageSize));//2.返回数据, 查询分页查询的数据结构return Result.success(page);}
}

3.vue分页组件

<el-paginationv-model:current-page="searchForm.currentPage"v-model:page-size="searchForm.pageSize":total="total":page-sizes="[10, 20, 50, 100]"layout="total, sizes, prev, pager, next, jumper"@size-change="handleSizeChange"@current-change="handleCurrentChange"
/>

在这里插入图片描述

配置Druid数据源

参考整合Druid到SpringBoot

带条件的分页查询

@GetMapping("listByCondition")
public Result listByCondition(@RequestParam(defaultValue = "1") Integer pageNum,@RequestParam(defaultValue = "10") Integer pageSize,SysUser sysUser) {//1.先床啊进QueryWrapper, 可以将我们的检索条件封装进QueryWrapperQueryWrapper<SysUser> wrapper = new QueryWrapper<>();// 根据用户名模糊查询if (StringUtils.hasText(sysUser.getUsername()) ) {wrapper.like("username", sysUser.getUsername());}Page<SysUser> page = sysUserService.page(new Page<>(pageNum, pageSize), wrapper);return Result.success(page);
}

后端校验

/*** 验证表单*/
private Map<String, Object> validateForm(Errors errors) {Map<String, Object> errorMap = new HashMap<>();List<FieldError> fieldErrors = errors.getFieldErrors();for (FieldError fieldError : fieldErrors) {errorMap.put(fieldError.getField(), fieldError.getDefaultMessage());}return errorMap;
}
}@PostMapping("/save")public Result save(@RequestBody @Validated SysUser sysUser, Errors errors) {Map<String, Object> map = validateForm(errors);if (!map.isEmpty()) {return Result.error(map, "数据校验失败");}boolean save = sysUserService.save(sysUser);if (save) {return Result.success("添加成功");}return Result.error("添加失败");}

lambda表达式说明

https://baijiahao.baidu.com/s?id=1652786021461159890&wfr=spider&for=pc

https://blog.csdn.net/hjl21/article/details/102702934

解读

//编写方法,使用lambdaQueryWrapper封装查询条件, 完成检索
@GetMapping("listByCondition2")
public Result listByCondition2(@RequestParam(defaultValue = "1") Integer pageNum,@RequestParam(defaultValue = "10") Integer pageSize,SysUser sysUser) {//说明: 关于lambda表达式, 我们这里使用的是 类名::实例方法//是lambda方法引用中不太好理解的//解读//1. SysUser::getUsername 通过lambda表达式 引用实例方法 getUsername//2. 这里就是把 SysUser::getUsername 赋给 SFunction<T,R> 函数式接口//3. 查看 SFunction<T,R> 源代码/*** @FunctionalInterface* public interface SFunction<T, R> extends Function<T, R>, Serializable {* }* 父接口*@FunctionalInterface* public interface Function<T, R> {*      R apply(T t);//抽象方法, 表示根据类型T的参数, 获取类型R的结果**      //这里有默认实现方法* }*///4.传入 SysUser::getUsername 后, 就相当于实现了 SFunction<T,R> 的apply方法//5.底层会根据 传入的 SysUser:getUsername 去得到该方法的对应的属性映射的表的字段, 更加灵活//<resultMap id="BaseResultMap" type="com.zzw.springboot.bean.SysMenu">//        <id column="id" jdbcType="INTEGER" property="id"/>//创建lambdaQueryWrapper, 封装查询条件LambdaQueryWrapper<SysUser> lambdaQueryWrapper = Wrappers.<SysUser>lambdaQuery();//判断if (StringUtils.hasText(sysUser.getUsername())) {//lambdaQueryWrapper.like(SysUser::getUsername, sysUser.getUsername());//换一个写法, 依然正确SFunction<SysUser, Object> sf = SysUser::getUsername;;lambdaQueryWrapper.like(sf, sysUser.getUsername());}Page<SysUser> page = sysUserService.page(new Page<SysUser>(pageNum, pageSize), lambdaQueryWrapper);log.info("page={}", page);return Result.success(page);
}

模拟实现src/main/java/com/zzw/springboot/lambda/Test.java

public class Test {public static void main(String[] args) {//传统的方法来实现ZzwFuntcion接口, 使用匿名内部类, 得到一个实现接口的对象/*** class Test$1 implements ZzwFunction<AClass, Object> {*     public Object apply (Aclass aclass) {*          return "Aclass";*     }* }* Test$1 test$1 = new Test$1();* test$1.apply(new Aclass());*///ZzwFunction<AClass, String> zf = new ZzwFunction<AClass, String>() {//    @Override//    public String apply(AClass aClass) {//        return "AClass";//    }//};//Object result = zf.apply(new AClass());//System.out.println("result=" + result);ZzwFunction<AClass, String> zf2 = AClass::getBrand;Object result2 = zf2.apply(new AClass());System.out.println("result2=" + result2);//zf2.say();}
}//定义一个函数式接口: 有且只有一个抽象方法的接口
//可以使用@FunctionalInterface 来标识一个函数式接口
//ZzwFunction是一个函数式接口(这个是一个自定义泛型接口)
@FunctionalInterface
interface ZzwFunction<T,R> {R apply(T t);//抽象方法: 表示根据类型T的参数, 获取类型R的结果//函数式接口, 依然可以有多个默认是先方法default public void say() {System.out.println("hello");}
}class AClass {//Beanprivate String name = "lambda AClass";private String brand = "奔驰品牌";public String getName() {return name;}public String getBrand() {return brand;}
}

相关文章:

  • 在 Ubuntu 22.04 x64 系统安装/卸载 1Panel 面板
  • Docker容器技术基础入门
  • Java 的创新与变革之路:从 JDK 7 到 JDK 23
  • 无需手动重建!Altium到Cadence的封装转换:ASCII文件方法详解
  • 前端实现商品放大镜效果(Vue3完整实现)
  • 【计算机视觉】TorchVision 深度解析:从核心功能到实战应用 ——PyTorch 官方计算机视觉库的全面指南
  • MCU低功耗运行模式与唤醒机制解析
  • Docker 常用命令(涵盖多个方面)
  • 8、HTTPD服务--ab压力测试
  • Java多线程入门案例详解:继承Thread类实现线程
  • mtrace和memleak源码分析
  • 从困局到破局的AI+数据分析
  • 【机器学习】​碳化硅器件剩余使用寿命稀疏数据深度学习预测
  • UE 滚动提示条材质制作
  • 民锋视角下的价格风险管理策略
  • 0805登录_注册_token_用户信息_退出-网络ajax请求2-react-仿低代码平台项目
  • 八大排序——快速排序/快排优化
  • 【javascript】竞速游戏前端优化:高频操作与并发请求的解决方案
  • jaffree 封装ffmpeg 转换视频格式,获取大小,时间,封面
  • 汤晓鸥:计算机视觉的开拓者与AI产业化的先行者
  • 药明康德一季度净利增长89%,在手订单增超四成至523亿元
  • 夜读丨怀念那个写信的年代
  • 央行副行长:研究建立民营中小企业增信制度,破解民营中小企业信用不足等融资制约
  • 广州海关原党委委员、副关长刘小威被开除党籍
  • 民航局:预计五一假期民航旅客运输量创同期历史新高,将加强价格管理
  • 涉李小龙形象商标被判定无效,真功夫:暂无更换计划