梳理总结SpringBoot+Vue前后端分离的简单实现

1、简介

想做一个简单的Java前后端分离的项目,不知如何下手,利用闲暇时间将学习的SpringBoot和Vue做一次简单的小整合,从而实现简单的前后端分离,帮助理清前后端思路。

该文档的目的就是为了帮助你理清前后端分离,并将对应的数据进行简单的CRUD,希望对你有所帮助。
梳理总结SpringBoot+Vue前后端分离的简单实现_第1张图片

2、技术栈

使用的工具:

IntelliJ IDEA 2021.2.1,Maven,Navicat Premium 16,

前端

Vue:3.2.38

axios:1.1.3

ElementUI Plus 2.2.17

后端

SpringBoot 2.7.4

MySQL 5.7.36

Mybatis Plus

3、常用配置文件

IDEA创建一个SpringBoot项目,然后修改pom.xml文件添加相关依赖。

3.1、pom.xml文件



    org.springframework.boot
    spring-boot-starter-web



    mysql
    mysql-connector-java
    5.1.47



    com.baomidou
    mybatis-plus-boot-starter
    3.4.2



    com.alibaba
    druid
    1.2.13-SNSAPSHOT



    org.projectlombok
    lombok
    true

3.2、创建数据库和表

推荐一个网站可以快速创建数据库。https://www.sqlfather.com/

建表语句

-- 用户表信息
create table if not exists vaccine_system.`user`
(
`id` bigint not null auto_increment comment '主键' primary key,
`username` varchar(256) not null comment '用户名',
`password` varchar(256) not null comment '密码',
`id_card` varchar(256) null comment '身份证号',
`real_name` varchar(256) not null comment '真实姓名',
`gender` varchar(256) not null comment '性别',
`address` varchar(256) not null comment '地址',
`phone` varchar(256) not null comment '手机号',
`role` varchar(256) default '0' not null comment '角色',
`age` varchar(256) not null comment '年龄',
`user_status` varchar(256) default '0' not null comment '状态',
`update_time` datetime default 'CURRENT_TIMESTAMP' not null on update CURRENT_TIMESTAMP comment '更新时间',
`create_time` datetime default 'CURRENT_TIMESTAMP' not null comment '创建时间',
`is_deleted` tinyint default 0 not null comment '是否删除(0-未删, 1-已删)'
) comment '用户表信息';

插入数据

insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('藤森里穂', 'password', '田振家', '女', '宜城市', '13884310615', '87');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('末広純', 'password', '钟博文', '女', '泰州市', '14577692413', '92');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('櫻空桃', 'password', '陆梓晨', '女', '崇左市', '17010768373', '36');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('西田那津', 'password', '萧浩', '女', '诸城市', '17179533521', '95');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('蓮實克蕾兒', 'password', '吕天宇', '女', '江油市', '15190645338', '97');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('藤森里穂', 'password', '高擎苍', '女', '巴彦淖尔市', '17300534915', '45');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('三上悠亜', 'password', '杨智宸', '男', '峨眉山市', '15834255560', '32');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('葵司', 'password', '贾鹏煊', '男', '茂名市', '15042781120', '100');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('伊藤舞雪', 'password', '廖耀杰', '男', '临清市', '17127846009', '65');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('櫻空桃', 'password', '廖雨泽', '男', '淮北市', '17814700078', '92');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('松本一香', 'password', '崔修杰', '女', '新泰市', '15832830726', '53');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('七澤美亞', 'password', '顾泽洋', '女', '瑞丽市', '15984970745', '93');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('七森莉莉', 'password', '董浩宇', '男', '平湖市', '15227610271', '40');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('櫻空桃', 'password', '黎语堂', '女', '武夷山市', '17121546218', '74');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('石原希望', 'password', '莫智宸', '女', '南京市', '15147185954', '85');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('小宵虎南', 'password', '龚立轩', '男', '图木舒克市', '14508002887', '70');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('夢乃愛華', 'password', '冯天磊', '男', '郑州市', '17517334820', '43');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('七澤美亞', 'password', '阎振家', '男', '诸城市', '17182063425', '12');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('蕾', 'password', '袁烨磊', '男', '福安市', '18288482422', '46');
insert into vaccine_system.`user` (`username`, `password`, `real_name`, `gender`, `address`, `phone`, `age`) values ('河北彩花', 'password', '夏懿轩', '女', '沅江市', '17134097852', '94');

修改数据库配置文件application.properties

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/iw?useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#单个文件大小,默认1MB
spring.servlet.multipart.max-file-size=10MB
#每次请求文件的大小
spring.servlet.multipart.max-request-size=10MB

3.3、使用IDEA的插件MybatisX-Generator快速创建相关文件

3.4、创建controller包

需要使用到的几个注解。简单举例:

@RestController
@RequestMapping(value=“/login”,method = RequestMethod.GET) //该写法等同于GetMapping

@RequestMapping(value=“/login”,method = RequestMethod.POST) //该写法等同于PostMapping

