• 适合新手拿来练习的springboot+vue前后端分离小Demo


    前言:

    作者:神的孩子在歌唱

    大家好,我叫智

    一. 设计数据库

    这里用navicat创建了一张表

    image-20220626221631258

    二 . springboot项目创建

    打开idea

    image-20220625162231757

    image-20220625162332986

    image-20220625162854426

    取好名字后就成功创建一个springboot项目了

    image-20220625163621774

    2.1 基本配置

    在pom.xml中导入mybatis-plus: https://baomidou.com/pages/24112f/

        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-boot-starterartifactId>
            <version>3.4.3version>
        dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹:

    @MapperScan("com.chen.dao.mapper")
    
    • 1

    image-20220626142415384

    编写配置文件properties

    #server
    #访问接口
    server.port=8888
    #应用名称
    spring.application.name=cyz
    
    #datasource数据库配置
    spring.datasource.url=jdbc:mysql://localhost:3306/cyz?useUnicode=true&characterEncoding=UTF-8&serverTimeZone=UTC
    spring.datasource.username=root
    spring.datasource.password=123456
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    
    #mybatis-plus配置
    
    #打印日志,打印到控制台看到一些sql语句
    mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
    #标识表的前缀
    mybatis-plus.global-config.db-config.table-prefix=cyz_
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    2.2 创建dao层
    package com.chen.dao.pojo;
    
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Data;
    
    /**
     * @author: 那就叫小智吧
     * @date: 2022/6/25 17:50
     * @Version 1.0
     * @Description:
     */
    @Data
    @ApiModel("计划任务")
    public class Task {
        
        private  Long id;
    
        // 计划内容
        private String body;
    
        // 创建时间
        private Long createDate;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    mapper映射

    package com.chen.dao.mapper;
    
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.chen.dao.pojo.Task;
    
    /**
     * @author: 那就叫小智吧
     * @date: 2022/6/25 17:52
     * @Version 1.0
     * @Description:
     */
    public interface TaskMapper extends BaseMapper<Task> {
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    测试数据库是否连通

    package com.chen;
    
    import com.chen.dao.mapper.TaskMapper;
    import com.chen.dao.pojo.Task;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import java.util.List;
    
    /**
     * @author: 那就叫小智吧
     * @date: 2022/6/25 17:54
     * @Version 1.0
     * @Description:
     */
    @SpringBootTest
    class TaskApiApplicationTests {
        @Autowired(required = true)
        private TaskMapper taskMapper;
        @Test
        void contextLoads() {
            List<Task> tasts = (List<Task>) taskMapper.selectList(null);
            System.out.println(tasts);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    image-20220626142928527

    三. 配置swagger

    为了方便接口测试,我们用swagger对接口进行管理

    注入以下依赖

    <dependency>
        <groupId>io.springfoxgroupId>
        <artifactId>springfox-boot-starterartifactId>
        <version>3.0.0version>
    dependency>
    <dependency>
        <groupId>com.github.xiaoymingroupId>
        <artifactId>knife4j-spring-boot-starterartifactId>
        <version>2.0.7version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    knife4j:https://doc.xiaominfo.com/knife4j/documentation/description.html

    knife4j是美化swagger-ui的

    编写swagger配置

    package com.chen.config;
    
    import org.springframework.context.annotation.Configuration;
    import springfox.documentation.oas.annotations.EnableOpenApi;
    
    import java.util.ArrayList;
    
    @Configuration//编写配置项
    @EnableOpenApi//开启swagger
    //http://localhost:8888/swagger-ui/index.html
    //http://localhost:8888/doc.html
    public class SwaggerConfig {
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    原始的swagger-ui:http://localhost:8888/swagger-ui/index.html

    image-20220626144233837

    knife4j美化后:http://localhost:8888/doc.html

    image-20220626144048453

    四. 获取任务接口

    接下来我们编写一下获取任务的接口吧

    Task添加上 @ApiModelProperty(这是swagger上对参数的描述)

    @Data
    @ApiModel("计划任务")
    public class Task {
    
        private  Long id;
    
        // 计划内容
        @ApiModelProperty("计划内容")
        private String body;
    
        // 创建时间
        @ApiModelProperty("创建时间")
        private Long createDate;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    4.1 Result

    写一个统一返回的工具类

    package com.chen.util;
    
    import io.swagger.annotations.ApiModelProperty;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    /**
     * @author: 那就叫小智吧
     * @date: 2022/6/26 0:05
     * @Version 1.0
     * @Description:
     */
    @Data
    //所有有参构造器
    @AllArgsConstructor
    //无参构造器
    @NoArgsConstructor
    public class Result<T> {
        @ApiModelProperty("请求是否成功")
        private boolean success;
    
        @ApiModelProperty("状态码")
        private Integer code;
    
        @ApiModelProperty("参数")
        private String msg;
    
        @ApiModelProperty("返回数据")
        private T data;
    
        // 返回json数据类
        public static Result success(Object data) {
            return new Result(true, 200, "sucess", data);
        }
    
        // 请求失败
        public static Result fail(Integer code, String msg) {
            return new Result(false, code, msg, null);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    4.2 vo层

    创建vo层与前端交互

    TaskVo

    package com.chen.vo;
    
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Data;
    
    /**
     * @author: 那就叫小智吧
     * @date: 2022/6/26 0:03
     * @Version 1.0
     * @Description:
     */
    @Data
    @ApiModel("任务实体类")
    public class TaskVo {
        private Long id;
        // 计划内容
        @ApiModelProperty("计划内容")
        private String body;
        // 创建时间
        @ApiModelProperty("创建时间")
        private Long createDate;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    4.3 service层

    创建service层

    TaskService接口

    package com.chen.service;
    
    import com.chen.util.Result;
    import com.chen.vo.TaskVo;
    
    /**
     * @author: 那就叫小智吧
     * @date: 2022/6/26 0:14
     * @Version 1.0
     * @Description:
     */
    public interface TaskService {
        Result<TaskVo> listTask();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    TaskService实现

    package com.chen.service.impl;
    
    import com.chen.dao.mapper.TaskMapper;
    import com.chen.dao.pojo.Task;
    import com.chen.service.TaskService;
    import com.chen.util.Result;
    import com.chen.vo.TaskVo;
    import org.springframework.beans.BeanUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author: 那就叫小智吧
     * @date: 2022/6/26 0:23
     * @Version 1.0
     * @Description:
     */
    @Service
    public class TaskServiceImpl implements TaskService {
    
        @Autowired
        private TaskMapper taskMapper;
    
        @Override
        public Result<TaskVo> listTask() {
            List<Task> taskList = taskMapper.selectList(null);
            List<TaskVo> taskVoList = copyList(taskList);
            return Result.success(taskVoList);
        }
        // 循环遍历到列表中
        private List<TaskVo> copyList(List<Task> taskList) {
            List<TaskVo> taskVoList = new ArrayList<>();
            // stream真的香
            taskList.stream().forEach(task -> taskVoList.add(copy(task)));
            return taskVoList;
        }
        private TaskVo copy(Task task) {
            TaskVo taskVo = new TaskVo();
            BeanUtils.copyProperties(task, taskVo);
            return taskVo;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    4.4 控制层controller
    package com.chen.controller;
    
    import com.chen.service.TaskService;
    import com.chen.service.impl.TaskServiceImpl;
    import com.chen.util.Result;
    import com.chen.vo.TaskVo;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author: 那就叫小智吧
     * @date: 2022/6/26 0:46
     * @Version 1.0
     * @Description:
     */
    @RestController
    @RequestMapping("task")
    @Api(tags = "计划任务接口")
    public class TaskController {
    
        @Autowired
        private TaskService taskService;
        @ApiOperation("获取任务列表")
        @GetMapping
        public Result<TaskVo> ListTask() {
            return taskService.listTask();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    我们重启项目打开swagger

    image-20220626144942227

    获取到了数据库数据

    image-20220626145016808

    接下来就是编写前端页面将这些数据渲染上去就可以了

    image-20220626145249244

    五 . vue2创建前端项目

    vue官网:https://cn.vuejs.org/v2/guide/index.html#%E5%A3%B0%E6%98%8E%E5%BC%8F%E6%B8%B2%E6%9F%93

    https://blog.csdn.net/weixin_46659028/article/details/122123984

    1. 电脑安装node.js
      下载地址:https://nodejs.org/en/download/

      image-20220625170150459

      根据自己电脑型号安装node的版本,点击下载之后,继续下一步直至完成安装就行,

    2. 创建一个文件夹,打开cmd控制命令行程序

      node -v
      npm -v
      
      • 1
      • 2
    3. 安装webpack

      npm install webpack –g
      
      • 1

    如果安装太慢就使用淘宝NPM 镜像

    npm install -g cnpm --registry=https://registry.npm.taobao.org
    这样就可以使用cnpm 命令来安装模块了

    1. 安装脚手架

      vue init webpack cyz_web
      
      • 1

    image-20220625161418262

    image-20220625161434921

    npm install

    1. 执行npm run dev

      在浏览器中运行http://localhost:8080/#/

    image-20220625161536212

    5.1 axios

    1. 通过终端安装axios
    cnpm install axios
    
    • 1

    image-20220626145500696

    1. 在main.js中导入
    import axios from 'axios'
    Vue.prototype.$axios = axios //
    
    • 1
    • 2
    1. 编写Task.vue

    用idea打开创建好的项目 创建一个Task.vue文件

    image-20220626145358742

    在App.vue中注释掉img

    image-20220626150309072

    1. 通过axios获取后端数据
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    1. index.js中设置路由
    import Vue from 'vue'
    import Router from 'vue-router'
    import HelloWorld from '@/components/HelloWorld'
    import Task from '@/views/Task'
    Vue.use(Router)
    
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component: HelloWorld
        },
        {
          path: '/task',
          name: 'Task',
          component: Task
        }
      ]
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    访问页面发现报错了

    image-20220626150422580

    这是跨域问题

    1. 后台设置允许跨域
    package com.chen.config;
    //配置类
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.CorsRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class WebConfig  implements WebMvcConfigurer {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            //跨域配置,不可设置为*,不安全, 前后端分离项目,可能域名不一致
            //本地测试 端口不一致 也算跨域
            registry.addMapping("/**").allowedOrigins("http://localhost:8080");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在浏览器上进行访问就能获取到数据了

    image-20220626150610061

    5.2 element

    接下来就是将这些数据渲染到页面中去就可以了

    这里我们通过element-ui对数据进行渲染

    官方网站: https://element.eleme.cn/#/zh-CN/component/table

    在本目录下安装

    cnpm install element-ui --save
    
    • 1

    image-20220626150953639

    在main.js中导入

    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css'
    Vue.use(ElementUI)
    
    • 1
    • 2
    • 3

    我们找到element中的基础表格直接拿来用

    image-20220626150811910

    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    再次运行

    image-20220626151246488

    前后端分离的一个基本用法已经完成了

    本人csdn博客:https://blog.csdn.net/weixin_46654114

    转载说明:跟我说明,务必注明来源,附带本人博客连接。

  • 相关阅读:
    微服务治理热门技术揭秘:无损上线
    Discuz3.X各广告位的具体位置和效果探究
    平衡二叉树的定义,插入操作以及插入新结点后的调整规则(ALV树)
    提权方法:利用环境变量路径劫持提权
    「 打卡训练 」Fiddler(三) - 抓取http请求
    苍穹外卖day10(2)WebSocket、来单提醒、客户催单
    Istio实践(4)- 故障注入、熔断及ServiceEntry
    内存对齐对性能的影响
    Java关于普通查找和二分查找
    实践出真知:全网最强秒杀系统架构解密,不是所有的秒杀都是秒杀!!
  • 原文地址:https://blog.csdn.net/weixin_46654114/article/details/127493357