当前位置: 首页 > news >正文

JAVA 整合 AWS S3(Amazon Simple Storage Service)文件上传,分片上传,删除,下载

依赖

因为aws需要发送请求上传、下载等api,所以需要加上httpclient相关的依赖

<dependency><groupId>com.amazonaws</groupId><artifactId>aws-java-sdk-s3</artifactId><version>1.11.628</version>
</dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version>
</dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpcore</artifactId><version>4.4.13</version>
</dependency>

工具类

上传和下载方式都被重载了,所以可以根据不同的业务场景去使用不同的重载方式。

import com.amazonaws.AmazonServiceException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
import com.amazonaws.services.s3.transfer.Upload;
import com.amazonaws.util.StringUtils;
import com.mocha.order.enums.PropertiesEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;@Component
public class CosUtil {private static final Logger LOGGER = LoggerFactory.getLogger(CosUtil.class);//访问keypublic static String accessKey;//密钥keypublic static String secretKey;//服务区域public static String serviceEndpoint; // e.g., "cos.gz-tst.cos.tg.unicom.local"//区域public static String region; // e.g., "gz-tst"static AWSCredentials credentials ;static AWSStaticCredentialsProvider awsStaticCredentialsProvider ;static ClientConfiguration config ;static AwsClientBuilder.EndpointConfiguration endpointConfiguration ;static AmazonS3 conn ;//分片大小5M,一般设置5的倍数即可,分片大小最大不要超过100Mpublic static final int  FIVE_PARTSIZE=5242880;//1Mpublic static final int  ONE_PARTSIZE=1048576;@PostConstructpublic void init() {//这些配置的值,可以从数据库获取、也可以丛配置文件获取final String cosAccessKey = PropertiesEnum.getCosAccessKey();final String cosSecretKey = PropertiesEnum.getCosSecretKey();final String cosServiceEndpoint = PropertiesEnum.getCosServiceEndpoint();final String cosRegion = PropertiesEnum.getCosRegion();if (org.apache.commons.lang3.StringUtils.isBlank(cosAccessKey)){LOGGER.error("联通云Cos配置的AccessKey为空,请保证【COS_ACCESSKEY】值不为空,否则会影响项目相关功能的使用");}if (org.apache.commons.lang3.StringUtils.isBlank(cosSecretKey)){LOGGER.error("联通云Cos配置的SecretKey为空,请保证【COS_SECRETKEY】值不为空,否则会影响项目相关功能的使用");}if (org.apache.commons.lang3.StringUtils.isBlank(cosServiceEndpoint)){LOGGER.error("联通云Cos配置的ServiceEndpoint为空,请保证【COS_SERVICEENDPOINT】值不为空,否则会影响项目相关功能的使用");}if (org.apache.commons.lang3.StringUtils.isBlank(cosRegion)){LOGGER.error("联通云Cos配置的Region为空,请保证【COS_REGION】值不为空,否则会影响项目相关功能的使用");}LOGGER.info("联通云Cos的配置分别为,accessKey:{},secretKey:{},serviceEndpoint:{},region:{}",cosAccessKey,cosAccessKey,cosServiceEndpoint,cosRegion);LOGGER.info("开始初始化联通云Cos的配置,开始初始化时间:{}",new Date());accessKey=cosAccessKey;secretKey=cosSecretKey;serviceEndpoint=cosServiceEndpoint;region=cosRegion;LOGGER.info("结束初始化联通云Cos的配置,结束初始化时间:{}",new Date());credentials = new BasicAWSCredentials(accessKey, secretKey);awsStaticCredentialsProvider = new AWSStaticCredentialsProvider(credentials);config = new ClientConfiguration();endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(serviceEndpoint, region);conn = AmazonS3ClientBuilder.standard().withCredentials(awsStaticCredentialsProvider).withClientConfiguration(config.withProtocol(Protocol.HTTP).withSignerOverride("S3SignerType")).withEndpointConfiguration(endpointConfiguration).build();}//检查桶是否存在public static boolean doesBucketExist(String bucketName){return conn.listBuckets().stream().map(Bucket::getName).collect(Collectors.toList()).contains(bucketName);}/*** 创建桶* 1、创建已经存在的桶,不会把之前存在的桶内容删除**/public static Bucket createBucket(String bucketName){LOGGER.info("创建桶:{}",bucketName);return conn.createBucket(bucketName);}// 列出所有桶列表public static List<Bucket> listBuckets(){return conn.listBuckets();}// 列出桶内对象public static ObjectListing listObjects(String bucketName){ObjectListing objects = conn.listObjects(bucketName);do {for (S3ObjectSummary objectSummary : objects.getObjectSummaries()) {LOGGER.info(objectSummary.getKey() + "\t" + objectSummary.getSize() + "\t" + StringUtils.fromDate(objectSummary.getLastModified()));}objects = conn.listNextBatchOfObjects(objects);} while (objects.isTruncated());return objects;}//  获取文件public static ObjectMetadata  getObjectMeta(String bucketName, String fileName){LOGGER.info("上传文件,桶名称:{},文件名称:{}",bucketName,fileName);return conn.getObjectMetadata(bucketName, fileName);}// 上传文件-通过实体类public static PutObjectResult uploadFile(PutObjectRequest putObjectRequest){LOGGER.info("上传文件桶实体类方式,实体类是:{}",putObjectRequest);return conn.putObject(putObjectRequest);}// 上传文件-通过Filepublic static PutObjectResult uploadFile(String bucketName, String keyName, File file){LOGGER.info("上传文件,桶名称:{},文件名称:{}",bucketName,keyName);return conn.putObject(bucketName, keyName, file);}// 上传文件-通过InputStreampublic static PutObjectResult uploadFile(String bucketName, String keyName, InputStream inputStream){LOGGER.info("上传文件,桶名称:{},文件名称:{}",bucketName,keyName);return conn.putObject(bucketName, keyName, inputStream, new ObjectMetadata());}// 上传文件-通过字符串public static PutObjectResult uploadFile(String bucketName, String keyName, String content){LOGGER.info("上传文件,桶名称:{},文件名称:{}",bucketName,keyName);return conn.putObject(bucketName, keyName, content);}// 分片上传(不要需要指定分片的大小、还提供上传进度跟踪、断点续传、并发上传等功能)public static Upload uploadFileByShard(String bucketName, String keyName, String filePath) throws InterruptedException,AmazonServiceException {TransferManager tm = TransferManagerBuilder.standard().withS3Client(conn).build();try {LOGGER.info("开始分片上传,桶名称:{},文件名称:{},路径:{}",bucketName,keyName,filePath);Upload upload = tm.upload(bucketName, keyName, new File(filePath));upload.waitForCompletion();LOGGER.info("结束分片上传,桶名称:{},文件名称:{},路径:{}",bucketName,keyName,filePath);return upload;} catch (AmazonServiceException | InterruptedException e) {LOGGER.error("分片上传异常,桶名称:{},文件名称:{},路径:{}",bucketName,keyName,filePath);e.printStackTrace();throw e;}}/*** 大文件分段上传(需要指定分片的大小,自定义的线程池)** @param bucketName  bucketName* @param objectName  objectName* @param file        MultipartFile* @param minPartSize 每片大小,单位:字节(eg:5242880 <- 5m)* @return*/public static boolean uploadMultipartFileByPart(String bucketName, String objectName, File file, int minPartSize) {long size = file.length();final String fileName = file.getName();if (size==0) {LOGGER.error("分片上传的文件:{}为空",fileName);return false;}// 计算分片大小// 得到总共的段数,和 分段后,每个段的开始上传的字节位置List<Long> positions = Collections.synchronizedList(new ArrayList<>());long filePosition = 0;while (filePosition < size) {positions.add(filePosition);filePosition += Math.min(minPartSize, (size - filePosition));}if (LOGGER.isDebugEnabled()) {LOGGER.info("文件:{},总大小:{}字节,分为{}段",fileName, size, positions.size());}// 创建一个列表保存所有分传的 PartETag, 在分段完成后会用到List<PartETag> partETags = Collections.synchronizedList(new ArrayList<>());// 第一步,初始化,声明下面将有一个 Multipart Upload// 设置文件类型ObjectMetadata metadata = new ObjectMetadata();String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);metadata.setContentType(fileType);InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(bucketName, objectName, metadata);InitiateMultipartUploadResult initResponse = conn.initiateMultipartUpload(initRequest);if (LOGGER.isDebugEnabled()) {LOGGER.info("分片上传开始,上传的文件时:{}",fileName);}//声明线程池ExecutorService exec = Executors.newFixedThreadPool(5);long begin = System.currentTimeMillis();try {for (int i = 0; i < positions.size(); i++) {int finalI = i;exec.execute(() -> {long time1 = System.currentTimeMillis();UploadPartRequest uploadRequest = new UploadPartRequest().withBucketName(bucketName).withKey(objectName).withUploadId(initResponse.getUploadId()).withPartNumber(finalI + 1).withFileOffset(positions.get(finalI)).withFile(file).withPartSize(Math.min(minPartSize, (size - positions.get(finalI))));// 第二步,上传分段,并把当前段的 PartETag 放到列表中partETags.add(conn.uploadPart(uploadRequest).getPartETag());LOGGER.info("分片上传的文件时:{},第{}段上传耗时:{}",fileName ,finalI + 1, (System.currentTimeMillis() - time1));});}//任务结束关闭线程池exec.shutdown();//判断线程池是否结束,不加会直接结束方法while (true) {if (exec.isTerminated()) {break;}}// 第三步,完成上传,合并分段CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(bucketName, objectName, initResponse.getUploadId(), partETags);conn.completeMultipartUpload(compRequest);} catch (Exception e) {conn.abortMultipartUpload(new AbortMultipartUploadRequest(bucketName, objectName, initResponse.getUploadId()));LOGGER.error("分片上传文件:{}异常,异常是:{}, ",fileName, e.getLocalizedMessage());e.printStackTrace();}LOGGER.info("分片上传文件:{}结束,总上传耗时:{}毫秒",fileName, (System.currentTimeMillis() - begin));return false;}/*** 初始化,声明有一个Multipart Upload** @param initRequest 初始化请求* @return 初始化返回*/private InitiateMultipartUploadResult initiateMultipartUpload(InitiateMultipartUploadRequest initRequest) {return conn.initiateMultipartUpload(initRequest);}/*** 上传分段** @param uploadRequest 上传请求* @return 上传分段返回* @see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPart">AWS* API Documentation</a>*/private UploadPartResult uploadPart(UploadPartRequest uploadRequest) {return conn.uploadPart(uploadRequest);}/*** 分段合并** @param compRequest 合并请求* @see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompleteMultipartUpload">AWS* API Documentation</a>*/private CompleteMultipartUploadResult completeMultipartUpload(CompleteMultipartUploadRequest compRequest) {return conn.completeMultipartUpload(compRequest);}/*** 中止分片上传** @param uploadRequest 中止文件上传请求* @see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortMultipartUpload">AWS* API Documentation</a>*/private void abortMultipartUpload(AbortMultipartUploadRequest uploadRequest) {conn.abortMultipartUpload(uploadRequest);}// 修改对象的访问控制权限public static void modifyFileAccessAuthority(String bucketName, String keyName, CannedAccessControlList cannedAccessControlList){LOGGER.info("修改文件的访问权限,桶名称:{},文件名称:{},权限类型时:{}",bucketName,keyName,cannedAccessControlList.toString());conn.setObjectAcl(bucketName, keyName, cannedAccessControlList);}// 下载一个对象(到指定路径)public static ObjectMetadata downloadFileAssignPath(String bucketName, String keyName, String fileSavePath){return conn.getObject(new GetObjectRequest(bucketName, keyName), new File(fileSavePath));}// 生成对象下载链接(带签名)public static URL generatorFileUrl(String bucketName, String keyName){GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, keyName);return conn.generatePresignedUrl(request);}// 删除文件public static void deleteFie(String bucketName, String keyName){LOGGER.info("删除文件,桶名称:{},文件名称:{},删除时间:{}",bucketName,keyName,new Date());conn.deleteObject(bucketName, keyName);}// 删除桶public static void deleteFie(String bucketName){LOGGER.info("删除桶,桶名称:{},删除时间:{}",bucketName,new Date());conn.deleteBucket(bucketName);}public static void main(String[] args) {String filePath = "G:\\mk\\GDrepo\\repo\\org\\apache\\httpcomponents\\httpcomponents-core\\4.0.1\\httpcomponents-core-4.0.1.pom"; //文件路径//        ByteArrayInputStream input1 = new ByteArrayInputStream("Hello World!".getBytes());
//        CosUtil.createBucket("aaa");
//        final FileInputStream inputStream;
//        try {
//            inputStream = new FileInputStream("G:\\mk\\GDrepo\\repo\\org\\apache\\httpcomponents\\httpcomponents-core\\4.0.1\\httpcomponents-core-4.0.1.pom");
//        } catch (FileNotFoundException e) {
//            throw new RuntimeException(e);
//        }
//        CosUtil.uploadFile("aaa","a.pom",inputStream);CosUtil.uploadFile("test","a.txt",new File(filePath));CosUtil.uploadFile("test","a.txt",new File(filePath));//上传空文件夹conn.putObject("aaa", "demo" + "/","");//上传文件到指定的文件夹final PutObjectRequest putObjectRequest = new PutObjectRequest("aaa", "demo" + "/" + "a.txt", new File(filePath));conn.putObject(putObjectRequest);// 列出所有桶列表List<Bucket> buckets = conn.listBuckets();for (Bucket bucket : buckets) {System.out.println(bucket.getName() + "\t" + StringUtils.fromDate(bucket.getCreationDate()));}// 创建桶Bucket bucket = conn.createBucket("111");Bucket bucket1 = conn.createBucket("111");Bucket bucket12 = conn.createBucket("111");System.out.println(bucket.getName());// 列出桶内对象ObjectListing objects = conn.listObjects(bucket.getName());do {for (S3ObjectSummary objectSummary : objects.getObjectSummaries()) {System.out.println(objectSummary.getKey() + "\t" +objectSummary.getSize() + "\t" +StringUtils.fromDate(objectSummary.getLastModified()));}objects = conn.listNextBatchOfObjects(objects);} while (objects.isTruncated());// 创建对象ByteArrayInputStream input = new ByteArrayInputStream("Hello World!".getBytes());conn.putObject(bucket.getName(), "hello.txt", input, new ObjectMetadata());//分段上传String keyName = "demoya"; //文件上传成功后的文件名TransferManager tm = TransferManagerBuilder.standard().withS3Client(conn).build();try {// TransferManager processes all transfers asynchronously,// so this call returns immediately.System.out.println("开始分片上传");Upload upload = tm.upload("my-test-bucket", keyName, new File(filePath));//Optionally, wait for the upload to finish before continuing.upload.waitForCompletion();System.out.println("结束分片上传");} catch (AmazonServiceException | InterruptedException e) {// The call was transmitted successfully, but Amazon S3 couldn't process// it, so it returned an error response.e.printStackTrace();}// 修改对象的访问控制权限conn.setObjectAcl(bucket.getName(), "hello.txt", CannedAccessControlList.PublicRead);// 下载一个对象(到本地文件)conn.getObject(new GetObjectRequest(bucket.getName(), "hello.txt"), new File("G:\\mk\\hello.txt"));// 生成对象下载链接(带签名)GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucket.getName(), "hello.txt");System.out.println(conn.generatePresignedUrl(request));// 删除一个对象conn.deleteObject(bucket.getName(), "hello.txt");//删除桶conn.deleteBucket(bucket.getName());}
}