@GetMapping(“/login”)//RESTful风格要求尽量用该注解进行获取资源

@PostMapping(“/login”)//RESTful风格要求尽量用该注解进行新建资源

@PutMapping(“”) //RESTful风格要求尽量用该注解进行更新资源

@DeleteMapping(“”) //RESTful风格要求尽量用该注解进行删除资源

@PathMapping() //RESTful风格要求尽量用该注解进行部分资源更新

@RequestParam 参数传递时,参数名称和方法中的名称不一致时可以使用。被该注解标记的参数必须有值。添加属性required=false可更改不必须有值。

@PathVariable 动态获取一个值。注意:@GetMapping(“/login/{id}”)要加上{}

@RequestBody 接收json类型的注解

@TableLogic 逻辑删除,添加到属性名上。例如:@TableLogic private Integer isDeleted;

Mybatis Plus中的一些注解

@TableId(type = IdType.AUTO) 设置到实体类的主键上,自动填充值。

@TableField(“”) 数据库中的名称和实体类中属性的名称不一致时可以使用。实体类中有数据库中不存在的字段时,可以使用exist=false属性设置为该字段为非数据库字段。

创建UserController类:

@RestController
public class UserController {

    //查询全部
    @GetMapping("/user/findAll")
    public List<User> findAll(){
        return "查询全部人员";
    }
}

运行SpringBoot启动类并在浏览器中访问localhost:8080/user/findAll。

3.5、Mybatis Plus分页插件

编写配置类MybatisPlusConfig

@Configuration
@MapperScan("scan.your.mapper.package")
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

简单使用

//分页查询
@GetMapping("/user/findByPage")
public IPage<User> findByPage(){
    //设置查询的起始值及每页条数
    Page<User> page = new Page<>(0,5);
    //将查询的结果封装成了一个新的对象
    IPage<User> iPage = userMapper.selectPage(page, null);
    return iPage;
}

4、前端部分

4.1、Vue3

https://cn.vuejs.org/

使用node.js下载Vue3,并创建一个项目。

npm init vue@latest

可供选用的功能

✔ Project name: … <your-project-name>
✔ Add TypeScript? … No / Yes
✔ Add JSX Support? … No / Yes
✔ Add Vue Router for Single Page Application development? … No / Yes
✔ Add Pinia for state management? … No / Yes
✔ Add Vitest for Unit testing? … No / Yes
✔ Add Cypress for both Unit and End-to-End testing? … No / Yes
✔ Add ESLint for code quality? … No / Yes
✔ Add Prettier for code formatting? … No / Yes

Scaffolding project in ./<your-project-name>...
Done.

4.2、ElementUI Plus

https://element-plus.gitee.io/zh-CN/

使用组件快速开发。

npm install element-plus --save

​ main.js中添加以下内容

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus)

4.3、Axios

https://www.axios-http.cn/

第一步:安装

npm install axios

第二步:main.js文件中添加

import axios from 'axios'

第三步:main.js文件中注册

//将axios作为全局的自定义属性,每个组件可以在内部直接访问
app.config.globalProperties.$http=axios

第四步:main.js文件中指定请求头

//配置请求根路径
axios.defaults.baseURL = 'http://localhost:8080';

4.4、跨域

1、@CrossOrigin 在controller包下需要跨域的类添加注解。
2、编写跨域配置文件,允许全部跨域。

5、具体使用

之后可以在前端界面中添加一个ElementUI Plus的表格,启动前端项目和后端项目,使用axios将后端数据加载到前端。

6、前端代码

main.js文件:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

import './assets/main.css'

import axios from 'axios'
//配置请求根路径
axios.defaults.baseURL = 'http://localhost:8080';

const app = createApp(App)

app.use(ElementPlus)

app.use(router)
//将axios作为全局的自定义属性,每个组件可以在内部直接访问
app.config.globalProperties.$http=axios

app.mount('#app')

前端页面的代码:
这里我是使用的AboutView.vue文件,我将其内容全部重写了。






7、后端代码

梳理总结SpringBoot+Vue前后端分离的简单实现_第2张图片
MybatisPlusConfig 配置文件:

@Configuration
@MapperScan("com.f.iw.mapper")
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

UserController

@CrossOrigin
@RestController
public class UserController {
    @Autowired
    private UserMapper userMapper;

    //查询全部
    @GetMapping("/user/findAll")
    public List<User> findAll(){
        List<User> list = userMapper.selectList(null);
        System.out.println(list);
        return list;
    }

    //分页查询
    @GetMapping("/user/findByPage")
    public IPage<User> findByPage(){
        //设置查询的起始值及每页条数
        Page<User> page = new Page<>(0,5);
        //将查询的结果封装成了一个新的对象
        IPage<User> iPage = userMapper.selectPage(page, null);
        return iPage;
    }
}

User

/**
 * 用户表信息
 * @TableName user
 */
@Data
public class User implements Serializable {
    /**
     * 主键
     */
    @TableId(type = IdType.AUTO)
    private Long id;

    /**
     * 用户名
     */

    private String username;

