SpringBoot集成Minio(简单使用)

SpringBoot整合Minio的详细步骤 SpringBoot整合Minio详细步骤 阅读详情

前言

1.什么是Minio?
MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。(我的理解就是对象存储服务。跟fastdfs很像,有服务端和客户端)

  1. docker安装Minio(别问我为什么用docker。两个字简单方便)
#拉取镜像
docker pull minio
#拉取镜像
docker run 
-p 9001:9000 -p 9090:9090  # 第一个端口是服务端口,第二个是客户端(9001是宿主机端口,9000是容器内部端口)
--net=host  #表示容器和宿主机共享一个ip
--name minio #容器名称
-d --restart=always  #自启动
-e "MINIO_ACCESS_KEY=minio"  #客户端账号(有点像Mysql的用户密码)
-e "MINIO_REGION=cn-north-1" 
-e "TZ=Asia/Beijing"  #设置容器时区(不设置会报错)
-e "MINIO_SECRET_KEY=minio123456" #客户端密码 (密码必须不得少于8位不然启动不了) 
-v /minio/data:/data  #挂载目录将/minio/data挂载到容器的/data目录,防止数据丢失
-v /minio/config:/root/.minio  minio/minio server /data 
--console-address ":9090" -address ":9001"

没有设置时区时会报错
error occurred
ErrorResponse(code = AccessDenied, message = Access denied, bucketName = bucket, objectName = null, resource = /bucket, requestId = null, hostId = null)
request={method=HEAD, url=http://192.168.186.128:9090/bucket, headers=Host: 192.168.186.128:9090
Accept-Encoding: identity
User-Agent: MinIO (amd64; amd64) minio-java/2.0.0
Content-MD5: 1B2M2Y8AsgTpgAmY7PhCfg==
x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date: 20220126T034536Z
Authorization: AWS4-HMAC-SHA256 Credential=REDACTED/20220126/us-east-1/s3/aws4_request, SignedHeaders=accept-encoding;content-md5;host;x-amz-content-sha256;x-amz-date, Signature=REDACTED
}
response={code=403, headers=Date: Wed, 26 Jan 2022 03:45:36 GMT
Content-Length: 209
Content-Type: text/xml; charset=utf-8
Connection: close
}
参考解决链接
2. 启动成功后访问http://ip:9090,进入控制台页面
在这里插入图片描述
用户密码就是上面启动命令里的账号密码
在这里插入图片描述
Buckets:我的理解就是一个打的文件盘,而下面的project和file是一个个文件夹,objects就是文件个数
3. SpringBoot简单使用

#pom文件
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 操作minio的java客户端-->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.5.2</version>
        </dependency>
        <!-- 操作minio的java客户端-->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.2.1</version>
        </dependency>
        <!--        jwt鉴权相应依赖-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.11.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
#yml文件
server:
  port: 8080
spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB

  #minio配置
  minio:
    access-key: minio #启动命令里的账号
    secret-key: minio123456 #启动命令里的地址
    url: http://192.168.32.211:9001  #访问地址
    bucket-name: project
#配置文件
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.minio")
public class MinioConfig {
    private String accessKey;

    private String secretKey;

    private String url;

    private String bucketName;

    @Bean
    public MinioClient minioClient(){
        return MinioClient.builder()
                .region("cn-north-1")
                .endpoint(url)
                .credentials(accessKey,secretKey)
                .build();
    }
}
#工具类
package com.example.producerserver.util;