相关文章:

JAVA 整合 AWS S3(Amazon Simple Storage Service)文件上传,分片上传,删除,下载

依赖 因为aws需要发送请求上传、下载等api&#xff0c;所以需要加上httpclient相关的依赖 <dependency><groupId>com.amazonaws</groupId><artifactId>aws-java-sdk-s3</artifactId><version>1.11.628</version> </dependency&…...

记录:Unity脚本的编写9.0

目录 射线一些准备工作编写代码 突然发现好像没有写过关于射线的内容&#xff0c;我就说怎么总感觉好像少了什么东西&#xff08;心虚 那就在这里写一下关于射线的内容吧&#xff0c;将在这里实现射线检测鼠标点击的功能 射线 射线是一种在Unity中检测碰撞器或触发器的方法&am…...

共享单车停放(简单的struct结构运用)

本来不想写这题的&#xff0c;但是想想最近沉迷玩雨世界&#xff0c;班长又问我这题&#xff0c;就草草写了一下 代码如下&#xff1a; #include<stdio.h> #include<math.h> struct parking{int distance;int remain;int speed;int time;int jud; }parking[50]; …...

【Java8系列07】Java8日期处理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

为什么做CSGO搬砖的不直接去炒股呢?

首先&#xff0c;CS2并非只有一个交易平台&#xff0c;阿阳个人觉得像IGXE等交易平台一样是交易&#xff0c;况且我记得很早的时候我就开始用IGXE了&#xff0c;我记得最早的时候还是机器人发货&#xff0c;后来因为V社对于很多开箱网站的管控&#xff0c;所以让这种发货的方式…...