    /**
     * 密码
     */
    private String password;

    /**
     * 身份证号
     */
    private String idCard;

    /**
     * 真实姓名
     */
    private String realName;

    /**
     * 性别
     */
    private String gender;

    /**
     * 地址
     */
    private String address;

    /**
     * 手机号
     */
    private String phone;

    /**
     * 角色
     */
    private String role;

    /**
     * 年龄
     */
    private String age;

    /**
     * 状态
     */
    private String userStatus;

    /**
     * 更新时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
    private Date updateTime;

    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
    private Date createTime;

    /**
     * 是否删除(0-未删, 1-已删)
     */
    private Integer isDeleted;

    private static final long serialVersionUID = 1L;

    @Override
    public boolean equals(Object that) {
        if (this == that) {
            return true;
        }
        if (that == null) {
            return false;
        }
        if (getClass() != that.getClass()) {
            return false;
        }
        User other = (User) that;
        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
            && (this.getUsername() == null ? other.getUsername() == null : this.getUsername().equals(other.getUsername()))
            && (this.getPassword() == null ? other.getPassword() == null : this.getPassword().equals(other.getPassword()))
            && (this.getIdCard() == null ? other.getIdCard() == null : this.getIdCard().equals(other.getIdCard()))
            && (this.getRealName() == null ? other.getRealName() == null : this.getRealName().equals(other.getRealName()))
            && (this.getGender() == null ? other.getGender() == null : this.getGender().equals(other.getGender()))
            && (this.getAddress() == null ? other.getAddress() == null : this.getAddress().equals(other.getAddress()))
            && (this.getPhone() == null ? other.getPhone() == null : this.getPhone().equals(other.getPhone()))
            && (this.getRole() == null ? other.getRole() == null : this.getRole().equals(other.getRole()))
            && (this.getAge() == null ? other.getAge() == null : this.getAge().equals(other.getAge()))
            && (this.getUserStatus() == null ? other.getUserStatus() == null : this.getUserStatus().equals(other.getUserStatus()))
            && (this.getUpdateTime() == null ? other.getUpdateTime() == null : this.getUpdateTime().equals(other.getUpdateTime()))
            && (this.getCreateTime() == null ? other.getCreateTime() == null : this.getCreateTime().equals(other.getCreateTime()))
            && (this.getIsDeleted() == null ? other.getIsDeleted() == null : this.getIsDeleted().equals(other.getIsDeleted()));
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
        result = prime * result + ((getUsername() == null) ? 0 : getUsername().hashCode());
        result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());
        result = prime * result + ((getIdCard() == null) ? 0 : getIdCard().hashCode());
        result = prime * result + ((getRealName() == null) ? 0 : getRealName().hashCode());
        result = prime * result + ((getGender() == null) ? 0 : getGender().hashCode());
        result = prime * result + ((getAddress() == null) ? 0 : getAddress().hashCode());
        result = prime * result + ((getPhone() == null) ? 0 : getPhone().hashCode());
        result = prime * result + ((getRole() == null) ? 0 : getRole().hashCode());
        result = prime * result + ((getAge() == null) ? 0 : getAge().hashCode());
        result = prime * result + ((getUserStatus() == null) ? 0 : getUserStatus().hashCode());
        result = prime * result + ((getUpdateTime() == null) ? 0 : getUpdateTime().hashCode());
        result = prime * result + ((getCreateTime() == null) ? 0 : getCreateTime().hashCode());
        result = prime * result + ((getIsDeleted() == null) ? 0 : getIsDeleted().hashCode());
        return result;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", username=").append(username);
        sb.append(", password=").append(password);
        sb.append(", idCard=").append(idCard);
        sb.append(", realName=").append(realName);
        sb.append(", gender=").append(gender);
        sb.append(", address=").append(address);
        sb.append(", phone=").append(phone);
        sb.append(", role=").append(role);
        sb.append(", age=").append(age);
        sb.append(", userStatus=").append(userStatus);
        sb.append(", updateTime=").append(updateTime);
        sb.append(", createTime=").append(createTime);
        sb.append(", isDeleted=").append(isDeleted);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }
}

UserMapper

public interface UserMapper extends BaseMapper<User> {

}

IwApplication

@SpringBootApplication
@MapperScan("com.f.iw.mapper")
public class IwApplication {

    public static void main(String[] args) {
        SpringApplication.run(IwApplication.class, args);
    }

}

8、最后

启动前后端项目,然后就能的到一个巨丑无比的表格,表格中的数据就是数据库中的数据。后续的简单的CRUD操作,可以直接使用mybatis plus提供的方法即可。
梳理总结SpringBoot+Vue前后端分离的简单实现_第3张图片
至此简单的前后端数据算是绑定在一起了,可以进行其他的操作了。

9、推荐一个github上的项目供学习参考

这里推荐一个后台管理的前后端项目。
项目地址:vue-element-admin
项目文档也非常的齐全,可供学习参考。

你可能感兴趣的:(spring,boot,vue.js,mybatis,前端,后端)