后端SpringBoot+前端Vue前后端分离的项目(一)

前言:后端使用SpringBoot框架,前端使用Vue框架,做一个前后端分离的小项目,需求:实现一个表格,具备新增、删除、修改的功能。

目录

一、数据库表的设计

二、后端实现

环境配置

数据处理-增删改查

model层

mapper层

XML配置

Service层

controller层

单元测试

三、前后端交互

配置

vite.config.ts文件配置

创建axios实例 

业务请求

四、前端实现

环境配置

Main.vue

interface接口

五、效果展示

六、总结


一、数据库表的设计

设计了一个merchandise表,id是编号,唯一的,类型为int,category是一级类别,type是二级类别,name是商品的名称,sum_quantity是总数量,sold_quantity是售卖的数量。

后端SpringBoot+前端Vue前后端分离的项目(一)_第1张图片

数据库里的字段名使用的是下划线连接,在java中变量命名一般使用驼峰式,需要在application.properties文件中进行配置

mybatis.configuration.map-underscore-to-camel-case=true

二、后端实现

model层

package com.mrjj.java.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class merchandise {
    public int id;
    public String category;
    public String type;
    public String name;
    public String sum_quantity;
    public String sold_quantity;
}

环境配置

引入需要的依赖

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

        
            org.springframework.boot
            spring-boot-starter-tomcat
            provided
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.2.2
        
        
            mysql
            mysql-connector-java
            8.0.19
        
        
            org.mybatis.generator
            mybatis-generator-core
            1.4.0
        
        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        
        
            org.projectlombok
            lombok
        
        
            com.baomidou
            mybatis-plus-boot-starter
            3.5.3
        

 完成application.properties文件的配置,连接mysql