12月01日,每日信息差//阿里国际发布3款AI设计生态工具//美团买菜升级为“小象超市”//外国人永居证换新、6国游客免签来华

_灵感 &#x1f396; 阿里国际发布3款AI设计生态工具 &#x1f384; AITO问界系列11月交付新车18827辆 &#x1f30d; 美团买菜升级为“小象超市” &#x1f30b; 全球首个金融风控大模型国际标准出炉&#xff0c;由腾讯牵头制定 &#x1f381; 支付宝&#xff1a;支持外国人…...

ChatGPT探索:提示工程详解—程序员效率提升必备技能【文末送书】

文章目录 一.人工智能-ChatGPT1.1 ChatGPT简介1.2 ChatGPT探索&#xff1a;提示工程详解1.2 提示工程的优势 二.提示工程探索2.1 提示工程实例&#xff1a;2.2 英语学习助手2.3 Active-Prompt思维链&#xff08;CoT&#xff09;方法2.4 提示工程总结 三.文末推荐与福利3.1《Cha…...

Pytest做性能测试?

Pytest其实也是可以做性能测试或者基准测试的。是非常方便的。 可以考虑使用Pytest-benchmark类库进行。 安装pytest-benchmark 首先&#xff0c;确保已经安装了pytest和pytest-benchmark插件。可以使用以下命令安装插件&#xff1a; pip install pytest pytest-benchmark …...

