Vue3+Spring Boot技術棧,前端提交混合表單數據(普通字段+文件字段),上傳文件,后端插入數據,將文件保存到數據庫

一、技術棧

1、前端 Vue3 + Element Plus + TypeSprict

2、后端 Spring Boot 3.2.12 + Mybatis Plus

3、模型特點

3.1、表格展示列表數據

3.2、行點擊,彈出對話框

3.3、前端使用 FormData 提交混合表單數據,包含普通字段和文件字段

3.4、文件對應數據庫結構類型為 image

3.5、Spring MVC 注解?@RequestPart、@ModelAttribute

2、應用效果

3、Vue3 前端

對話框表單?QualityFileInfoDialog.vue

<script setup lang="ts" name="QualityFileInfoDialog">
......
// 上傳,防抖
const onUploadClick = debounce(() => {// 模擬點擊元素if (fileInputRef.value) {// 重置以允許重復選擇相同文件fileInputRef.value.value = "";fileInputRef.value.click();}},1000,{ leading: true, trailing: true, maxWait: 1000 }
);// 點擊【上傳】觸發,實現 SQL Server image 類型文件上傳
const handleUpload = async (e: Event) => {// 打印 FormData 表單數據的內容// FormData對象不能直接通過 console.log(formData)輸出完整內容(控制臺僅顯示 FormData {}的抽象表示)// console.log("formData = ", formData);// 使用 Object.fromEntries()將 FormData 轉為普通對象,再通過 console.log 打印完整內容// const data = Object.fromEntries(formData.entries());// console.log(data);// 清空 FormData 表單數據的內容:遍歷刪除所有字段// formData.keys() 返回的迭代器會實時跟蹤 FormData的當前狀態。當調用 delete(key) 后,迭代器的內部指針可能因數據變化而跳過后續鍵。// 先將將迭代器轉為靜態數組,避免動態變化的影響// 使用 Array.from() 將迭代器轉為靜態數組// const keys = Array.from(formData.keys());// 使用 擴展運算符 將迭代器轉為靜態數組// const keys = [...formData.keys()];// for (let key of keys) {//   formData.delete(key);// }// 清空 FormData 表單數據的內容:重新賦值,創建新實例,舊數據被丟棄(完全清空),需要使用 let 聲明對象,不能使用 const 聲明對象formData = new FormData();// 獲取文件對象const input = e.target as HTMLInputElement;if (!input.files?.length) return;const file = input.files[0];// 校驗文件大小if (file.size > 1024 * 1024 * 10) {ElMessage.warning("文件大小不能超過10MB");return;}if (file) {// 獲取文件名的擴展名(后綴)extension.value = getExtension(file.name);// 新增模式if (props.isNew) {if (upperCase(extension.value) === upperCase("pdf")) {// 將文件對象 file 添加到 formData 對象中,uploadFile 需要與后端接口中接收文件的參數名一致,如果不一致,則后端需要指定參數名,如 @RequestPart("uploadFile") MultipartFile fileformData.append("uploadFile", file);} else if (upperCase(extension.value) === upperCase("xls") || upperCase(extension.value) === upperCase("xlsx")) {// 將文件對象 file 添加到 formData 對象中,uploadFile 需要與后端接口中接收文件的參數名一致,如果不一致,則后端需要指定參數名,如 @RequestPart("uploadFile") MultipartFile fileformData.append("uploadFile", file);// 將普通對象 qualityFileObj 的屬性添加到 formData 對象中formData.append("fileNo", qualityFileObj.value.fileNo);formData.append("fileName", qualityFileObj.value.fileName);formData.append("edition", qualityFileObj.value.edition as string);formData.append("orderNo", qualityFileObj.value.orderNo as string);formData.append("issueDept", qualityFileObj.value.issueDept as string);formData.append("issueDate", qualityFileObj.value.issueDate as string);formData.append("smallCategory", qualityFileObj.value.smallCategory as string);formData.append("detailCategory", qualityFileObj.value.detailCategory as string);formData.append("modifyRecord", qualityFileObj.value.modifyRecord as string);formData.append("remark", qualityFileObj.value.remark as string);} else {// 將文件對象 file 添加到 formData 對象中,uploadFile 需要與后端接口中接收文件的參數名一致,如果不一致,則后端需要指定參數名,如 @RequestPart("uploadFile") MultipartFile fileformData.append("uploadFile", file);// 將普通對象 qualityFileObj 轉換為 json 字符串 添加到 formData 對象中formData.append("qualityFile", JSON.stringify(qualityFileObj.value));}}// 查改模式else {if (upperCase(extension.value) === upperCase("pdf")) {// 將文件對象 file 添加到 formData 對象中,uploadFile 需要與后端接口中接收文件的參數名一致,如果不一致,則后端需要指定參數名,如 @RequestPart("uploadFile") MultipartFile fileformData.append("uploadFile", file);// 無需點擊確定,直接發送請求,上傳文件到數據庫,實現 SQL Server image 類型文件上傳await qualityFileUploadFileWithPutService(qualityFileObj.value.fileNo, formData);} else {// 將文件對象 file 添加到 formData 對象中,uploadFile 需要與后端接口中接收文件的參數名一致,如果不一致,則后端需要指定參數名,如 @RequestPart("uploadFile") MultipartFile fileformData.append("uploadFile", file);// 將普通對象 qualityFileObj 的 fileNo 屬性添加到 formData 對象中formData.append("fileNo", qualityFileObj.value.fileNo);// 無需點擊確定,直接發送請求,上傳文件到數據庫,實現 SQL Server image 類型文件上傳await qualityFileUploadFileService(formData);}// 點擊【上傳/重傳】選擇文件后,上傳文件完成,通知父組件更新文件路徑名稱和是否空內容的操作emit("upload-file-complete", file.name);}// 同步更新表單數據qualityFileObj.value.filePathname = file.name;qualityFileObj.value.isNullContent = false;}
};// 確定
const onConfirmClick = async () => {// 檢查if (!check()) {return;}// 新增模式if (props.isNew) {if (upperCase(extension.value) === upperCase("pdf")) {// 發送請求,使用 put 發送請求,發送的數據有:請求體數據(文件數據 file),請求參數數據(普通對象數據 qualityFile)await qualityFileAddAttachUploadFileWithPutService(qualityFileObj.value, formData);} else if (upperCase(extension.value) === upperCase("xls") || upperCase(extension.value) === upperCase("xlsx")) {// 發送請求,使用 patch 發送請求,通過請求體發送表單數據 formData,表單數據,包含的數據有:文件數據(uploadFile)和// 普通對象的屬性數據(fileNo、fileName、edition、orderNo、issueDept、issueDate、smallCategory、detailCategory、modifyRecord、remark)await qualityFileAddAttachUploadFileWithPatchService(formData);} else {// 發送請求,使用 post 發送請求,通過請求體發送表單數據 formData,表單數據,包含的數據有:文件數據(uploadFile)和 普通對象的json字符串數據(qualityFile)await qualityFileAddAttachUploadFileService(formData);}}// 查改模式else {// 兩個對象不相同,需要更新數據;如果兩個對象相同(所有屬性值都相同),不需要更新數據if (!isEqual(props.qualityFileInfo, qualityFileObj.value)) {// 點擊【確定】,確定質量體系文件信息,通知父組件執行相應的操作emit("confirm-quality-file", qualityFileObj.value);}}dialogVisible.value = false;
};
......
</script><template><el-dialogclass="quality-file-dialog"title="基礎信息"width="640px"top="0vh"centerstyle="border-radius: 10px"v-model="dialogVisible":close-on-press-escape="true":close-on-click-modal="false":show-close="true"@close="onCancelClick"><template #default><el-form :model="qualityFileObj" label-width="auto" style="margin: 8px 16px"><el-row :gutter="10"><el-col :span="12"><el-form-item label="序號" label-position="right"><el-input v-model="qualityFileObj.orderNo" clearable /></el-form-item></el-col><el-col :span="12"><el-form-item label="文件編號" label-position="right"><el-input v-model="qualityFileObj.fileNo" clearable :disabled="!props.isNew" /></el-form-item></el-col></el-row><el-row :gutter="10"><el-col :span="24"><el-form-item label="文件名稱" label-position="right"><el-input v-model="qualityFileObj.fileName" clearable /></el-form-item></el-col></el-row><el-row :gutter="10"><el-col :span="12"><el-form-item label="版本號" label-position="right"><el-input v-model="qualityFileObj.edition" clearable /></el-form-item></el-col><el-col :span="12"><el-form-item label="修改記錄" label-position="right"><el-input v-model="qualityFileObj.modifyRecord" clearable /></el-form-item></el-col></el-row><el-row :gutter="10"><el-col :span="12"><el-form-item label="所屬小類" label-position="right"><el-selectv-model="qualityFileObj.smallCategory"placeholder="請選擇"clearable@clear="handleSmallCategoryClear"><el-option v-for="item in fileSmallCategoryList" :label="item.label" :value="item.value" /></el-select></el-form-item></el-col><el-col :span="12"><el-form-item label="所屬類別" label-position="right"><el-selectv-model="qualityFileObj.detailCategory"placeholder="請選擇"clearablefilterabledefault-first-option><el-option v-for="item in fileDetailCategoryList" :label="item.label" :value="item.label" /></el-select></el-form-item></el-col></el-row><el-row :gutter="10"><el-col :span="12"><el-form-item label="發布部門" label-position="right"><el-selectv-model="qualityFileObj.issueDept"placeholder="請選擇"clearablefilterableallow-createdefault-first-option:value-on-clear="``"><el-option v-for="item in departmentList" :label="item.deptName" :value="item.deptName" /></el-select></el-form-item></el-col><el-col :span="12"><el-form-item label="發布日期" label-position="right"><el-date-pickerv-model="qualityFileObj.issueDate"type="date"format="YYYY-MM-DD"value-format="YYYY-MM-DD"clearablestyle="width: 100%" /></el-form-item></el-col></el-row><el-row :gutter="10"><el-col :span="24"><el-form-item label="備注" label-position="right"><el-input v-model="qualityFileObj.remark" clearable /></el-form-item></el-col></el-row><el-row :gutter="10"><el-col :span="15"><el-form-item label="附件" label-position="right"><el-input class="input-readonly" v-model="qualityFileObj.filePathname" readonly /></el-form-item></el-col><el-col :span="9"><el-form-item label="" label-position="right"><BasePreventReClickButton type="primary" plain :loading="false" @click="onUploadClick">{{qualityFileObj.isNullContent ? "上傳" : "重傳"}}</BasePreventReClickButton><BasePreventReClickButton:loading="false":disabled="qualityFileObj.isNullContent"@click="onDownloadClick">下載</BasePreventReClickButton><BasePreventReClickButtontype="danger"plain:loading="false":disabled="qualityFileObj.isNullContent"@click="onClearClick">清除</BasePreventReClickButton><!-- 文件輸入元素,不顯示,通過點擊按鈕【上傳/重傳】執行 onUploadClick,模擬點擊該元素,從而觸發 handleUpload 事件 --><input ref="fileInputRef" type="file" style="display: none" @change="handleUpload" /></el-form-item></el-col></el-row></el-form></template><!-- 模態框底部插槽,就算沒有內容,也要寫一個空的插槽,否則會影響布局 --><template #footer><div class="footer-div"><BasePreventReClickButton class="btn" type="primary" @click="onConfirmClick">確定</BasePreventReClickButton><el-button class="btn" @click="onCancelClick">取消</el-button></div></template></el-dialog>
</template><style scoped lang="scss">
.el-form {margin: 0 15px;
}// 設置等同于disabled的樣式效果,背景色 #f5f7fa,字體顏色 #c0c4cc
// 設置類名為 input-readonly 的元素的背景顏色
.input-readonly :deep(.el-input__wrapper) {background-color: #f5f7fa;
}
// 設置只讀的input的字體顏色,不使用類名,使用類屬性選擇器(.類名[屬性名])
:deep(.el-input__inner[readonly]) {color: #c0c4cc;
}
</style>

qualityFile.ts

import request from "@/utils/request";
import type { IQualityFile, IQualityFileQueryObj } from "@/views/resources/QualityFile/types";/*** 新增質量體系文件信息,附帶上傳文件,使用 put 發送請求,發送的數據有:請求體數據(文件數據 uploadFile),請求參數數據(普通對象數據 qualityFile)* @param qualityFile 質量體系文件信息 {@link IQualityFile}* @param formData 表單數據,包含的數據只有:文件數據(uploadFile) {@link FormData}* @returns*/
export const qualityFileAddAttachUploadFileWithPutService = (qualityFile: IQualityFile, formData: FormData) => {// 發送請求,發送的數據有:請求體數據(文件數據 uploadFile),請求參數數據(普通對象數據 qualityFile)return request.put("/resources/qualityFile/addAttachUploadFile", formData, {params: qualityFile,// 上傳文件,需設置 headers 信息,將"Content-Type"設置為"multipart/form-data"headers: {"Content-Type": "multipart/form-data"}});
};/*** 新增質量體系文件信息,附帶上傳文件,使用 patch 發送請求,通過請求體發送表單數據 formData* @param formData 表單數據,包含的數據有:文件數據(uploadFile)和* 普通對象的屬性數據(fileNo、fileName、edition、orderNo、issueDept、issueDate、smallCategory、detailCategory、modifyRecord、remark) {@link FormData}* @returns*/
export const qualityFileAddAttachUploadFileWithPatchService = (formData: FormData) => {return request.patch("/resources/qualityFile/addAttachUploadFile", formData, {// 上傳文件,需設置 headers 信息,將"Content-Type"設置為"multipart/form-data"headers: {"Content-Type": "multipart/form-data"}});
};/*** 新增質量體系文件信息,附帶上傳文件,使用 post 發送請求,通過請求體發送表單數據 formData* @param formData 表單數據,包含的數據有:文件數據(uploadFile)和 普通對象的json字符串數據(qualityFile) {@link FormData}* @returns*/
export const qualityFileAddAttachUploadFileService = (formData: FormData) => {return request.post("/resources/qualityFile/addAttachUploadFile", formData, {// 上傳文件,需設置 headers 信息,將"Content-Type"設置為"multipart/form-data"headers: {"Content-Type": "multipart/form-data"}});
};

4、Spring Boot 后端

DTO?

QualityFile.java

package com.weiyu.pojo;import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.time.LocalDate;/*** 質量體系文件*/
@Schema(description = "質量體系文件實體")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class QualityFile {@Schema(description = "文件唯一標識 id", example = "1")private Integer id;@Schema(description = "序號", example = "A00")private String orderNo;@Schema(description = "文件編號", example = "CZCDC/QM-2024-A0")private String fileNo;@Schema(description = "文件名稱", example = "質量手冊(封面)")private String fileName;@Schema(description = "版本號", example = "第9版")private String edition;@Schema(description = "修改記錄", example = "第9版第0次修改")private String modifyRecord;@Schema(description = "所屬小類", example = "3003")private String smallCategory;@Schema(description = "所屬類別", example = "第九版")private String detailCategory;@Schema(description = "發布部門", example = "質量管理科")private String issueDept;@Schema(description = "發布日期", example = "2025-08-16")@JsonFormat(pattern = "yyyy-MM-dd")private LocalDate issueDate;@Schema(description = "備注", example = " ")private String remark;@Schema(description = "文件路徑名稱", example = "CZCDC∕QM-2018-B2 4.2 人員vVv+DW=dw.doc")private String filePathname;@Schema(description = "是否空內容", example = "true")private Boolean isNullContent;
}

QualityFileDTO.java

package com.weiyu.pojo;import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.time.LocalDate;/*** 質量體系文件 DTO*/
@Schema(description = "質量體系文件 DTO")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class QualityFileDTO {@Schema(description = "序號", example = "A00")private String orderNo;@Schema(description = "文件編號", example = "CZCDC/QM-2024-A0")private String fileNo;@Schema(description = "文件名稱", example = "質量手冊(封面)")private String fileName;@Schema(description = "版本號", example = "第9版")private String edition;@Schema(description = "修改記錄", example = "第9版第0次修改")private String modifyRecord;@Schema(description = "所屬小類", example = "3003")private String smallCategory;@Schema(description = "所屬類別", example = "第九版")private String detailCategory;@Schema(description = "發布部門", example = "質量管理科")private String issueDept;@Schema(description = "發布日期", example = "2025-08-16")@JsonFormat(pattern = "yyyy-MM-dd")private LocalDate issueDate;@Schema(description = "備注", example = " ")private String remark;
}

控制層?QualityFileController.java

package com.weiyu.controller;import com.alibaba.fastjson.JSON;
import com.weiyu.anno.Debounce;
import com.weiyu.pojo.QualityFile;
import com.weiyu.pojo.QualityFileDTO;
import com.weiyu.pojo.QualityFileQueryDTO;
import com.weiyu.pojo.Result;
import com.weiyu.service.QualityFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.List;/*** 質量體系文件 Controller*/
@RestController
@RequestMapping("/resources/qualityFile")
@Slf4j
public class QualityFileController {@Autowiredprivate QualityFileService qualityFileService;/*** 新增質量體系文件,附帶上傳文件,使用 @PutMapping 接收請求,@ModelAttribute 接收參數* @ ModelAttribute是 Spring MVC 中處理復雜數據綁定和模型管理的核心注解,尤其適合表單操作和共享數據場景,能顯著減少樣板代碼* 將 HTTP 請求參數(如表單字段、查詢參數)自動綁定到 Java 對象的屬性上* 示例說明:* 如果查詢參數有fileNo為A1,表單字段也有fileNo為B2,那么qualityFile中的fileNo為B2,A1,即先獲取表單字段,再獲取查詢參數,中間使用逗號分隔* MultipartFile參數名稱說明:* 因為前端使用 formData.append("uploadFile", file) 用的參數名稱是 uploadFile* 后端這里使用 uploadFile 與前端一致,可以不使用 @RequestPart("uploadFile"),也可以使用* @param qualityFile 質量體系文件 {@link QualityFile}* @param uploadFile 上傳文件 {@link MultipartFile}*/@PutMapping("/addAttachUploadFile")public Result<?> addAttachUploadFile(@ModelAttribute QualityFile qualityFile,MultipartFile uploadFile) throws IOException {log.info("【質量體系文件】,新增附帶上傳文件,使用 @PutMapping 接收請求,@ModelAttribute 接收參數," +"/resources/qualityFile/addAttachUploadFile,qualityFile = {},uploadFile = {}", qualityFile, uploadFile);qualityFileService.addAttachUploadFile(qualityFile, uploadFile);return Result.success();}/*** 新增質量體系文件,附帶上傳文件,使用 @PatchMapping 接收請求,@ModelAttribute 接收參數* @ ModelAttribute是 Spring MVC 中處理復雜數據綁定和模型管理的核心注解,尤其適合表單操作和共享數據場景,能顯著減少樣板代碼* 將 HTTP 請求參數(如表單字段、查詢參數)自動綁定到 Java 對象的屬性上* 示例說明:* 如果查詢參數有fileNo為A1,表單字段也有fileNo為B2,那么qualityFile中的fileNo為B2,A1,即先獲取表單字段,再獲取查詢參數,中間使用逗號分隔* MultipartFile參數名稱說明:* 因為前端使用 formData.append("uploadFile", file) 用的參數名稱是 uploadFile* 后端這里使用 uploadFile 與前端一致,可以不使用 @RequestPart("uploadFile"),也可以使用* @param qualityFileDTO 質量體系文件 DTO {@link QualityFileDTO}* @param uploadFile 上傳文件 {@link MultipartFile}*/@PatchMapping("/addAttachUploadFile")public Result<?> addAttachUploadFile(@ModelAttribute QualityFileDTO qualityFileDTO,MultipartFile uploadFile) throws IOException {log.info("【質量體系文件】,新增附帶上傳文件,使用 @PatchMapping 接收請求,@ModelAttribute 接收參數," +"/resources/qualityFile/addAttachUploadFile,qualityFileDTO = {},uploadFile = {}", qualityFileDTO, uploadFile);QualityFile qualityFile = new QualityFile();qualityFile.setFileNo(qualityFileDTO.getFileNo());qualityFile.setFileName(qualityFileDTO.getFileName());qualityFile.setEdition(qualityFileDTO.getEdition());qualityFile.setOrderNo(qualityFileDTO.getOrderNo());qualityFile.setIssueDept(qualityFileDTO.getIssueDept());qualityFile.setIssueDate(qualityFileDTO.getIssueDate());qualityFile.setSmallCategory(qualityFileDTO.getSmallCategory());qualityFile.setDetailCategory(qualityFileDTO.getDetailCategory());qualityFile.setModifyRecord(qualityFileDTO.getModifyRecord());qualityFile.setRemark(qualityFileDTO.getRemark());qualityFileService.addAttachUploadFile(qualityFile, uploadFile);return Result.success();}/*** 新增質量體系文件,附帶上傳文件,使用 @PostMapping 接收請求,@RequestPart 接收參數* @ RequestPart是 Spring MVC 中處理 multipart 請求的靈活工具,尤其適合文件與結構化數據混合提交的場景,簡化了數據綁定與異常處理* MultipartFile參數名稱說明:* 因為前端使用 formData.append("uploadFile", file) 用的參數名稱是 uploadFile* 后端這里使用 uploadFile 與前端一致,可以使用 @RequestPart("uploadFile"),也可以不使用* String參數名稱說明:* 因為前端使用 formData.append("qualityFile", JSON.stringify(qualityFileObj.value)) 用的參數名稱是 qualityFile* 后端這里使用 qualityFileJsonString 與前端不一致,必須使用 @RequestPart("qualityFile") 映射參數名稱* @param qualityFileJsonString 質量體系文件json字符串* @param uploadFile 上傳文件 {@link MultipartFile}*/@PostMapping("/addAttachUploadFile")public Result<?> addAttachUploadFile(@RequestPart("qualityFile") String qualityFileJsonString,@RequestPart("uploadFile") MultipartFile uploadFile) throws IOException {log.info("【質量體系文件】,新增附帶上傳文件,使用 @PostMapping 接收請求,@RequestPart 接收參數," +"/resources/qualityFile/addAttachUploadFile,qualityFileJsonString = {},uploadFile = {}",qualityFileJsonString, uploadFile);// json字符串 轉換成 java對象(QualityFile)QualityFile qualityFile = JSON.parseObject(qualityFileJsonString, QualityFile.class);qualityFileService.addAttachUploadFile(qualityFile, uploadFile);return Result.success();}
}

服務層?QualityFileServiceImpl.java

package com.weiyu.service.impl;import com.weiyu.mapper.QualityFileMapper;
import com.weiyu.pojo.FileData;
import com.weiyu.pojo.QualityFile;
import com.weiyu.pojo.QualityFileQueryDTO;
import com.weiyu.service.QualityFileService;
import com.weiyu.utils.FileDownloadUtil;
import jakarta.validation.constraints.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/*** 質量體系文件 Service 接口實現*/
@Service
public class QualityFileServiceImpl implements QualityFileService {@Autowiredprivate QualityFileMapper qualityFileMapper;/*** 查詢質量體系文件列表** @param queryDTO 查詢 DTO* @return 質量體系文件列表*/@Overridepublic List<QualityFile> query(QualityFileQueryDTO queryDTO) {if (queryDTO == null) return new ArrayList<>();return qualityFileMapper.select(queryDTO);}/*** 新增質量體系文件** @param qualityFile 質量體系文件*/@Overridepublic void add(QualityFile qualityFile) {qualityFileMapper.insert(qualityFile);}/*** 上傳質量體系文件** @param fileNo 文件編號* @param uploadFile 上傳文件*/@Overridepublic void uploadFile(String fileNo, MultipartFile uploadFile) throws IOException {FileData fileData = new FileData();fileData.setFileName(uploadFile.getOriginalFilename());fileData.setFileContent(uploadFile.getBytes());// todo: 如果是大文件(超過10MB)保存到文件系統,數據庫只保存文件路徑;否則保存到數據庫// 保存文件到數據庫qualityFileMapper.saveFile(fileNo, fileData);}/*** 新增質量體系文件,附帶上傳文件** @param qualityFile 質量體系文件* @param uploadFile 上傳文件*/@Override@Transactionalpublic void addAttachUploadFile(QualityFile qualityFile, MultipartFile uploadFile) throws IOException {// 新增質量體系文件add(qualityFile);// 上傳質量體系文件uploadFile(qualityFile.getFileNo(), uploadFile);}
}

Mapper?QualityFileMapper.java

package com.weiyu.mapper;import com.weiyu.pojo.FileData;
import com.weiyu.pojo.QualityFile;
import com.weiyu.pojo.QualityFileQueryDTO;
import org.apache.ibatis.annotations.Mapper;import java.util.List;/*** 質量體系文件 Mapper*/
@Mapper
public interface QualityFileMapper {/*** 查詢質量體系文件列表* @param queryDTO 查詢 DTO* @return 質量體系文件列表*/List<QualityFile> select(QualityFileQueryDTO queryDTO);/*** 新增質量體系文件* @param qualityFile 質量體系文件*/void insert(QualityFile qualityFile);/*** 保存質量體系文件數據到數據庫* @param fileNo 文件編號* @param fileData 上傳文件*/void saveFile(String fileNo, FileData fileData);
}

數據庫sql操作?QualityFileMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.weiyu.mapper.QualityFileMapper"><!--mssql--><!-- 查詢質量體系文件列表 --><select id="select" resultType="com.weiyu.pojo.QualityFile">selectCfm_OrderID as orderNo, Cfm_ID as fileNo, Cfm_Name as fileName, Cfm_Edition as edition,Cfm_ModifyRecord as modifyRecord, Cfm_SmallType as smallCategory, Cfm_SampleType as detailCategory,Cfm_Dept as issueDept, Cfm_IssueDate as issueDate, Cfm_Memo as remark,cfm_ContentFileName as filePathname, cfm_ContentIsNull as isNullContentfrom ControledFileMain<where>Cfm_BigType = '3'<if test="fileNo != null and fileNo != ''">and Cfm_ID like '%' + #{fileNo} + '%'</if><if test="fileName != null and fileName != ''">and Cfm_Name like '%' + #{fileName} + '%'</if></where>order by Cfm_SmallType, Cfm_ID</select><!-- 新增質量體系文件 --><insert id="insert">insert into ControledFileMain(Cfm_BigType, Cfm_OrderID, Cfm_ID, Cfm_Name, Cfm_Edition,Cfm_ModifyRecord, Cfm_SmallType, Cfm_SampleType,Cfm_Dept, Cfm_IssueDate, Cfm_Memo)values ('3', #{orderNo}, #{fileNo}, #{fileName}, #{edition},#{modifyRecord}, #{smallCategory}, #{detailCategory},#{issueDept}, #{issueDate}, #{remark})</insert><!-- 保存質量體系文件數據到數據庫 --><update id="saveFile">update ControledFileMain setcfm_ContentFileName = #{fileData.fileName}, cfm_Content = #{fileData.fileContent}, cfm_ContentIsNull = 0where Cfm_BigType = '3' and Cfm_ID = #{fileNo}</update>
</mapper>

5、數據庫表結構(sql server)

CREATE TABLE [dbo].[ControledFileMain]([Cfm_ID] [varchar](30) NOT NULL,[Cfm_Name] [varchar](200) NULL,[Cfm_BigType] [varchar](10) NOT NULL,[Cfm_SmallType] [varchar](10) NULL,[Cfm_Dept] [varchar](50) NULL,[Cfm_Memo] [varchar](100) NULL,[Cfm_ModifyRecord] [varchar](128) NULL,[Cfm_Edition] [varchar](50) NULL,[Cfm_IssueDate] [datetime] NULL,[Cfm_SampleType] [varchar](50) NULL,[Cfm_StandardType] [int] NULL,[Cfm_OrderID] [varchar](10) NULL,[Cfm_Holder] [varchar](50) NULL,[cfm_Content] [image] NULL,[cfm_ContentIsNull] [bit] NULL,[cfm_ContentFileName] [varchar](255) NULL,CONSTRAINT [PK_ControledFileMain] PRIMARY KEY CLUSTERED 
([Cfm_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]GO

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/94155.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/94155.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/94155.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Qt開發】Qt的背景介紹(四)

目錄 1 -> Qt Hello World 程序 1.1 -> 使用“按鈕”實現 1.1.1 -> 純代碼方式實現 1.1.2 -> 可視化操作實現 1.2 -> 使用“標簽”實現 1.2.1 -> 純代碼方式實現 1.2.2 -> 可視化操作實現 2 -> 項目文件解析 2.1 -> .pro文件解析 2.2 -&g…

Linux驅動開發筆記(六)——pinctrl GPIO

開發板&#xff1a;imx6ull mini 虛擬機&#xff1a;VMware17 ubuntu&#xff1a;ubuntu20.04 視頻&#xff1a;第8.1講 pinctrl和gpio子系統試驗-pincrl子系統詳解_嗶哩嗶哩_bilibili 文檔&#xff1a;《【正點原子】I.MX6U嵌入式Linux驅動開發指南.pdf》四十五章 這一章…

SpringBoot 快速上手:從環境搭建到 HelloWorld 實戰

在 Java 開發領域&#xff0c;Spring 框架占據著舉足輕重的地位&#xff0c;但它復雜的配置曾讓不少開發者望而卻步。SpringBoot 的出現&#xff0c;如同為 Spring 框架裝上了 “加速器”&#xff0c;以 “約定大于配置” 的理念簡化了開發流程。本文將從環境準備、Maven 配置入…

圖、最小生成樹與最短路徑

目錄 并查集 并查集實現 圖 概念 圖的存儲結構 鄰接矩陣 鄰接表 無向圖 有向圖 圖的遍歷 廣度優先遍歷 深度優先遍歷 最小生成樹 Kruskal算法&#xff08;克魯斯卡爾算法&#xff09; Prim算法&#xff08;普利姆算法&#xff09; 最短路徑 單源最短路徑--Dij…

互聯網電商新生態:開源AI智能名片、鏈動2+1模式與S2B2C商城小程序的融合賦能

摘要&#xff1a;本文聚焦互聯網電商領域&#xff0c;探討在當下直播電商蓬勃發展的背景下&#xff0c;開源AI智能名片、鏈動21模式以及S2B2C商城小程序如何相互融合&#xff0c;為創業者、企業和淘寶主播IP等電商參與者帶來新的發展機遇。通過分析各要素的特點與優勢&#xff…

企業車輛|基于SprinBoot+vue的企業車輛管理系統(源碼+數據庫+文檔)

企業車輛管理系統 基于SprinBootvue的企業車輛管理系統 一、前言 二、系統設計 三、系統功能設計 系統功能實現 后臺模塊實現 管理員模塊實現 駕駛員模塊實現 四、數據庫設計 五、核心代碼 六、論文參考 七、最新計算機畢設選題推薦 八、源碼獲取&#xff1a; 博…

自學嵌入式第二十五天:數據結構-隊列、樹

一、隊列隊列是只允許一段進行插入&#xff0c;另一端進行刪除操作的線性表&#xff1b;允許插入的一端叫隊尾&#xff0c;允許刪除的一端叫對頭&#xff1b;先進先出&#xff1b;用于解決速度不匹配&#xff08;例如一快一慢&#xff09;&#xff0c;做緩沖用&#xff1b;二、…

MySQL索引原理與優化全解析

1、MySQL索引是什么&#xff1f; 在關系數據庫中&#xff0c;索引是一種單獨的、物理的對數據庫表中一列或多列的值進行排序的一種存儲結構&#xff0c;它是某個表中一列或若干列值的集合和相應的指向表中物理標志這些值的數據頁的邏輯指針清單。索引的作用相當于圖書的目錄&a…

模型對話狀態管理方法詳解

模型對話狀態管理方法詳解 目錄 簡介手動管理對話狀態構建對話歷史追加響應內容 API 支持的自動化對話狀態管理使用 previous_response_id 鏈接話輪 Token 及上下文窗口管理上下文窗口定義與限制Token 計數與工具 安全與合規注意事項結語1. 簡介 在多輪對話場景中&#xff0c;合…

GPT-5 上線風波深度復盤:從口碑兩極到策略調整,OpenAI 的變與不變

摘要&#xff1a; 近日&#xff0c;備受矚目的 GPT-5 正式上線&#xff0c;卻意外地在社區引發了兩極化爭議。面對技術故障與用戶質疑&#xff0c;OpenAI 迅速推出一系列補救措施。本文將深度復盤此次發布風波&#xff0c;解析其背后的技術挑戰與應對策略&#xff0c;并探討這一…

【Android】使用FragmentManager動態添加片段

三三要成為安卓糕手 上一篇文章&#xff0c;我們是在xml中靜態添加fragment&#xff0c;但是一些修改或者其他事情是做不了的&#xff1b; 本章我們達成在java代碼中靈活添加、刪除、替換fragment操作 一&#xff1a;核心代碼展示 簡單做一個這種頁面public class FragmentActi…

MiniOB環境部署開發(使用開源學堂)

整體思路&#xff1a; 1.使用開源學堂在線編程環境開發MiniOB編譯環境 2.使用vscode進行代碼調試和開發以及上傳到倉庫 MiniOB源碼&#xff1a;https://github.com/oceanbase/miniob MiniOB文檔&#xff1a;MiniOB 介紹 - MiniOB 數據庫大賽官網&#xff1a;OceanBase 社區…

09_常用內置模塊進階

第9課&#xff1a;常用內置模塊進階 課程目標 深入學習Python常用內置模塊掌握collections、itertools、functools等模塊學習json、csv、pickle等數據處理模塊 1. collections模塊 1.1 Counter類 from collections import Counter# 統計元素出現次數 text "hello world p…

? Ranger 基礎命令與功能詳解

&#x1f4cc; 1. Ranger簡介 Ranger&#xff08;游俠&#xff09;是一款 Linux 專用的 指令式文件管理器&#xff0c;其操作風格類似 Vim&#xff0c;通過輸入指令即可完成目錄跳轉、文件編輯、移動、復制等操作。 相比于 mc&#xff08;Midnight Commander&#xff09;&…

CUDA安裝教程(包括cuDNN的教程)一個博客帶你了解所有問題

前言 windows10 版本安裝 CUDA &#xff0c;首先需要下載兩個安裝包 CUDA toolkit&#xff08;toolkit就是指工具包&#xff09;cuDNN 注&#xff1a;cuDNN 是用于配置深度學習使用 官方教程 CUDA&#xff1a;Installation Guide Windows :: CUDA Toolkit Documentation …

ArkTS 語言全方位解析:鴻蒙生態開發新選擇

在鴻蒙生態蓬勃發展的當下&#xff0c;一款高效、健壯的開發語言成為開發者的迫切需求。ArkTS 語言應運而生&#xff0c;作為鴻蒙生態的核心應用開發語言&#xff0c;它在 TypeScript&#xff08;簡稱 TS&#xff09;基礎上進行創新擴展&#xff0c;為開發者打造高性能、易維護…

JavaScript性能優化實戰:從瓶頸識別到極致體驗

文章目錄JavaScript性能優化實戰&#xff1a;從瓶頸識別到極致體驗1. 引言&#xff1a;為什么JavaScript性能至關重要1.1 性能對用戶體驗的影響1.2 JavaScript性能瓶頸的多樣性2. JavaScript內存管理優化2.1 JavaScript內存模型詳解2.2 垃圾回收機制與優化策略2.3 內存分析實戰…

批量歸一化:不將參數上傳到中心服務器,那服務器怎么進行聚合?

聯邦批量歸一化&#xff08;FedBN&#xff09; 是一種聯邦學習客戶端本地模型優化算法。它的核心思想是&#xff1a;在聯邦學習的客戶端本地訓練過程中&#xff0c;保留并獨立更新批量歸一化層&#xff08;Batch Normalization, BN&#xff09;的參數&#xff0c;而不將這些參數…

Qt中使用MySQL數據庫

一、MySQL 入門 核心概念 在 QT 中操作數據庫,主要使用兩個模塊: QSqlDatabase:代表一個數據庫連接。 QSqlQuery:用于執行 SQL 語句(如 SELECT, INSERT, UPDATE, DELETE)并處理結果。 環境準備 在編寫代碼之前,你需要確保系統已具備以下條件: 1. 安裝 MySQL 從 M…

Android - 統一資源標識符 Uri

一、概念URI&#xff08;Uniform Resource Identifier&#xff09;統一資源標識符&#xff0c;用于標識資源的字符串&#xff08;如圖片、網頁、文件、應用等&#xff09;。1.1 與 URL 的區別URL&#xff08;統一資源定位符&#xff09;是 URI&#xff08;統一資源標識符&#…