import com.example.producerserver.config.MinioConfig;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import lombok.SneakyThrows;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class MinioUtils {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConfig configuration;

    /**
     * @param name 名字
     * @return boolean
     * @Description description: 判断bucket是否存在,不存在则创建
     * @Author zy
     * @Date 2024/08/01
     */
    public boolean existBucket(String name) {
        boolean exists;
        try {
            exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build());
            if (!exists) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build());
                exists = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            exists = false;
        }
        return exists;
    }

    /**
     * @param bucketName 存储bucket名称
     * @return {@link Boolean }
     * @Description 创建存储bucket
     * @Author zy
     * @Date 2024/08/01
     */
    public Boolean makeBucket(String bucketName) {
        try {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * @param bucketName 存储bucket名称
     * @return {@link Boolean }
     * @Description 删除存储bucket
     * @Author zy
     * @Date 2024/08/01
     */
    public Boolean removeBucket(String bucketName) {
        try {
            minioClient.removeBucket(RemoveBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * @param fileName 文件名称
     * @param time     时间
     * @return {@link Map }
     * @Description 获取上传临时签名
     * @Author zy
     * @Date 2024/08/01
     */
    @SneakyThrows
    public Map getPolicy(String fileName, ZonedDateTime time) {
        PostPolicy postPolicy = new PostPolicy(configuration.getBucketName(), time);
        postPolicy.addEqualsCondition("key", fileName);
        try {
            Map<String, String> map = minioClient.getPresignedPostFormData(postPolicy);
            HashMap<String, String> map1 = new HashMap<>();
            map.forEach((k, v) -> {
                map1.put(k.replaceAll("-", ""), v);
            });
            map1.put("host", configuration.getUrl() + "/" + configuration.getBucketName());
            return map1;
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param objectName 对象名称
     * @param method     方法
     * @param time       时间
     * @param timeUnit   时间单位
     * @return {@link String }
     * @Description 获取上传文件的url
     * @Author zy
     * @Date 2024/08/01
     */
    public String getPolicyUrl(String objectName, Method method, int time, TimeUnit timeUnit) {
        try {
            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(method)
                    .bucket(configuration.getBucketName())
                    .object(objectName)
                    .expiry(time, timeUnit).build());
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * @param file     文件
     * @param fileName 文件名称
     * @Description 上传文件
     * @Author zy
     * @Date 2024/08/01
     */
    public void upload(MultipartFile file, String fileName) {
        // 使用putObject上传一个文件到存储桶中。
        try {
            InputStream inputStream = file.getInputStream();
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(configuration.getBucketName())
                    .object(fileName)
                    .stream(inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build());
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param objectName 对象名称
     * @param time       时间
     * @param timeUnit   时间单位
     * @return {@link String }
     * @Description 根据filename获取文件访问地址
     * @Author zy
     * @Date 2024/08/01
     */
    public String getUrl(String objectName, int time, TimeUnit timeUnit) {
        String url = null;
        try {
            url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket(configuration.getBucketName())
                    .object(objectName)
                    .expiry(time, timeUnit).build());
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        }
        return url;
    }

    /**
     * @param fileName
     * @return {@link ResponseEntity }<{@link byte[] }>
     * @Description description: 下载文件
     * @Author zy
     * @Date 2024/08/01
     */
    public ResponseEntity<byte[]> download(String fileName) {
        ResponseEntity<byte[]> responseEntity = null;
        InputStream in = null;
        ByteArrayOutputStream out = null;
        try {
            in = minioClient.getObject(GetObjectArgs.builder().bucket(configuration.getBucketName()).object(fileName).build());
            out = new ByteArrayOutputStream();
            IOUtils.copy(in, out);
            //封装返回值
            byte[] bytes = out.toByteArray();
            HttpHeaders headers = new HttpHeaders();
            try {
                headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            headers.setContentLength(bytes.length);
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setAccessControlExposeHeaders(Arrays.asList("*"));
            responseEntity = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.BAD_REQUEST);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responseEntity;
    }

    /**
     * @param objectFile 对象文件
     * @return {@link String }
     * @Description 根据文件名和桶获取文件路径
     * @Author zy
     * @Date 2024/08/01
     */
    public String getFileUrl(String objectFile) {
        try {

            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket(configuration.getBucketName())
                    .object(objectFile)
                    .build()
            );
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }


}
#写个测试接口
package com.example.producerserver.controller;

import com.example.producerserver.util.MinioUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;

@CrossOrigin
@RestController
@RequestMapping("/api")
@Log4j2
public class MinioFileUploadController {
    @Autowired
    private MinioUtils minioUtils;

    /**
     * @param file     文件
     * @param fileName 文件名称
     * @return {@link AjaxResult }
     * @Description 上传文件
     * @Author  zy
     * @Date 2024/08/01
     */
    @GetMapping("/upload")
    public Object uploadFile(@RequestParam("file") MultipartFile file, String fileName) {
        StopWatch stopWatch=new StopWatch();
        stopWatch.start("测试上传");
        minioUtils.upload(file, fileName);
        stopWatch.stop();
       log.info(stopWatch.prettyPrint());
        return"上传成功";

    }

    /**
     * @param fileName 文件名称
     * @return {@link ResponseEntity }
     * @Description dowload文件
     * @Author  zy
     * @Date 2024/08/01
     */
    @GetMapping("/dowload")
    public ResponseEntity dowloadFile(@RequestParam("fileName") String fileName) {
        return minioUtils.download(fileName);
    }

    /**
     * @param fileName 文件名称
     * @return {@link AjaxResult }
     * @Description 得到文件url
     * @Author  zy
     * @Date 2024/08/01
     */
    @GetMapping("/getUrl")
    public Object getFileUrl(@RequestParam("fileName") String fileName){
        HashMap map=new HashMap();
        map.put("FileUrl",minioUtils.getFileUrl(fileName));
        return map;
    }
}
  1. 测试
    在这里插入图片描述
    在这里插入图片描述当文件名相同时会覆盖掉之前的文件。
    在这里插入图片描述
    在这里插入图片描述
    上传2G文件耗时110秒左右,总的来说还行
  2. 总结:工作中用到的存储文件的方式是nas盘,最近由于文件越来越多,导致磁盘空间不可用,就想找个别的东西代替nas存储文件,偶然了解到minio分布式文件存储。本次demo只是简单介绍和使用,学习之路任到重远,欢迎指点
MinIO与SpringBoot集成完整指南 MinIO是一款高性能的开源对象存储服务,完全兼容Amazon S3 API。本文详细介绍了MinIO的安装部署、SpringBoot集成及实际应用方案。主要内容包括:通过Docker或二进制方式部署MinIO;使用SpringBoot开发完整的文件管理API,涵盖文件上传、下载、删除等操作;提供HTML前端示例实现可视化文件管理;分享性能优化、安全实践等生产环境经验。文章还解决了常见问题如连接失败、权限配置等,并给出分片上传、连接池配置等优化建议。该指南帮助开发者快速构建基于MinIO的企业级文件存储系统 阅读详情

相关推荐

SpringBoot整合MinIO

MinIO的安装和运行以及SpringBoot整合MinIO

w1245247503的博客 1502

springboot整合minio

minio是对象存储服务。它基于Apache License 开源协议,兼容Amazon S3云存储接口。适合存储非结构化数据,如图片,音频,视频,日志等。对象文件最大可以达到5TB。

qq_36090537的博客 9549

SpringBoot项目集成MinIO

最近在学习MinIO,所以想让自己的SpringBoot项目集成MinIO,在网上查阅资料,并进行操作的过程中遇到一些问题,所以想把自己遇到的坑和完成步骤记录下来供自己和各位查阅。

m0_54850786的博客 1191

SpringBoot+MinIO实现minio部署和使用

功能完善:Minio支持云原生,能与Kubernetes、Docker、Swarm编排系统良好对接,实现灵活部署。简单、可靠:Minio采用简单可靠的集群方案,摒弃复杂的大规模的集群调度管理,减少风险与性能瓶颈,聚焦产品的核心功能,打造高可用的集群、灵活的扩展能力以及超过的性能。Minio是一个go编写基于Apache License v2.0开源协议的对象存储系统,是为海量数据存储、人工智能、大数据分析而设计,它完全兼容Amazon S3接口,十分符合存储大容量的非结构化数据从几十kb到最大5T不等。

qq_39990869的博客 7241

SpringBoot 集成MinIO

SpringBoot 集成MinIO 引入jar包 <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>7.0.2</version> </dependency> 配置 minio: endpoint: 172.28.43.29 port: 9000

赵先森 1万+

保姆级教程:手把手教你用RKISP TURN为RV1106生成和配置IQfile(附AIQ版本匹配避坑指南)

本文提供RV1106 ISP调试的完整指南,详细讲解如何使用RKISP TURN工具生成和配置IQfile,包括环境搭建、参数调试、设备树配置及常见问题解决方案。特别强调AIQ版本匹配的重要性,帮助开发者避免常见陷阱,提升图像信号处理效率。

weixin_42520796的博客 489

docker环境下minio的简单搭建和springboot集成使用

官方文档有各种平台的使用教程,可以参考官网地址:https://www.minio.org.cn/

sujt0726的博客 2803

避坑指南:用pygrib处理ERA5气象数据时遇到的5个典型问题

本文总结了使用pygrib库处理ERA5气象GRIB数据时常见的五个典型问题及解决方案,涵盖数据获取、内存管理、时间处理、空间插值和性能优化。重点针对气象数据插值这一核心挑战,提供了处理不规则网格、缺失值和跨日期变更线的实用代码示例与优化策略,帮助用户高效、稳定地完成气象数据分析工作。

weixin_28224217的博客 185

SpringBoot集成Minio实战详解

本博客旨在快速使用sringBoot集成MinIo,具有很强的使用性和参考意义,可减少初学者的学习成本,快速提高技术。

weixin_46242847的博客 3086

GenomeSurvyIndex设计--随笔017

摘要: GenomeSurvyIndex是一款自动化多倍体基因组调查工具,整合FastK、Smudgeplot和GenomeScope2.0三大核心组件。该工具通过k-mer频谱特征自动识别基因组倍性类型,包括二倍体(1:2:4)和同源四倍体(1:2:3:4),并采用3a1b>2a2b算法判定同源/异源多倍体。工具提供完整的conda环境配置方案,封装为Python脚本实现全流程自动化分析,包含k-mer计数、倍性判定、基因组特征计算等功能,最终输出标准化报告和可视化图表。该方案可直接部署使用,适用于

weixin_44874487的博客 474

电力-平衡式IEC 60870-5-101规约报文解析

本文详细介绍了电力自动化中平衡式IEC 60870-5-101规约的应用,包括链路建立与初始化、对时、遥控操作、数据上送和总召唤等关键步骤,通过实例解析了报文格式和交互过程,是理解配网自动化通信的重要参考资料。

让你爱上电路设计 5682

springboot集成minio

springboot整合minio服务

Priorityszr的博客 1403

UWB定位进阶:如何利用DW1000的CIR数据做NLOS信号识别?

本文深入探讨了如何利用DW1000芯片的信道脉冲响应(CIR)数据进行非视距(NLOS)信号识别,以提升UWB定位精度。通过分析CIR数据的核心价值、预处理方法、特征提取技术以及机器学习模型构建,为研究人员和工程师提供了实用的解决方案,帮助克服室内定位中的NLOS挑战。

weixin_28729205的博客 474

minio单机、集群搭建、Spring Boot集成,详细步骤

一、单机minio搭建 1.下载rpm包 下载地址:https://dl.min.io/server/minio/release/linux-amd64/ 2.安装 rpm -ivh minio-20220504074527.0.0.x86_64.rpm 修改 /etc/systemd/system/minio.service文件 #启动的用户和用户组 User=root Group=root #配置文件地址 EnvironmentFile=-/etc/default/minio..

localhost 2867

【第2章>第10节】深度学习DenseNet模型分析与matlab仿真

本文介绍了基于DenseNet深度学习模型的图像分类MATLAB实现方法。主要内容包括:1. DenseNet模型原理,详细解析了初始卷积层、密集块、过渡层等核心结构;2. 在MATLAB环境下完成DenseNet工具箱安装和测试样本准备;3. 实现图像预处理(统一缩放为224×224)、模型训练和测试的完整流程;4. 提供了混淆矩阵和准确率等测试结果分析。文章附带完整的MATLAB程序代码和操作视频教程,适合深度学习初学者快速掌握DenseNet模型的图像分类应用。通过实际测试,验证了该方案的有效性。

FPGA/MATLAB学习教程/源码/项目合作开发 330

PointPillars代码详解及实现

SourceURL:file://文字文稿1和2D图像的深度学习目标检测很不相同,点云数据具有两个显著特征,为了将图像领域卷积神经网络做模式识别的经验引入三维点云中,一些深度学习方法采用了三维卷积方法或者是将点云投射为2维深度图,还有一类方法是使用鸟瞰视角Bird’s Eye View,来组织点云数据的输入,相比于2维深度图,鸟瞰图不存在遮挡问题但是数据分布更加稀疏造成网络特征学习效率低下。

m0_47313541的博客 660

minio部署及springboot集成使用

MinIO对象存储部署与集成指南 本文介绍了MinIO分布式对象存储系统的核心特性和部署方法。MinIO具有开源、高性能、兼容S3协议等特点,支持混合云部署。详细步骤包括:Linux环境准备、二进制包下载、权限设置、服务启动(默认9001端口)及账号密码修改。Web控制台提供桶管理、文件操作和权限策略配置功能。最后给出了SpringBoot集成方案,包含Maven依赖和YAML配置示例,并提供了示例工程Git仓库地址。部署过程配有操作动图演示,便于用户快速掌握从安装到应用集成的完整流程。

qq_36402507的博客 2077

鲁棒控制理论 --- H∞ 控制(被裁篇)

鲁棒控制理论 --- H∞ 控制

记录老板的每次pua,分享领导每天的毒鸡汤... 6万+

minio的安装和springboot集成minio

minio的安装和springboot集成minio

qq_47614329的博客 5456

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

上一篇: SpringBoot集成Mybatis多数据源实现分表分库
下一篇: 线程池使用ThreadLocal需要注意哪些问题?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值