Swagger各版本访问地址

2.9.x 访问地址: http://ip:port/{context-path}/swagger-ui.html 3.0.x 访问地址: http://ip:port/{context-path}/swagger-ui/index.html 3.0集成knife4j 访问地址: http://ip:port/{context-path}/doc.html...

docker-compose;私有镜像仓库harbor搭建;镜像推送到私有仓库harbor

docker-compose&#xff1b;私有镜像仓库harbor搭建&#xff1b;镜像推送到私有仓库harbor 文章目录 docker-compose&#xff1b;私有镜像仓库harbor搭建&#xff1b;镜像推送到私有仓库harbordocker-compose私有镜像仓库harbor搭建镜像推送到私有仓库harbor docker-compose D…...

OpenTSDB(CVE-202035476)漏洞复现及利用

任务一&#xff1a; 复现环境中的命令注入漏洞。 任务二&#xff1a; 利用命令注入执行whoami&#xff0c;使用DNS外带技术获取结果 任务三&#xff1a;使用反弹shell&#xff0c;将漏洞环境中的shell反弹到宿主机或者vps服务器。 任务一&#xff1a; 1.搭建好环境 2.先去了…...

Maven无法拉取依赖/构建失败操作步骤(基本都能解决)

首先检查配置文件&#xff0c;确认配置文件没有问题(也可以直接用同事的配置文件(记得修改文件里的本地仓库地址)) 1.file->Invalidate Caches清除缓存重启(简单粗暴&#xff0c;但最有效) 2.刷新maven以及mvn clean&#xff0c;多刷几次&#xff0c;看看还有没有报红的依赖…...

