MySQL学习——在用Connector/NET处理BLOB数据

MySQL的一个常见用途是将二进制数据存储在BLOB列中。MySQL支持四种不同的BLOB数据类型:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB,所有这些都在BLOB and TEXT Types和 Data Type Storage Requirements中进行了描述。

存储在BLOB列中的数据可以使用MySQL Connector/NET进行访问,并使用客户端代码进行操作。将Connector/NET与BLOB数据一起使用没有特殊要求。

1 准备MySQL服务器

使用MySQL和BLOB数据的第一步是配置服务器。首先,创建一个可以访问的表。文件表通常有四列:

  • 适当大小的AUTO_INCREMENT列(UNSIGNED SMALLINT)用作标识文件的主键,
  • 存储文件名的VARCHAR列,
  • 存储文件大小的UNSIGNED MEDIUMINT列,
  • 存储文件本身的MEDIUMBLOB列。

对于此示例,请使用下表定义:

CREATE TABLE file(
file_id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
file_name VARCHAR(64) NOT NULL,
file_size MEDIUMINT UNSIGNED NOT NULL,
file MEDIUMBLOB NOT NULL);

创建表后,可能需要修改max_allowed_packet系统变量。这个变量决定了一个数据包(即单行)可以发送到MySQL服务器的大小。默认情况下,服务器只接受客户端应用程序的最大为1MB的数据包。如果您打算在文件传输中超过1MB,请增加这个数字。

max_allowed_packet选项可以使用MySQL Workbench服务器管理界面进行修改。将“网络”选项卡的“Data / Memory size”部分中的“允许的最大值”选项调整为适当的设置。调整值后,单击Apply按钮,然后使用MySQL Workbench的Startup/Shutdown屏幕重新启动服务器。您也可以直接在my.cnf文件中调整此值(添加一行读取max_allowed_packet=xxM),或使用SET max_allowed _packet=xxM;MySQL中的语法。

设置max_allowed_packet时尽量保守,因为BLOB数据的传输可能需要一些时间才能完成。尝试设置一个适合您预期用途的值,并在必要时增加该值。

2 将文件写入数据库

要将文件写入数据库,我们需要将文件转换为字节数组,然后将字节数组用作INSERT查询的参数。

以下代码使用FileStream对象打开一个文件,将其读取到字节数组中,并将其插入到文件表中:

C# Code Example
MySql.Data.MySqlClient.MySqlConnection conn;
MySql.Data.MySqlClient.MySqlCommand cmd;conn = new MySql.Data.MySqlClient.MySqlConnection();
cmd = new MySql.Data.MySqlClient.MySqlCommand();string SQL;
UInt32 FileSize;
byte[] rawData;
FileStream fs;conn.ConnectionString = "server=127.0.0.1;uid=root;" +"pwd=12345;database=test";try
{fs = new FileStream(@"c:\image.png", FileMode.Open, FileAccess.Read);FileSize = fs.Length;rawData = new byte[FileSize];fs.Read(rawData, 0, FileSize);fs.Close();conn.Open();SQL = "INSERT INTO file VALUES(NULL, @FileName, @FileSize, @File)";cmd.Connection = conn;cmd.CommandText = SQL;cmd.Parameters.AddWithValue("@FileName", strFileName);cmd.Parameters.AddWithValue("@FileSize", FileSize);cmd.Parameters.AddWithValue("@File", rawData);cmd.ExecuteNonQuery();MessageBox.Show("File Inserted into database successfully!","Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);conn.Close();
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message,"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

Visual Basic Code Example

Dim conn As New MySqlConnection
Dim cmd As New MySqlCommandDim SQL As StringDim FileSize As UInt32
Dim rawData() As Byte
Dim fs As FileStreamconn.ConnectionString = "server=127.0.0.1;" _& "uid=root;" _& "pwd=12345;" _& "database=test"Tryfs = New FileStream("c:\image.png", FileMode.Open, FileAccess.Read)FileSize = fs.LengthrawData = New Byte(FileSize) {}fs.Read(rawData, 0, FileSize)fs.Close()conn.Open()SQL = "INSERT INTO file VALUES(NULL, @FileName, @FileSize, @File)"cmd.Connection = conncmd.CommandText = SQLcmd.Parameters.AddWithValue("@FileName", strFileName)cmd.Parameters.AddWithValue("@FileSize", FileSize)cmd.Parameters.AddWithValue("@File", rawData)cmd.ExecuteNonQuery()MessageBox.Show("File Inserted into database successfully!", _"Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)conn.Close()
Catch ex As ExceptionMessageBox.Show("There was an error: " & ex.Message, "Error", _MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try

FileStream对象的Read方法用于将文件加载到一个字节数组中,该数组的大小根据FileStream对象的Length属性而定。

将字节数组指定为MySqlCommand对象的参数后,将调用ExecuteNonQuery方法,并将BLOB插入到文件表中。

3 将BLOB从数据库读取到磁盘上的文件

将文件加载到文件表中后,我们可以使用MySqlDataReader类来检索它。

以下代码从文件表中检索一行,然后将数据加载到要写入磁盘的FileStream对象中:

C# Code Example
MySql.Data.MySqlClient.MySqlConnection conn;
MySql.Data.MySqlClient.MySqlCommand cmd;
MySql.Data.MySqlClient.MySqlDataReader myData;conn = new MySql.Data.MySqlClient.MySqlConnection();
cmd = new MySql.Data.MySqlClient.MySqlCommand();string SQL;
UInt32 FileSize;
byte[] rawData;
FileStream fs;conn.ConnectionString = "server=127.0.0.1;uid=root;" +"pwd=12345;database=test";SQL = "SELECT file_name, file_size, file FROM file";try
{conn.Open();cmd.Connection = conn;cmd.CommandText = SQL;myData = cmd.ExecuteReader();if (! myData.HasRows)throw new Exception("There are no BLOBs to save");myData.Read();FileSize = myData.GetUInt32(myData.GetOrdinal("file_size"));rawData = new byte[FileSize];myData.GetBytes(myData.GetOrdinal("file"), 0, rawData, 0, (int)FileSize);fs = new FileStream(@"C:\newfile.png", FileMode.OpenOrCreate, FileAccess.Write);fs.Write(rawData, 0, (int)FileSize);fs.Close();MessageBox.Show("File successfully written to disk!","Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);myData.Close();conn.Close();
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message,"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

Visual Basic Code Example

Dim conn As New MySqlConnection
Dim cmd As New MySqlCommand
Dim myData As MySqlDataReader
Dim SQL As String
Dim rawData() As Byte
Dim FileSize As UInt32
Dim fs As FileStreamconn.ConnectionString = "server=127.0.0.1;" _& "uid=root;" _& "pwd=12345;" _& "database=test"SQL = "SELECT file_name, file_size, file FROM file"Tryconn.Open()cmd.Connection = conncmd.CommandText = SQLmyData = cmd.ExecuteReaderIf Not myData.HasRows Then Throw New Exception("There are no BLOBs to save")myData.Read()FileSize = myData.GetUInt32(myData.GetOrdinal("file_size"))rawData = New Byte(FileSize) {}myData.GetBytes(myData.GetOrdinal("file"), 0, rawData, 0, FileSize)fs = New FileStream("C:\newfile.png", FileMode.OpenOrCreate, FileAccess.Write)fs.Write(rawData, 0, FileSize)fs.Close()MessageBox.Show("File successfully written to disk!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)myData.Close()conn.Close()
Catch ex As ExceptionMessageBox.Show("There was an error: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try

连接后,文件表的内容将加载到MySqlDataReader对象中。MySqlDataReader的GetBytes方法用于将BLOB加载到字节数组中,然后使用FileStream对象将其写入磁盘。

MySqlDataReader的GetOrdinal方法可用于确定命名列的整数索引。如果SELECT查询的列顺序发生更改,则使用GetOrdinal方法可以防止出现错误。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/27339.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Apollo9.0 PNC源码学习之Control模块(二)—— controller解析

前面文章:Apollo9.0 PNC源码学习之Control模块(一) 本文将对具体控制器以及原理做一个剖析 1 PID控制器 1.1 PID理论基础 如下图所示,PID各参数(Kp,Ki,Kd)的作用: 任何闭环控制系统的首要任务是要稳、准、快的响…

水表摄像直读抄表仪

1.技术性简述 水表摄像直读抄表仪,是一种前沿的智能计量机器设备,它利用超清摄像头部和图像识别算法,完成了远程控制、非接触的水表载入。这一技术的普及,颠覆了传统式人力抄表的形式,提高了效率,降低了不…

RPA-UiBot6.0控制与运行机器人 —工作任务智能调度自动运行

前言 来也产品文档中心 来也产品文档中心 (laiye.com)https://documents.laiye.com/ 友友们你们是否曾因为例行性工作的繁琐而苦恼?是否想要让机器人帮你自动执行这些任务?小北的这篇博客将为友友们揭示其中的奥秘,让我们一起学习如何通过RP…

计算机组成原理历年考研真题对应知识点(计算机系统层次结构)

目录 1.2计算机系统层次结构 1.2.2计算机硬件 【命题追踪——冯诺依曼计算机的特点(2019)】 【命题追踪——MAR 和 MDR 位数的概念和计算(2010、2011)】 1.2.3计算机软件 【命题追踪——三种机器语言的特点(2015)】 【命题追踪——各种翻译程序的概念(2016)】 1.2.5计算…

python,flask连接数据库

1、直接连接 from flask import Flask from flask_sqlalchemy import SQLAlchemy from sqlalchemy import textapp Flask(__name__)# "mysqlpymysql://账号:密码127.0.0.1:3306/数据库?charsetutf8" app.config[SQLALCHEMY_DATABASE_URI] "mysqlpymysql://…

2024.6.14 刷题总结

2024.6.14 **每日一题** 2786.访问数组中的位置使分数最大,看到这题就想到动态规划的思路,遍历数组,每次选择移动该元素时能获得到的最大值,分别考虑最后一个的元素为奇数/偶数的最大值,用长度为2的数组来储存这两个值…

HTML解析之Beautiful Soup

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 Beautiful Soup是一个用于从HTML和XML文件中提取数据的Python库。Beautiful Soup 提供一些简单的、函数用来处理导航、搜索、修改分析树等功能。Beau…

代码随想录:回溯20-21

51.N皇后 题目 按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回所有不同的 n 皇后问题 的解…

【深度学习】Transformer分类器,CICIDS2017,入侵检测,随机森林、RFE、全连接神经网络

文章目录 1 前言2 随机森林训练3 递归特征消除 RFE Recursive feature elimination4 DNN5 Transformer5.1. 输入嵌入层(Input Embedding Layer)5.2. 位置编码层(Positional Encoding Layer)5.3. Transformer编码器层(T…

堆的实现及其应用

堆的概念 堆是完全二叉树,分为大堆和小堆。大堆:任何一个父亲都大于等于孩子,小堆:任何一个父亲都小于等于孩子。 堆的实现 目录 typedef int HPDataType;typedef struct Heap { HPDataType* a;int size;int capacity; }HP;//交…

高考志愿填报秘籍:未来篇

选择适合自己的大学和专业,对广大考生来说至关重要。从某种程度上来说,决定了考生未来所从事的行业和发展前景。为了帮助广大考生更加科学、合理地填报志愿,选择适合自己的大学和专业,本公众号将推出如何用AI填报高考志愿专栏文章…

C语言之操作符

目录 一、二进制 原码、反码、补码 二、移位操作符 位操作符 三、 逗号表达式 四、下标访问[]、函数调用() 五. 操作符的属性 整型提升 算术转换 六、总结 一、二进制 其实2进制、8进制、10进制、16进制是数值的不同表示形式而已。 其实10进制是生活中经常使用的&am…

MPLS的配置

1、IP可达--- 使用路由协议全网可达 2、配置 MPLS ——LDP [r2]mpls lsr-id 2.2.2.2 必须先定义 mpls 的router-id,要为本地设备的真实ip地址,且邻居可达,因为该地址将用于建立 TCP 会话,建议使用环回地址 [r2]mpls 再开…

嵌入式微处理器重点学习(二)

影响cache命中率的因素 影响Cache命中率的因素主要包括以下几个方面: Cache大小:一般来说,Cache的大小越大,其能够存储的数据也就越多,因此可能缓存更多需要访问的数据,从而提高命中率。但是,增…

MySQL为什么需要事务回滚机制

在MySQL中事务回滚通过日志完成,所有事务进行的修改都会先记录到回滚日志中,然后再对数据库中的对应行进行写入。当事务被提交后就无法回滚了。 回滚日志的作用: 能够在发生错误或用户执行rollback时提供回滚的相关信息。 在整个系统发生崩溃…

Sklearn简介、安装教程、入门学习

当谈到sklearn(scikit-learn)教程时,以下是一个清晰、分点表示和归纳的概述,结合了参考文章中的相关信息: 1. Sklearn简介 定义:Scikit-learn(sklearn)是Python中用于机器学习的开…

类别朴素贝叶斯CategoricalNB和西瓜数据集

CategoricalNB 1 CategoricalNB原理以及用法2 数据集2.1 西瓜数据集2.2 LabelEncoder2.3 OrdinalEncoder 3 代码实现 1 CategoricalNB原理以及用法 (1)具体原理 具体原理可看:贝叶斯分类器原理 sklearn之CategoricalNB对条件概率的原理如下&…

粉丝经济时代:微信订阅号如何助力中小企业增长

在数字化浪潮席卷全球的今天,微信订阅号凭借其独特的优势,成为了中小企业数字化出海的重要工具。作为NetFarmer,我们致力于帮助企业充分利用这一平台,推动业务发展和市场拓展。今天将深入探讨微信订阅号的概念、用途、使用方法、适…

【驱动】使用fdisk、parted等命令制作SD启动卡

1、检查文件大小 计算烧写的文件系统大小 和 SD卡的大小,判断SD是否可以装下文件系统 1.1 计算文件系统大小 1)在终端中输入命令 $ du ./filesystem -b --max-depth=0 661447340 ./filesystem2)在脚本中计算 data_size=$(du ./filesystem -b --max-depth=0 | gre…

mac安装高版本git(更新git)

问题 问题:新下载的idea,此idea的版本较高,但是在工作发现这个版本的git存在一定漏洞会导致一些信息泄露问题。 1.安装Homebrew 对于Mac更新git,最简单的就是使用brew命令。所以我们首先下载homebrew。已下载的同学忽略直接下一…