Java使用JDBC向数据库存取二进制数据(如图片,视频,音频等)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: Java使用JDBC向数据库存取二进制数据(如图片,视频,音频等)

前言


上次写了一个用JDBC向数据库存取小说等大文本的案例用到了PreparedStatement和io流的相关知识。

Java使用JDBC向数据库存取大文本(比如小说等)

https://blog.csdn.net/weixin_50216991/article/details/120642592

今天我又想起了数据库还可以存取图片,视频,音频等的二进制数据文件,按理来说说任何文件都可以存进数据库。其实和上一期的写法差不多啦,只是数据库存储数据的数据类型和io流不一样罢了,用到的是PreparedStatement的setBinaryStream()这个方法,而不是setCharacterStream()。我也借此机会顺便巩固一下jdbc和io流。


前提知识点


MySQL数据库有一个BLOB的数据类型,是一个可以存储二进制文件的容器,BLOB类型的文件可以是任何文件。


MySQL有4种BLOB类型,如下:

image.png

这里要测试存取音频或图片,我就用MediumBlob吧。

io流FileInputStream就行,其他都和上篇一样。

具体实现步骤

1.打开MySQL,并创建一个名为files的数据库,然后创建数据表。

代码如下(示例):

create database files default character set = "utf8mb4";


image.png

create table myFile(
                       id int primary key ,
                       file mediumblob
);

2.将文件写入到数据库中myFile表的file字段。


创建普通Java项目,把MySQL的jdbc驱动的jar包下载后,导入到项目中,在src目录下创建一个WriteAndReadFile类,D盘根目录下有一个的音频萤火之森.mp3,假设我们就是要把它存入数据库中。然后编WriteAndReadFile类。这次的代码可能不会有那么多注释了,如果你不理解的话就去看我上一篇文章吧。