server.port=8888
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mrjj?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
mybatis.mapper-locations=classpath:/mapper/*.xml
mybatis.configuration.map-underscore-to-camel-case=true

数据处理-增删改查

model层

映射数据库中的字段

package com.mrjj.java.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Merchandise {
    public int id;
    public String merchandiseCategory;
    public String merchandiseType;
    public String merchandiseName;
    public int sumQuantity;
    public int soldQuantity;
}

返回结果字段

package com.mrjj.java.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
    private Integer code;
    private String msg;
    private T data;

    public Result(String msg, Integer code) {
        this.msg = msg;
        this.code = code;
    }

    public Result(T data) {
        this.data = data;
        this.code = 1000;
    }

    public static  Result success(T data) {
        Result result = new Result<>(data);
        result.setCode(200);
        result.setMsg("请求成功");
        return result;
    }

    public static  Result success(String msg, T data) {
        Result result = new Result<>(data);
        result.setCode(200);
        result.setMsg(msg);
        return result;
    }

    public static  Result fail(int code, String message, T data) {
        Result resultData = new Result<>();
        resultData.setCode(code);
        resultData.setMsg(message);
        resultData.setData(data);
        return resultData;
    }
}

mapper层

package com.mrjj.java.mapper;

import com.mrjj.java.model.Merchandise;
import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper
public interface MerchandiseMapper {

    @Select("select * from merchandise")
    List getMerchandise();

    @Insert("insert into merchandise values(#{id},#{merchandiseCategory},#{merchandiseType},#{merchandiseName},#{sumQuantity},#{soldQuantity})")
    int addMerchandise(Merchandise merchandise);

    @Delete("delete from merchandise where id=#{id}")
    int deleteOneMerchandise(@Param("id") Long id);

    int updateMerchandise(List merchandise);
}

XML配置

注意!!!

要配置上allowMultiQueries=true,才能批量处理!!!这个问题查了蛮久的!!!





    

    
        delete from merchandise
        
            
                #{item}
            
        
    

    
        
            update merchandise
            
                
                    merchandise_category=#{item.merchandiseCategory},
                
                
                    merchandise_type=#{item.merchandiseType},
                
                
                    merchandise_name=#{item.merchandiseName},
                
                
                    sum_quantity=#{item.sumQuantity},
                
                
                    sold_quantity=#{item.soldQuantity},
                

            
            where id=#{item.id}
        
    

Service层

package com.mrjj.java.service;

import java.util.List;

public interface MerchandiseService {
    int deleteMoreMerchandise(List ids);
}
package com.mrjj.java.service.impl;

import com.mrjj.java.mapper.MerchandiseMapper;
import com.mrjj.java.service.MerchandiseService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service("MerchandiseService")
public class MerchandiseServiceImpl implements MerchandiseService {
    @Resource
    MerchandiseMapper merchandiseMapper;


    @Override
    public int deleteMoreMerchandise(List ids) {
        int delCount = 0;
        for (Long id : ids) {
            delCount += merchandiseMapper.deleteOneMerchandise(id);
        }
        System.out.println("删除了" + delCount + "条用例");
        return delCount;
    }
}

controller层

package com.mrjj.java.controller;

import com.mrjj.java.mapper.MerchandiseMapper;
import com.mrjj.java.model.Merchandise;
import com.mrjj.java.model.Result;
import com.mrjj.java.service.MerchandiseService;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/mrjjMerchandise")
public class MerchandiseController {
    @Resource
    MerchandiseMapper merchandiseMapper;
    @Resource
    MerchandiseService merchandiseService;

    @GetMapping
    public Result listMerchandise() {
        List Marchandise = merchandiseMapper.getMerchandise();
        System.out.println("查到的商品是" + Marchandise);
        return Result.success(Marchandise);
    }

    @GetMapping("/view")
    public ModelAndView showMerchandise() {
        ModelAndView MarchandiseView = new ModelAndView();
        List Marchandise = merchandiseMapper.getMerchandise();
        MarchandiseView.addObject("mrjjMarchandiseView", Marchandise);
        MarchandiseView.setViewName("mrjjMarchandise");
        return MarchandiseView;
    }

    @PostMapping
    public Result addMerchandise(@RequestBody Merchandise merchandise) {
        int i = merchandiseMapper.addMerchandise(merchandise);
        if (i > 0) {
            return Result.success(merchandise);
        } else {
            return Result.fail(210, "新增商品信息失败", merchandise);
        }
    }

    @PutMapping
    public Result updateMerchandise(@RequestBody List MerchandiseList) {
        System.out.println("修改");
        int i = merchandiseMapper.updateMerchandise(MerchandiseList);
        if (i > 0)
            return Result.success("修改商品信息成功");
        else
            return Result.fail(230, "修改商品信息失败", MerchandiseList);
    }

    @DeleteMapping("/{id}")
    public Result deleteOneMerchandise(@PathVariable Long id) {
        System.out.println(id);
        int i = merchandiseMapper.deleteOneMerchandise(id);
        System.out.println("删除的结果是:" + i);
        if (i > 0) {
            return Result.success("删除商品成功");
        } else {
            return Result.fail(240, "删除商品信息用例失败", "删除商品信息失败");
        }
    }

    @DeleteMapping("/ids/{ids}")
    public int deleteMoreMerchandise(@PathVariable List ids) {
        return merchandiseService.deleteMoreMerchandise(ids);
    }


}

单元测试

package com.mrjj.java.controller;

import com.mrjj.java.model.Result;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest
@RunWith(SpringRunner.class)
@Transactional
@Rollback(value=true)
class MerchandiseControllerTest {
    @Resource
    MerchandiseController merchandiseController;

    @Test
    public void testQuery() {
        Result queryData = merchandiseController.listMerchandise();
        System.out.println(queryData);
    }
    @Test
    public void testDelete(){
        Result deleteData = merchandiseController.deleteOneMerchandise(4L);
        System.out.println(deleteData);
    }
    @Test
    public void testDeleteMore(){
        List list1 = new ArrayList<>();
        list1.add(0,5L);
        list1.add(1,4L);
        int deleteMoreData = merchandiseController.deleteMoreMerchandise(list1);
        System.out.println(deleteMoreData);
    }
}

三、前后端交互

配置

大致画了个流程图

后端SpringBoot+前端Vue前后端分离的项目(一)_第2张图片

可以看到在发送请求时,路径以及变了 

后端SpringBoot+前端Vue前后端分离的项目(一)_第3张图片

vite.config.ts文件配置

target是本地服务的地址和端口号

添加的路径/mrjj

server:{
    open:true,
    proxy:{
      '/mrjj': {
        target: 'http://localhost:8888',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/mrjj/, ''),
      },
    }
  }

创建axios实例 

import axios, { type AxiosResponse } from 'axios'
const instance = axios.create({
  baseURL: '/mrjj',
  timeout: 30000,
  headers: { 'Content-Type': 'application/json;charset=utf-8' }
})

instance.interceptors.response.use(
  function (response: AxiosResponse) {
    const { code } = response.data
    if (code === 200) {
      return response.data
    }
  },
  function (error) {
    return Promise.reject(error)
  }
)
export default instance

业务请求

baseURL对应本地服务的接口地址

导出后端服务增删改查方法

import request from '../request'
import axios, { type AxiosPromise } from 'axios'
import type { MrjjMerchandise } from '@/types/merchandises/type'
const instance = axios.create({
  baseURL: '/mrjjMerchandise',
  timeout: 30000,
  headers: { 'Content-Type': 'application/json;charset=utf-8' }
})
export default instance

export function listMerchandiseApi(): AxiosPromise {
  return request({
    url: '/mrjjMerchandise',
    method: 'get'
  })
}

export function addMerchandiseApi(data: MrjjMerchandise) {
  return request({
    url: '/mrjjMerchandise',
    method: 'post',
    data: data
  })
}

export function changeMerchandiseApi(data: MrjjMerchandise) {
  return request({
    url: '/mrjjMerchandise',
    method: 'put',
    data
  })
}

export function deleteMerchandiseApi(ids: string) {
  return request({
    url: '/mrjjMerchandise/ids/' + ids,
    method: 'delete'
  })
}

四、前端实现

环境配置

import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import VXETable from 'vxe-table'
import 'vxe-table/lib/style.css'
import router from './router'
createApp(App).use(router).use(ElementPlus, { locale: zhCn }).use(VXETable).mount('#app')

Main.vue





interface接口

export interface MerchandiseShow{
    merchandiseCategory:string;
    merchandiseType:string;
    merchandiseName:string;
    sumQuantity:number;
    soldQuantity:number;
    [key:string]: any;
    }
    export interface MrjjMerchandise extends MerchandiseShow{
        id:number;
    }
    export interface MrjjMerchandiseEdit extends MrjjMerchandise{
        isEdit:boolean;
    }

五、效果展示

实现了查询、新增、删除、修改的功能

后端SpringBoot+前端Vue前后端分离的项目(一)_第4张图片

后端SpringBoot+前端Vue前后端分离的项目(一)_第5张图片 修改后,数据库里的值也发生了变化

六、总结

通过对数据库表、后端接口设计、前端页面编写,已经实现了一个前后端分离的小项目了,当然还可以进一步完善这个功能,比如新增时可以加上参数校验,可以做一个树形结构的列表,实现数据的拖拽,还可以加上查询、分页、排序等功能,后续博客会对不断进行完善。

你可能感兴趣的:(前端技术,#,SpringBoot,测试技术,前端,后端)