【数据库】数据库并发控制的目标,可串行化序列的分析,并发控制调度器模型

数据库并发控制 ​专栏内容&#xff1a; 手写数据库toadb 本专栏主要介绍如何从零开发&#xff0c;开发的步骤&#xff0c;以及开发过程中的涉及的原理&#xff0c;遇到的问题等&#xff0c;让大家能跟上并且可以一起开发&#xff0c;让每个需要的人成为参与者。 本专栏会定期更…...

带头结点的双向循环链表

目录 带头结点的双向循环链表 1.存储定义 2.结点的创建 3.结点的初始化 4.尾插结点 5.尾删结点 6.头插结点 7.头删结点 8.查找并返回结点 9.在pos结点前插入结点 10.删除pos结点 11.打印链表 12.销毁链表 13.头插结点2.0版 14.尾插结点2.0版 前言&#xff1a; 当…...

2023年11月下旬大模型新动向集锦

2023年11月下旬大模型新动向集锦 2023.12.1版权声明&#xff1a;本文为博主chszs的原创文章&#xff0c;未经博主允许不得转载。 1、微软将向中国大陆开放Windows Copilot服务 据微软发布的消息&#xff0c;微软将在 2023 年 12 月 1 日面向中国大陆的企业和教育机构推出 We…...