实现代码如下(示例):

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class WriteAndReadFile {
    //定义方法把文件写入MySQL数据库
    public static void writeFileToMySQL(){
        Connection conn=null;
        PreparedStatement ps=null;
        int result = 0;
        String dbDriver="com.mysql.cj.jdbc.Driver";
        String URL="jdbc:mysql://localhost:3306/files";
        String user="root";
        String pwd="zc20020106";
        try {
            Class.forName(dbDriver);
            conn=DriverManager.getConnection(URL,user,pwd);
            String sql="insert into myFile(id, file) values (?,?)";
            ps=conn.prepareStatement(sql);
            ps.setInt(1,1);
            File file =new File("D:\\idm_download\\萤火之森.mp3");
            //用FileInputStream来存文件
            InputStream in = new FileInputStream(file);
            ps.setBinaryStream(2,in,(int)file.length());
            result= ps.executeUpdate();
            in.close();
            if (result>0){
                System.out.println("音频文件写入成功!");
            }else {
                System.out.println("音频文件写入失败!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //释放资源
            if (ps!=null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) {
        writeFileToMySQL();
    }
}

85d642f52e49475e9451dc02c6d3c66d.png

067f8d3af206429b876bdfc8e84a4da3.png


3.读取数据库里的音频


思路:通过ResultSet的getBinaryStream()方法读取音频,然后通过io流写入到硬盘(src目录下)


代码如下:


import java.io.*;
import java.sql.*;
    public static void ReadFileToLocal(){
        Connection conn=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        String dbDriver="com.mysql.cj.jdbc.Driver";
        String URL="jdbc:mysql://localhost:3306/files";
        String user="root";
        String pwd="zc20020106";
        try {
            Class.forName(dbDriver);
            conn=DriverManager.getConnection(URL,user,pwd);
            String sql="select * from myfile where id=?";
            ps=conn.prepareStatement(sql);
            ps.setInt(1,1);
            rs= ps.executeQuery();
            if (rs.next()){
                InputStream in=rs.getBinaryStream("file");
                OutputStream out=new FileOutputStream("src//萤火之森.mp3");
                byte[] temp=new byte[1024];
                int len=-1;
                while ((len=in.read(temp))!=-1){
                    out.write(temp);
                }
                in.close();
                out.close();
                System.out.println("音频文件读取成功!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //释放资源
            if (rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (ps!=null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) {
        ReadFileToLocal();
    }
}

运行代码:

1373a0942fdf4ed08827dd90f6c15701.png

370ba0265bf04d1e941dd0791dda38a9.png

d5014a7d1fa644cc96a248ae52793ffa.png


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
23天前
|
前端开发 JavaScript Java
java常用数据判空、比较和类型转换
本文介绍了Java开发中常见的数据处理技巧,包括数据判空、数据比较和类型转换。详细讲解了字符串、Integer、对象、List、Map、Set及数组的判空方法,推荐使用工具类如StringUtils、Objects等。同时,讨论了基本数据类型与引用数据类型的比较方法,以及自动类型转换和强制类型转换的规则。最后,提供了数值类型与字符串互相转换的具体示例。
|
2月前
|
存储 Java API
深入剖析Java Map:不只是存储数据,更是设计艺术的体现!
【10月更文挑战第17天】在Java编程中,Map是一种重要的数据结构,用于存储键值对,并展现了设计艺术的精髓。本文深入剖析了Map的设计原理和使用技巧,包括基本概念、设计艺术(如哈希表与红黑树的空间时间权衡)、以及使用技巧(如选择合适的实现类、避免空指针异常等),帮助读者更好地理解和应用Map。
113 3
|
7天前
|
Java 数据库连接 数据库
springboot java.lang.ClassNotFoundException: dm.jdbc.driver.DmDriver应该如何解决
通过上述步骤,可以有效解决Spring Boot项目中遇到的 `java.lang.ClassNotFoundException: dm.jdbc.driver.DmDriver`问题。确保在项目中正确添加达梦数据库的JDBC驱动依赖,并在配置文件中正确配置数据源信息,是解决此问题的关键。通过这些方法,可以确保Spring Boot项目能够正确连接达梦数据库并正常运行。
69 31
|
1月前
|
JSON Java 程序员
Java|如何用一个统一结构接收成员名称不固定的数据
本文介绍了一种 Java 中如何用一个统一结构接收成员名称不固定的数据的方法。
26 3
|
1月前
|
Java 程序员 容器
Java中的变量和常量:数据的‘小盒子’和‘铁盒子’有啥不一样?
在Java中,变量是一个可以随时改变的数据容器,类似于一个可以反复打开的小盒子。定义变量时需指定数据类型和名称。例如:`int age = 25;` 表示定义一个整数类型的变量 `age`,初始值为25。 常量则是不可改变的数据容器,类似于一个锁死的铁盒子,定义时使用 `final` 关键字。例如:`final int MAX_SPEED = 120;` 表示定义一个名为 `MAX_SPEED` 的常量,值为120,且不能修改。 变量和常量的主要区别在于变量的数据可以随时修改,而常量的数据一旦确定就不能改变。常量主要用于防止意外修改、提高代码可读性和便于维护。
|
1月前
|
存储 缓存 安全
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见。本文介绍了使用 `File.createTempFile` 方法和自定义创建临时文件的两种方式,详细探讨了它们的使用场景和注意事项,包括数据缓存、文件上传下载和日志记录等。强调了清理临时文件、确保文件名唯一性和合理设置文件权限的重要性。
103 2
|
1月前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
35 2
|
1月前
|
存储 分布式计算 Java
存算分离与计算向数据移动:深度解析与Java实现
【11月更文挑战第10天】随着大数据时代的到来,数据量的激增给传统的数据处理架构带来了巨大的挑战。传统的“存算一体”架构,即计算资源与存储资源紧密耦合,在处理海量数据时逐渐显露出其局限性。为了应对这些挑战,存算分离(Disaggregated Storage and Compute Architecture)和计算向数据移动(Compute Moves to Data)两种架构应运而生,成为大数据处理领域的热门技术。
68 2
|
1月前
|
SQL Java OLAP
java实现“数据平滑升级”
java实现“数据平滑升级”
44 2
|
2月前
|
SQL Java 关系型数据库
java连接mysql查询数据(基础版,无框架)
【10月更文挑战第12天】该示例展示了如何使用Java通过JDBC连接MySQL数据库并查询数据。首先在项目中引入`mysql-connector-java`依赖,然后通过`JdbcUtil`类中的`main`方法实现数据库连接、执行SQL查询及结果处理,最后关闭相关资源。
202 6