1.?分布式文件系統
1.1?什么是分布式文件系統
????????文件系統是負責管理和存儲文件的系統軟件,操作系統通過文件系統提供的接口去存取文件,用戶通過操作系統訪問磁盤上的文件。
????????下圖指示了文件系統所處的位置:
常見的文件系統:FAT16/FAT32、NTFS、HFS、UFS、APFS、XFS、Ext4等 。
????????現在有個問題,一此短視頻平臺擁有大量的視頻、圖片,這些視頻文件、圖片文件該如何存儲呢?如何存儲可以滿足互聯網上海量用戶的瀏覽。
????????通過分布式文件系統實現海量用戶查閱海量文件
好處:
1、一臺計算機的文件系統處理能力擴充到多臺計算機同時處理。
2、一臺計算機掛了還有另外副本計算機提供數據。
3、每臺計算機可以放在不同的地域,這樣用戶就可以就近訪問,提高訪問速度。
1.2 MinIo
1.2.1 介紹
????????本項目采用MinIO構建分布式文件系統,MinIO 是一個非常輕量的服務,可以很簡單的和其他應用的結合使用,它兼容亞馬遜 S3 云存儲服務接口,非常適合于存儲大容量非結構化的數據,例如圖片、視頻、日志文件、備份數據和容器/虛擬機鏡像等。
????????它一大特點就是輕量,使用簡單,功能強大,支持各種平臺,單個文件最大5TB,兼容 Amazon S3接口,提供了 Java、Python、GO等多版本SDK支持。
官網:https://min.io
中文:https://www.minio.org.cn/,http://docs.minio.org.cn/docs/
????????在大數據領域,通常的設計理念都是無中心和分布式。Minio分布式模式可以幫助你搭建一個高可用的對象存儲服務,你可以使用這些存儲設備,而不用考慮其真實物理位置。
????????它將分布在不同服務器上的多塊硬盤組成一個對象存儲服務。由于硬盤分布在不同的節點上,分布式Minio避免了單點故障。如下圖:
1.2.2?測試Docker環境
開發階段和生產階段統一使用Docker下的MINIO。
????????虛擬機中已安裝了MinIO的鏡像和容器,執行sh /data/soft /restart.sh啟動Docker下的MinIO
啟動完成登錄MinIO查看是否正常。訪問 http://192.168.101.65:9000,賬號和密碼為:minioadmin / minioadmin
本項目創建兩個buckets:
mediafiles: 普通文件
video:視頻文件
1.2.4 SDK
1)上傳文件
MinIO提供多個語言版本SDK的支持,下邊找到java版本的文檔:
地址:https://docs.min.io/docs/java-client-quickstart-guide.html
-
media-service工程中導入依賴
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.4.3</version>
</dependency>
<dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.8.1</version>
</dependency>
參數說明:
需要三個參數才能連接到minio服務。
參數 | 說明 |
Endpoint | 對象存儲服務的URL |
Access Key | Access key就像用戶ID,可以唯一標識你的賬戶。 |
Secret Key | Secret key是你賬戶的密碼。 |
- 創建一個桶進行測試
-
在xuecheng-plus-media-service工程 的test下編寫測試代碼如下
package com.xuecheng.media;import com.j256.simplemagic.ContentInfo;
import com.j256.simplemagic.ContentInfoUtil;
import io.minio.*;
import io.minio.errors.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;/*** 測試 minio*/
public class MinioTest {MinioClient minioClient =MinioClient.builder().endpoint("http://192.168.101.65:9000").credentials("minioadmin", "minioadmin").build();@Testpublic void test_upload() throws Exception {//通過擴展名得到媒體資源類型 mimeType//根據擴展名取出mimeTypeContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(".jpg");String mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;//通用mimeType,字節流if(extensionMatch!=null){mimeType = extensionMatch.getMimeType();}//上傳文件的參數信息UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder().bucket("testbucket")//桶.filename("D:\\學習\\images\\3.jpg") //指定本地文件路徑
// .object("3.jpg")//對象名 在桶下存儲該文件.object("test/01/3.jpg")//對象名 放在子目錄下.contentType(mimeType)//設置媒體文件類型.build();//上傳文件minioClient.uploadObject(uploadObjectArgs);}//刪除文件@Testpublic void test_delete() throws Exception {//RemoveObjectArgsRemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket("testbucket").object("3.jpg").build();//刪除文件minioClient.removeObject(removeObjectArgs);}//查詢文件 從minio中下載@Testpublic void test_getFile() throws Exception {GetObjectArgs getObjectArgs = GetObjectArgs.builder().bucket("testbucket").object("test/01/1.mp4").build();//查詢遠程服務獲取到一個流對象FilterInputStream inputStream = minioClient.getObject(getObjectArgs);//指定輸出流FileOutputStream outputStream = new FileOutputStream(new File("D:\\develop\\upload\\1a.mp4"));IOUtils.copy(inputStream,outputStream);//校驗文件的完整性對文件的內容進行md5FileInputStream fileInputStream1 = new FileInputStream(new File("D:\\develop\\upload\\1.mp4"));String source_md5 = DigestUtils.md5Hex(fileInputStream1);FileInputStream fileInputStream = new FileInputStream(new File("D:\\develop\\upload\\1a.mp4"));String local_md5 = DigestUtils.md5Hex(fileInputStream);if(source_md5.equals(local_md5)){System.out.println("下載成功");}}}
2. 上傳圖片
2.1 需求分析
2.1.1 業務流程
????????課程圖片是宣傳課程非常重要的信息,在新增課程界面上傳課程圖片,也可以修改課程圖片。
上傳課程圖片總體上包括兩部分:
- 上傳課程圖片前端請求媒資管理服務將文件上傳至分布式文件系統,并且在媒資管理數據庫保存文件信息。
- 上傳圖片成功保存圖片地址到課程基本信息表中。
詳細流程如下:
- 前端進入上傳圖片界面
- 上傳圖片,請求媒資管理服務。
- 媒資管理服務將圖片文件存儲在MinIO。
- 媒資管理記錄文件信息到數據庫。
- 前端請求內容管理服務保存課程信息,在內容管理數據庫保存圖片地址。
2.1.2 數據模型
????????涉及到的數據表有:課程信息表中的圖片字段、媒資數據庫的文件表,下邊主要看媒資數據庫的文件表。
2.2 準備
????????首先在minio配置bucket,bucket名稱為:mediafiles,并設置bucket的權限為公開
????????在nacos配置中minio的相關信息,進入media-service-dev.yaml:
minio:endpoint: http://192.168.101.65:9000accessKey: minioadminsecretKey: minioadminbucket:files: mediafilesvideofiles: video
????????在media-service工程編寫minio的配置類
package com.xuecheng.media.config;import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** minio配置類*/
@Configuration
public class MinioConfig {@Value("${minio.endpoint}")private String endpoint;@Value("${minio.accessKey}")private String accessKey;@Value("${minio.secretKey}")private String secretKey;@Beanpublic MinioClient minioClient() {// 創建Minio客戶端實例,使用endpoint、accessKey和secretKey進行配置MinioClient minioClient =MinioClient.builder().endpoint(endpoint) // 設置Minio服務地址.credentials(accessKey, secretKey) // 設置訪問憑證.build(); // 構建客戶端實例return minioClient; // 返回構建好的Minio客戶端}}
2.3 接口定義
????????根據需求分析,下邊進行接口定義,此接口定義為一個通用的上傳文件接口,可以上傳圖片或其它文件。
請求地址:/media/upload/coursefile
請求內容:Content-Type: multipart/form-data;
form-data; name="filedata"; filename="具體的文件名稱"
響應參數:文件信息,如下
{"id": "a16da7a132559daf9e1193166b3e7f52","companyId": 1232141425,"companyName": null,"filename": "1.jpg","fileType": "001001","tags": "","bucket": "/testbucket/2022/09/12/a16da7a132559daf9e1193166b3e7f52.jpg","fileId": "a16da7a132559daf9e1193166b3e7f52","url": "/testbucket/2022/09/12/a16da7a132559daf9e1193166b3e7f52.jpg","timelength": null,"username": null,"createDate": "2022-09-12T21:57:18","changeDate": null,"status": "1","remark": "","auditStatus": null,"auditMind": null,"fileSize": 248329
}
-
定義上傳響應模型類
package com.xuecheng.media.model.dto;import com.xuecheng.media.model.po.MediaFiles;
import lombok.Data;
import lombok.ToString;@Data
@ToString
public class UploadFileResultDto extends MediaFiles {}
- controller層接口
? ? ? ? 前端傳過來的文件名稱是filedata
package com.xuecheng.media.api;import com.xuecheng.base.model.PageParams;
import com.xuecheng.base.model.PageResult;
import com.xuecheng.media.model.dto.QueryMediaParamsDto;
import com.xuecheng.media.model.dto.UploadFileParamsDto;
import com.xuecheng.media.model.dto.UploadFileResultDto;
import com.xuecheng.media.model.po.MediaFiles;
import com.xuecheng.media.service.MediaFileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.io.IOException;/*** 媒資文件管理接口*/@Api(value = "媒資文件管理接口",tags = "媒資文件管理接口")@RestController
public class MediaFilesController {@AutowiredMediaFileService mediaFileService;@ApiOperation("媒資列表查詢接口")@PostMapping("/files")public PageResult<MediaFiles> list(PageParams pageParams, @RequestBody QueryMediaParamsDto queryMediaParamsDto){Long companyId = 1232141425L;return mediaFileService.queryMediaFiels(companyId,pageParams,queryMediaParamsDto);}@ApiOperation("上傳圖片")@RequestMapping(value = "/upload/coursefile",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public UploadFileResultDto upload(@RequestPart("filedata")MultipartFile filedata) throws IOException {//準備上傳文件的信息UploadFileParamsDto uploadFileParamsDto = new UploadFileParamsDto();//原始文件名稱uploadFileParamsDto.setFilename(filedata.getOriginalFilename());//文件大小uploadFileParamsDto.setFileSize(filedata.getSize());//文件類型uploadFileParamsDto.setFileType("001001");//創建一個臨時文件File tempFile = File.createTempFile("minio", ".temp");filedata.transferTo(tempFile);Long companyId = 1232141425L;//文件路徑String localFilePath = tempFile.getAbsolutePath();//調用service上傳圖片UploadFileResultDto uploadFileResultDto = mediaFileService.uploadFile(companyId, uploadFileParamsDto, localFilePath);return uploadFileResultDto;}}
2.4 接口開發
2.4.1 Dao層
- mapper層
@Mapper
public interface MediaFilesMapper extends BaseMapper<MediaFiles> {}
- sql映射
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuecheng.media.mapper.MediaFilesMapper"><!-- 通用查詢映射結果 --><resultMap id="BaseResultMap" type="com.xuecheng.media.model.po.MediaFiles"><id column="id" property="id" /><result column="company_id" property="companyId" /><result column="company_name" property="companyName" /><result column="filename" property="filename" /><result column="file_type" property="fileType" /><result column="tags" property="tags" /><result column="bucket" property="bucket" /><result column="file_id" property="fileId" /><result column="url" property="url" /><result column="timelength" property="timelength" /><result column="username" property="username" /><result column="create_date" property="createDate" /><result column="change_date" property="changeDate" /><result column="status" property="status" /><result column="remark" property="remark" /><result column="audit_status" property="auditStatus" /><result column="audit_mind" property="auditMind" /></resultMap><!-- 通用查詢結果列 --><sql id="Base_Column_List">id, company_id, company_name, filename, file_type, tags, bucket, file_id, url, timelength, username, create_date, change_date, status, remark, audit_status, audit_mind</sql></mapper>
2.4.2 Service層
1)定義請求參數類
@Data
@ToString
public class UploadFileParamsDto {/*** 文件名稱*/private String filename;/*** 文件類型(文檔,音頻,視頻)*/private String fileType;/*** 文件大小*/private Long fileSize;/*** 標簽*/private String tags;/*** 上傳人*/private String username;/*** 備注*/private String remark;}
2)定義service方法
/*** 上傳文件* @param companyId 機構id* @param uploadFileParamsDto 文件信息* @param localFilePath 文件本地路徑* @return UploadFileResultDto*/public UploadFileResultDto uploadFile(Long companyId, UploadFileParamsDto uploadFileParamsDto, String localFilePath);
3)impl實現類實現service接口,重寫方法
?
@Autowired
MinioClient minioClient;@Autowired
MediaFilesMapper mediaFilesMapper;//普通文件桶
@Value("${minio.bucket.files}")
private String bucket_Files;//獲取文件默認存儲目錄路徑 年/月/日
private String getDefaultFolderPath() {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String folder = sdf.format(new Date()).replace("-", "/")+"/";return folder;
}//獲取文件的md5
private String getFileMd5(File file) {try (FileInputStream fileInputStream = new FileInputStream(file)) {String fileMd5 = DigestUtils.md5Hex(fileInputStream);return fileMd5;} catch (Exception e) {e.printStackTrace();return null;}
}private String getMimeType(String extension){if(extension==null)extension = "";//根據擴展名取出mimeTypeContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(extension);//通用mimeType,字節流String mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;if(extensionMatch!=null){mimeType = extensionMatch.getMimeType();}return mimeType;
}
/*** @description 將文件寫入minIO* @param localFilePath 文件地址* @param bucket 桶* @param objectName 對象名稱*/
public boolean addMediaFilesToMinIO(String localFilePath,String mimeType,String bucket, String objectName) {try {UploadObjectArgs testbucket = UploadObjectArgs.builder().bucket(bucket).object(objectName).filename(localFilePath).contentType(mimeType).build();minioClient.uploadObject(testbucket);log.debug("上傳文件到minio成功,bucket:{},objectName:{}",bucket,objectName);System.out.println("上傳成功");return true;} catch (Exception e) {e.printStackTrace();log.error("上傳文件到minio出錯,bucket:{},objectName:{},錯誤原因:{}",bucket,objectName,e.getMessage(),e);XueChengPlusException.cast("上傳文件到文件系統失敗");}return false;
}/*** @description 將文件信息添加到文件表* @param companyId 機構id* @param fileMd5 文件md5值* @param uploadFileParamsDto 上傳文件的信息* @param bucket 桶* @param objectName 對象名稱* @return com.xuecheng.media.model.po.MediaFiles*/
@Transactional
public MediaFiles addMediaFilesToDb(Long companyId,String fileMd5,UploadFileParamsDto uploadFileParamsDto,String bucket,String objectName){//從數據庫查詢文件MediaFiles mediaFiles = mediaFilesMapper.selectById(fileMd5);if (mediaFiles == null) {mediaFiles = new MediaFiles();//拷貝基本信息BeanUtils.copyProperties(uploadFileParamsDto, mediaFiles);mediaFiles.setId(fileMd5);mediaFiles.setFileId(fileMd5);mediaFiles.setCompanyId(companyId);mediaFiles.setUrl("/" + bucket + "/" + objectName);mediaFiles.setBucket(bucket);mediaFiles.setFilePath(objectName);mediaFiles.setCreateDate(LocalDateTime.now());mediaFiles.setAuditStatus("002003");mediaFiles.setStatus("1");//保存文件信息到文件表int insert = mediaFilesMapper.insert(mediaFiles);if (insert < 0) {log.error("保存文件信息到數據庫失敗,{}",mediaFiles.toString());XueChengPlusException.cast("保存文件信息失敗");}log.debug("保存文件信息到數據庫成功,{}",mediaFiles.toString());}return mediaFiles;}
@Transactional
@Override
public UploadFileResultDto uploadFile(Long companyId, UploadFileParamsDto uploadFileParamsDto, String localFilePath) {File file = new File(localFilePath);if (!file.exists()) {XueChengPlusException.cast("文件不存在");}//文件名稱String filename = uploadFileParamsDto.getFilename();//文件擴展名String extension = filename.substring(filename.lastIndexOf("."));//文件mimeTypeString mimeType = getMimeType(extension);//文件的md5值String fileMd5 = getFileMd5(file);//文件的默認目錄String defaultFolderPath = getDefaultFolderPath();//存儲到minio中的對象名(帶目錄)String objectName = defaultFolderPath + fileMd5 + exension;//將文件上傳到minioboolean b = addMediaFilesToMinIO(localFilePath, mimeType, bucket_files, objectName);//文件大小uploadFileParamsDto.setFileSize(file.length());//將文件信息存儲到數據庫MediaFiles mediaFiles = addMediaFilesToDb(companyId, fileMd5, uploadFileParamsDto, bucket_files, objectName);//準備返回數據UploadFileResultDto uploadFileResultDto = new UploadFileResultDto();BeanUtils.copyProperties(mediaFiles, uploadFileResultDto);return uploadFileResultDto;}
2.5 前后端聯調測試
?
2.6 代碼優化
????????目前是在uploadFile方法上添加@Transactional,當調用uploadFile方法前會開啟數據庫事務,如果上傳文件過程時間較長那么數據庫的事務持續時間就會變長,這樣數據庫鏈接釋放就慢,最終導致數據庫鏈接不夠用。
????????我們只將addMediaFilesToDb方法添加事務控制即可,uploadFile方法上的@Transactional注解去掉。
方法上已經添加了@Transactional注解為什么該方法不能被事務控制呢?
如果是在uploadFile方法上添加@Transactional注解就可以控制事務,去掉則不行。
????????現在的問題其實是一個非事務方法調同類一個事務方法,事務無法控制,這是為什么?
原因分析如下:
????????如果在uploadFile方法上添加@Transactional注解,代理對象執行此方法前會開啟事務,如下圖
?????????如果在uploadFile方法上沒有@Transactional注解,代理對象執行此方法前不進行事務控制,如下圖:
????????所以判斷該方法是否可以事務控制必須保證是通過代理對象調用此方法,且此方法上添加了@Transactional注解?。現在在addMediaFilesToDb方法上添加@Transactional注解,也不會進行事務控制是因為并不是通過代理對象執行的addMediaFilesToDb方法。為了判斷在uploadFile方法中去調用addMediaFilesToDb方法是否是通過代理對象去調用,我們可以打斷點跟蹤
????????我們發現在uploadFile方法中去調用addMediaFilesToDb方法不是通過代理對象去調用?
解決方法是在MediaFileService的實現類中注入MediaFileService的代理對象,將addMediaFilesToDb方法提成接口
完整代碼如下:
@Slf4j
@Service
public class MediaFileServiceImpl implements MediaFileService {@Autowiredprivate MediaFilesMapper mediaFilesMapper;@AutowiredMinioClient minioClient;@AutowiredMediaFileService currentProxy;//存儲普通文件@Value("${minio.bucket.files}")private String bucket_mediafiles;//存儲視頻@Value("${minio.bucket.videofiles}")private String bucket_video;@Overridepublic PageResult<MediaFiles> queryMediaFiels(Long companyId, PageParams pageParams, QueryMediaParamsDto queryMediaParamsDto) {//構建查詢條件對象LambdaQueryWrapper<MediaFiles> queryWrapper = new LambdaQueryWrapper<>();//分頁對象Page<MediaFiles> page = new Page<>(pageParams.getPageNo(), pageParams.getPageSize());// 查詢數據內容獲得結果Page<MediaFiles> pageResult = mediaFilesMapper.selectPage(page, queryWrapper);// 獲取數據列表List<MediaFiles> list = pageResult.getRecords();// 獲取數據總數long total = pageResult.getTotal();// 構建結果集PageResult<MediaFiles> mediaListResult = new PageResult<>(list, total, pageParams.getPageNo(), pageParams.getPageSize());return mediaListResult;}//根據擴展名獲取mimeTypeprivate String getMimeType(String extension){if(extension == null){extension = "";}//根據擴展名取出mimeTypeContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(extension);String mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;//通用mimeType,字節流if(extensionMatch!=null){mimeType = extensionMatch.getMimeType();}return mimeType;}/*** 將文件上傳到minio* @param localFilePath 文件本地路徑* @param mimeType 媒體類型* @param bucket 桶* @param objectName 對象名* @return*/public boolean addMediaFilesToMinIO(String localFilePath,String mimeType,String bucket, String objectName){try {UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder().bucket(bucket)//桶.filename(localFilePath) //指定本地文件路徑.object(objectName)//對象名 放在子目錄下.contentType(mimeType)//設置媒體文件類型.build();//上傳文件minioClient.uploadObject(uploadObjectArgs);log.debug("上傳文件到minio成功,bucket:{},objectName:{},錯誤信息:{}",bucket,objectName);return true;} catch (Exception e) {e.printStackTrace();log.error("上傳文件出錯,bucket:{},objectName:{},錯誤信息:{}",bucket,objectName,e.getMessage());}return false;}//獲取文件默認存儲目錄路徑 年/月/日private String getDefaultFolderPath() {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String folder = sdf.format(new Date()).replace("-", "/")+"/";return folder;}//獲取文件的md5private String getFileMd5(File file) {try (FileInputStream fileInputStream = new FileInputStream(file)) {String fileMd5 = DigestUtils.md5Hex(fileInputStream);return fileMd5;} catch (Exception e) {e.printStackTrace();return null;}}@Overridepublic UploadFileResultDto uploadFile(Long companyId, UploadFileParamsDto uploadFileParamsDto, String localFilePath) {//文件名String filename = uploadFileParamsDto.getFilename();//先得到擴展名String extension = filename.substring(filename.lastIndexOf("."));//得到mimeTypeString mimeType = getMimeType(extension);//子目錄String defaultFolderPath = getDefaultFolderPath();//文件的md5值String fileMd5 = getFileMd5(new File(localFilePath));String objectName = defaultFolderPath+fileMd5+extension;//上傳文件到minioboolean result = addMediaFilesToMinIO(localFilePath, mimeType, bucket_mediafiles, objectName);if(!result){XueChengPlusException.cast("上傳文件失敗");}//入庫文件信息MediaFiles mediaFiles = currentProxy.addMediaFilesToDb(companyId, fileMd5, uploadFileParamsDto, bucket_mediafiles, objectName);if(mediaFiles==null){XueChengPlusException.cast("文件上傳后保存信息失敗");}//準備返回的對象UploadFileResultDto uploadFileResultDto = new UploadFileResultDto();BeanUtils.copyProperties(mediaFiles,uploadFileResultDto);return uploadFileResultDto;}/*** @description 將文件信息添加到文件表* @param companyId 機構id* @param fileMd5 文件md5值* @param uploadFileParamsDto 上傳文件的信息* @param bucket 桶* @param objectName 對象名稱*/@Transactionalpublic MediaFiles addMediaFilesToDb(Long companyId,String fileMd5,UploadFileParamsDto uploadFileParamsDto,String bucket,String objectName){//將文件信息保存到數據庫MediaFiles mediaFiles = mediaFilesMapper.selectById(fileMd5);if(mediaFiles == null){mediaFiles = new MediaFiles();BeanUtils.copyProperties(uploadFileParamsDto,mediaFiles);//文件idmediaFiles.setId(fileMd5);//機構idmediaFiles.setCompanyId(companyId);//桶mediaFiles.setBucket(bucket);//file_pathmediaFiles.setFilePath(objectName);//file_idmediaFiles.setFileId(fileMd5);//urlmediaFiles.setUrl("/"+bucket+"/"+objectName);//上傳時間mediaFiles.setCreateDate(LocalDateTime.now());//狀態mediaFiles.setStatus("1");//審核狀態mediaFiles.setAuditStatus("002003");//插入數據庫int insert = mediaFilesMapper.insert(mediaFiles);if(insert<=0){log.debug("向數據庫保存文件失敗,bucket:{},objectName:{}",bucket,objectName);return null;}return mediaFiles;}return mediaFiles;}
}