有IP没有域名可以申请证书吗?

一、IP证书是什么&#xff1f; ip证书是用于公网ip地址的SSL证书&#xff0c;与我们通常所讲的SSL证书并无本质上的区别&#xff0c;但由于SSL证书通常颁发给域名&#xff0c;而组织机构需要公共ip地址的SSL证书&#xff0c;这类SSL证书就是我们所说的ip证书。ip证书具有安全、…...

【软件推荐】卸载360软件geek;护眼软件flux;

卸载360软件geek f.lux: software to make your life better (justgetflux.com) 卸载完扫描残留 护眼软件 hf.lux: software to make your life better (justgetflux.com)https://justgetflux.com/https://justgetflux.com/...

Module build failed: Error: ENOENT: no such file or directory

前言 这个错误通常发生在Node.js 和 vue,js项目中&#xff0c;当你试图访问一个不存在的文件或目录时。在大多数情况下&#xff0c;这是因为你的代码试图打开一个不存在的文件&#xff0c;或者你的构建系统&#xff08;例如Webpack&#xff09;需要一个配置文件&#xff0c;但找…...

Postgresql BatchInsert唯一键冲突及解决

Postgresql BatchInsert唯一键冲突及解决 当有唯一键冲突时&#xff0c;批量插入可能会报错&#xff1b; insert into tableA(sno,name,age,emp) values(),(),(); 会报错 insert into tableA(sno,name,age,emp) values(),(),() on conflict on contraint tableA_unique_key do …...

腾讯云AMD服务器标准型SA5实例AMD EPYC Bergamo处理器

腾讯云服务器标准型SA5实例是最新一代的标准型实例&#xff0c;CPU采用AMD EPYC™ Bergamo全新处理器&#xff0c;采用最新DDR5内存&#xff0c;默认网络优化&#xff0c;最高内网收发能力达4500万pps。腾讯云百科txybk.com分享腾讯云标准型SA5云服务器CPU、内存、网络、性能、…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...