成都 网站改版,佛山 详情公布,网站建设电话邀约话术,iis网站下载前言#xff1a;后端使用SpringBoot框架#xff0c;前端使用Vue框架#xff0c;做一个前后端分离的小项目#xff0c;需求#xff1a;实现一个表格#xff0c;具备新增、删除、修改的功能。 目录
一、数据库表的设计
二、后端实现
环境配置
数据处理-增删改查
model… 前言后端使用SpringBoot框架前端使用Vue框架做一个前后端分离的小项目需求实现一个表格具备新增、删除、修改的功能。 目录
一、数据库表的设计
二、后端实现
环境配置
数据处理-增删改查
model层
mapper层
XML配置
Service层
controller层
单元测试
三、前后端交互
配置
vite.config.ts文件配置
创建axios实例
业务请求
四、前端实现
环境配置
Main.vue
interface接口
五、效果展示
六、总结 一、数据库表的设计
设计了一个merchandise表id是编号唯一的类型为intcategory是一级类别type是二级类别name是商品的名称sum_quantity是总数量sold_quantity是售卖的数量。 数据库里的字段名使用的是下划线连接在java中变量命名一般使用驼峰式需要在application.properties文件中进行配置
mybatis.configuration.map-underscore-to-camel-casetrue
二、后端实现
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;
}
环境配置
引入需要的依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-tomcat/artifactIdscopeprovided/scope/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion2.2.2/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.19/version/dependencydependencygroupIdorg.mybatis.generator/groupIdartifactIdmybatis-generator-core/artifactIdversion1.4.0/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-thymeleaf/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependencydependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.5.3/version/dependency 完成application.properties文件的配置连接mysql
server.port8888
spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver
spring.datasource.urljdbc:mysql://localhost:3306/mrjj?allowMultiQueriestrueuseUnicodetruecharacterEncodingutf8serverTimezoneUTC
spring.datasource.usernameroot
spring.datasource.password123456
mybatis.mapper-locationsclasspath:/mapper/*.xml
mybatis.configuration.map-underscore-to-camel-casetrue
数据处理-增删改查
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 ResultT {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 T ResultT success(T data) {ResultT result new Result(data);result.setCode(200);result.setMsg(请求成功);return result;}public static T ResultT success(String msg, T data) {ResultT result new Result(data);result.setCode(200);result.setMsg(msg);return result;}public static T Result fail(int code, String message, T data) {ResultT 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)ListMerchandise 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(ListMerchandise merchandise);
}XML配置
注意
要配置上allowMultiQueriestrue才能批量处理这个问题查了蛮久的
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
!-- namespace:填写映射当前的Mapper接口所有的增删改查的参数和返回值类型就可以直接填写缩写不区分大小写直接通过方法名去找类型--
mapper namespacecom.mrjj.java.mapper.MerchandiseMapper!-- id 对应的是mapper.CaseMapper里的方法名--delete iddeleteMoreMerchandisedelete from merchandisewhereforeach collectionlist separator, itemitem openid in ( close)#{item}/foreach/where/deleteupdate idupdateMerchandise parameterTypejava.util.Listforeach collectionlist itemitem separator;update merchandisesetif test#{item.merchandiseCategory}!nullmerchandise_category#{item.merchandiseCategory},/ifif test#{item.merchandiseType}!nullmerchandise_type#{item.merchandiseType},/ifif test#{item.merchandiseName}!nullmerchandise_name#{item.merchandiseName},/ifif test#{item.sumQuantity}!nullsum_quantity#{item.sumQuantity},/ifif test#{item.soldQuantity}!nullsold_quantity#{item.soldQuantity},/if/setwhere id#{item.id}/foreach/update
/mapper
Service层
package com.mrjj.java.service;import java.util.List;public interface MerchandiseService {int deleteMoreMerchandise(ListLong 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 {ResourceMerchandiseMapper merchandiseMapper;Overridepublic int deleteMoreMerchandise(ListLong 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 {ResourceMerchandiseMapper merchandiseMapper;ResourceMerchandiseService merchandiseService;GetMappingpublic Result listMerchandise() {ListMerchandise Marchandise merchandiseMapper.getMerchandise();System.out.println(查到的商品是 Marchandise);return Result.success(Marchandise);}GetMapping(/view)public ModelAndView showMerchandise() {ModelAndView MarchandiseView new ModelAndView();ListMerchandise Marchandise merchandiseMapper.getMerchandise();MarchandiseView.addObject(mrjjMarchandiseView, Marchandise);MarchandiseView.setViewName(mrjjMarchandise);return MarchandiseView;}PostMappingpublic Result addMerchandise(RequestBody Merchandise merchandise) {int i merchandiseMapper.addMerchandise(merchandise);if (i 0) {return Result.success(merchandise);} else {return Result.fail(210, 新增商品信息失败, merchandise);}}PutMappingpublic Result updateMerchandise(RequestBody ListMerchandise MerchandiseList) {System.out.println(修改);int i merchandiseMapper.updateMerchandise(MerchandiseList);if (i 0)return Result.success(修改商品信息成功);elsereturn 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 ListLong 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(valuetrue)
class MerchandiseControllerTest {ResourceMerchandiseController merchandiseController;Testpublic void testQuery() {Result queryData merchandiseController.listMerchandise();System.out.println(queryData);}Testpublic void testDelete(){Result deleteData merchandiseController.deleteOneMerchandise(4L);System.out.println(deleteData);}Testpublic void testDeleteMore(){ListLong list1 new ArrayList();list1.add(0,5L);list1.add(1,4L);int deleteMoreData merchandiseController.deleteMoreMerchandise(list1);System.out.println(deleteMoreData);}
}
三、前后端交互
配置
大致画了个流程图 可以看到在发送请求时路径以及变了 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;charsetutf-8 }
})instance.interceptors.response.use(function (response: AxiosResponse) {const { code } response.dataif (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;charsetutf-8 }
})
export default instanceexport function listMerchandiseApi(): AxiosPromiseMrjjMerchandise[] {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
templateel-dialog title添加商品 v-modelisAdd width30%el-form :modelnewMerchandise refform label-width80px :inlinefalse sizenormalel-form-item label一级分类el-input v-modelnewMerchandise.merchandiseCategory/el-input/el-form-itemel-form-item label二级分类el-input v-modelnewMerchandise.merchandiseType/el-input/el-form-itemel-form-item label商品名称el-input v-modelnewMerchandise.merchandiseName/el-input/el-form-itemel-form-item label总数量el-input v-modelnewMerchandise.sumQuantity/el-input/el-form-itemel-form-item label已售出el-input v-modelnewMerchandise.soldQuantity/el-input/el-form-item/el-formtemplate #footerspanel-button clickcloseAdder取消/el-buttonel-button typeprimary clickaddMerchandise确认/el-button/span/template/el-dialogel-card shadowalways :body-style{ padding: 0px }template #headerdivel-row :gutter16el-col :span4 classcase-titlespan商品信息/span/el-colel-col :span4 :offset16el-button typesuccess clickopenMerchandiseAddel-iconPlus //el-icon 新增商品/el-button/el-colel-button typeprimary sizedefault clickchangeMerchandiseel-iconPromotion //el-icon提交修改/el-buttonel-buttontypedangersizedefaultclickdeleteChecked:disablecheckedMoreIds?.length 0el-iconDelete //el-icon删除选中商品/el-button/el-row/div/templatevxe-tablerefmerchandiseTablebordershow-header-overflowshow-overflowcheckbox-allselectMoreMerchandiseEvent:column-config{ resizable: true }:dataMerchandises:edit-config{ trigger: dblclick, mode: cell }vxe-column typecheckbox width60/vxe-columnvxe-columnfieldmerchandiseCategorytitle一级类别:edit-render{ name: input }/vxe-columnvxe-columnfieldmerchandiseTypetitle二级类别:edit-render{ name: input }/vxe-columnvxe-columnfieldmerchandiseNametitle商品名称:edit-render{ name: input }/vxe-columnvxe-column fieldsumQuantity title总数量 :edit-render{ name: input }/vxe-columnvxe-column fieldsoldQuantity title已售出 :edit-render{ name: input }/vxe-columnvxe-column field title操作template #default{ row }el-button typeprimary sizedefault clickdeleteMerchandise(row) :iconDelete删除/el-button/template/vxe-column/vxe-table/el-card
/templatescript setup langts
import { Delete, Promotion, Plus } from element-plus/icons-vue
import type { VxeTableInstance } from vxe-table
import type { MerchandiseShow, MrjjMerchandise } from ../types/merchandises/type
import {listMerchandiseApi,addMerchandiseApi,deleteMerchandiseApi,changeMerchandiseApi
} from ../api/merchandise
import { ref, onMounted, reactive, computed } from vue
onMounted(() {listMerchandises()
})
let isAdd ref(false)
let isEdit ref(false)
let merchandiseTable refVxeTableInstance()
let Merchandises ref([])
let emptyMerchandise {merchandiseCategory: ,merchandiseType: ,merchandiseName: ,sumQuantity: ,soldQuantity:
}
let newMerchandise reactiveMerchandiseShow({merchandiseCategory: ,merchandiseType: ,merchandiseName: ,sumQuantity: ,soldQuantity:
})
const checkedMoreIds computed(() {return merchandiseTable.value?.getCheckboxRecords().map((MrjjMerchandise) {return MrjjMerchandise.id})
})
function closeAdder() {isAdd.value false
}
function openMerchandiseAdd() {isAdd.value true
}
function listMerchandises() {console.log(正在发送请求)listMerchandiseApi().then(({ data }) {Merchandises.value dataconsole.log(获取到的用例信息是, Merchandises)}).catch((error: any) {console.log(报错了, error)})
}
function addMerchandise() {let lastId Merchandises.value.length 0 ? Merchandises.value[Merchandises.value.length - 1].id : -1let addMerchandise: MrjjMerchandise { ...newMerchandise, id: 0 }addMerchandise.id lastId 1console.log(要新增的商品是, addMerchandise)addMerchandiseApi(addMerchandise).then(() {listMerchandises()})closeAdder()
}function deleteMerchandise(deleteOneMerchandise: MrjjMerchandise) {deleteMerchandiseApi(deleteOneMerchandise.id ).then(() {listMerchandises()})
}
function deleteChecked() {console.log(选中的id是, checkedMoreIds.value?.toString())deleteMerchandiseApi(checkedMoreIds.value!.toString()).then(() {listMerchandises()})
}
function changeMerchandise() {changeMerchandiseApi(Merchandises.value).then(() {listMerchandises()})
}
/scriptstyle scoped
.case-title {font-size: large;color: red;font-weight: bolder;
}
/style
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;}
五、效果展示
实现了查询、新增、删除、修改的功能 修改后数据库里的值也发生了变化 六、总结
通过对数据库表、后端接口设计、前端页面编写已经实现了一个前后端分离的小项目了当然还可以进一步完善这个功能比如新增时可以加上参数校验可以做一个树形结构的列表实现数据的拖拽还可以加上查询、分页、排序等功能后续博客会对不断进行完善。