用VB.NET开发图形数据库
1引言
随着计算机的普及,数据库应用程序越来越得到广泛的应用,带图像的数据库应用程序已成了数据库应用程序不可缺少的一部分,如何将图像信息存储到数据库中、如何用开发工具实现对图形数据库的存取等问
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
已成程序设计者必须解决的问题,如何解决上述问题就成了本文讨论的重点。
2在Access数据库中存储图像信息的
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
在Access数据库中存储图像的方法很多,例如:用OLE对象存储图像信息和用文本存储图像信息等,其中用OLE对象存储图像信息是将图像嵌入到数据库中,这样的好处是当数据库或者原来图像的位置发生变化时程序不需要做特殊的处理,但用OLE对象存储图像信息的数据库会随着图像的增多运行速度逐渐变慢并且占用的存储空间急剧增大,而用文本存储图像信息是用文本字段存放图像的文件名,并将数据库中用到的图像存放到指定的文件夹中,这种方法的好处是数据库占用的存储空间小并且运行速度快。
3用VB.NET对图片信息进行存取的方法
为了介绍上述方法的实现,本人先在Access中分别建立了名为DataBase1.mdb和DataBase2.mdb的学生信息数据库,数据库中都有一个名为Information表,其中一个包含了名为name的文本型字段和名为picture的OLE对象型字段,另一个包含了名为name和picture的两个文本型字段。然后在VB.NET中设计一个如图1所示的窗体,并添加一个名为OpenFileDialog1的OpenFileDialog控件。
图1 窗体的设计界面
3.1用OLE对象存储图片信息
3.1.1总的设计思路
使用OLE对象存储图片信息最关键的问题就是如何将PictureBox控件中的图像信息与OLE对象型字段的
内容
财务内部控制制度的内容财务内部控制制度的内容人员招聘与配置的内容项目成本控制的内容消防安全演练内容
关联起来,这里可以考虑将PictureBox对象中的图像文件读成内存流,用SQL语句插入或更新到OLE对象字段中以二进制形式存储,当从数据库中读取该字段时,将PictureBox对象的图像源设置为来自内存流。
3.1.2代码实现
(1)引入命名空间。由于在程序中用到MemoryStream类和与Access数据库操作相关的类,所以在程序一开始的地方加入以下两个语句引入命名空间:
Imports System.io
Imports System.Data.OleDb
(2)创建连接字符串。用Dim OleDbConnection1 As New OleDbConnection语句创建一个窗体级变量,在窗体的Load事件中设置连接字符串:OleDbConnection1.ConnectionString = "Data Source=""(数据库的存放路径)"";Provider=""Microsoft.Jet.OLEDB.4.0"""
(3)为“上传相片”按钮添加代码。当点击“上传相片”按钮时弹出打开文件对话框,将在打开文件对话框中选中的图片文件作为PictureBox对象的图像源,相关代码如下所示:
If Me.OpenFileDialog1.ShowDialog() = DialogResult.OK Then
picPicture.Image = Image.FromFile(Me.OpenFileDialog1.FileName)
End If
(4)将pictureBox对象中的图像信息转换成无符号的字节数组。先用Save方法将PictureBox对象中的图像信息保存到内存流对象TempMemoryStream中,然后用TempMemoryStream对象的GetBuffer方法返回从其创建此流的无符号字节数组。
Private Function GetImage() As Byte()
Dim TempMemoryStream As New MemoryStream
picPicture.Image.Save(TempMemoryStream, picPicture.Image.RawFormat)
Dim TempImage() As Byte = TempMemoryStream.GetBuffer
TempMemoryStream.Close()
Return TempImage
End Function
(5)将OLE对象字段的内容显示在PictureBox控件中。先用CType函数将OLE对象字段的值转化为字节数组类型,然后用上述所得到的字节数组作为MemoryStream类构造函数的参数来创建MemoryStream对象,最后将PictureBox对象的图像源设置为来源于内存流,相关代码如下所示:
Dim arrPicture() As Byte = CType(InformationTable.Rows(i)("picture"), Byte())
Dim TempMemoryStream As New MemoryStream(arrPicture)
picPicture.Image = Image.FromStream(TempMemoryStream)
(6)为插入、添加和删除按钮添加代码。插入、添加和删除这三个模块的设计思路基本一致:先创建一个OleDbCommand对象,然后设置 OleDbCommand对象要连接的数据源和执行的SQL语句,最后调用ExecuteNonQuery方法执行SQL语句。由于三个模块的代码相似,下面只介绍插入按钮的代码:
Dim InsertCommand As New OleDbCommand
InsertCommand.Connection = OleDbConnection1
InsertCommand.CommandText = "insert into information(name,picture) values(@Name,@Picture)"
InsertCommand.Parameters.Add("@Name", OleDb.OleDbType.VarChar, 0, "name")
InsertCommand.Parameters.Add("@Picture", OleDb.OleDbType.VarBinary, 0, "picture")
InsertCommand.Parameters("@Name").Value = txtName.Text
InsertCommand.Parameters("@Picture").Value = GetImage()
OleDbConnection1.Open()
InsertCommand.ExecuteNonQuery()
OleDbConnection1.Close()
3.2用文本存储图片信息
3.2.1总的设计思路
用文本存储图片信息是在存储图像时只将图像文件的文件名保存在数据库中,并将图像文件存放到指定的文件夹(picture文件夹)下,当浏览
记录
混凝土 养护记录下载土方回填监理旁站记录免费下载集备记录下载集备记录下载集备记录下载
时将指定文件夹下对应文件名的图像显示在PictureBox控件中。
在设计时我们应该注意:本程序模拟的是一个学生信息系统,一条记录对应一个图像文件,为了避免指定文件夹存放多余的图像文件,在一开始数据库为空时指定文件夹也没有任何文件,当添加或修改记录时才将对应的图像文件拷贝到指定文件夹中,当修改或删除记录时也应该删除不需要的图像文件。
3.2.2代码实现
(1)引入命名空间。由于在程序中用到与Access数据库操作相关的类和File类,所以在程序一开始的地方加入以下语句引入命名空间:
Imports System.Data.OleDb
Imports System.io
(2)为窗体的Load事件添加代码。先获取当前程序的运行路径和picture文件夹的路径,然后创建与数据库的关联,将相关数据从数据源提取到DataSet中,最后在窗体中显示数据库的内容。部分代码如下:
Dim CurrentPath As String = Directory.GetCurrentDirectory'获取当前程序的运行路径
Path = CurrentPath + "picture" '获取文件夹picture对应的路径
OleDbConnection1.ConnectionString = "Data Source=""(数据库的存放路径)"";Provider=""Microsoft.Jet.OLEDB.4.0"""
OleDbConnection1.Open()
Dim SelectCommand As New OleDbCommand("select * from Information", OleDbConnection1)
OleDataAdapter1.SelectCommand = SelectCommand
OleDataAdapter1.Fill(DataSet1, "Information")'将满足上面查询条件的内容填充到DataSet1中
OleDbConnection1.Close()
ShowFirstRecord()'显示第一条记录
(4)为“上传相片”按钮添加代码。将在打开文件对话框中选中的图片文件作为PictureBox对象的图像源,同时获取该图片文件的文件名和存放路径。
获取在打开文件对话框中选中的文件名的部分代码如下所示:
index = Me.OpenFileDialog1.FileName.LastIndexOf("")' index存放文件路径中最后一个""的位置
FileNameLength = Me.OpenFileDialog1.FileName.Length - index - 1 ' FileNameLength存放文件名的长度
PictureFileName = Me.OpenFileDialog1.FileName.Substring(index + 1, FileNameLength) ' PictureFileName存放在打开文件对话框中选中的文件的文件名
获取在打开文件对话框中选中的文件的路径(不包含文件名)的代码如下所示:
NewPictureFilePath = Me.OpenFileDialog1.FileName.Substring(0, OpenFileDialog1.FileName.Length - FileNameLength)
(5)为“插入记录”按钮添加代码。先将要插入的图片文件拷贝到指定的文件夹下,如果要插入的图片已经存放在指定文件夹下则不需要拷贝,如果新插入的图片文件名在指定文件夹中已经存在,则应该对新插入的图片重新命名;然后将新建的记录添加到表中并更新数据源;最后显示第一条记录。相关代码如下所示:
'1)如果在打开文件对话框中选中的文件的路径与picture文件夹的路径不同,则将在打开文件对话中选中的图片拷贝到文件夹picture中
If NewPictureFilePath.CompareTo(Path) <> 0 Then
Dim OldPictureFileName As String = NewPictureFileName '将选中的图片的文件名存在OldPictureFileName中
'如果选中的图片文件名与picture文件夹中的图片名相同,请重新命名
While File.Exists(Path + NewPictureFileName)
NewPictureFileName = InputBox("你选择的图片文件名在'picture'文件夹中已存在,请在下面文本框中重新命名该图片文件,文件名要求包含后缀名,如1.jpg", "提示")
End While
'将在打开文件对话中选中的图片拷贝到文件夹picture中
File.Copy(NewPictureFilePath + OldPictureFileName, Path + NewPictureFileName)
End If
'2)将记录插入到表中
Dim InsertCommand As New OleDbCommand
InsertCommand.Connection = OleDbConnection1
InsertCommand.CommandText = "insert into information2(name,picture) values(@Name,@Picture)"
InsertCommand.Parameters.Add("@Name", OleDb.OleDbType.VarChar, 0, "name")
InsertCommand.Parameters.Add("@Picture", OleDb.OleDbType.VarChar, 0, "picture")
InsertCommand.Parameters("@Name").Value = txtName.Text
InsertCommand.Parameters("@Picture").Value = NewPictureFileName
OleDbConnection1.Open()
InsertCommand.ExecuteNonQuery()
OleDbConnection1.Close()
'3)显示第一条记录,目的是更新数据集
ShowFirstRecord()
(6)为“删除记录”按钮添加代码。先删除picture文件夹中对应的图片文件,然后删除当前记录并更新数据源,最后显示第一条记录。部分代码如下所示:
'1)删除picture文件夹中对应的相片(假设一张相片只对应一条记录) picPicture.Image.Dispose() '释放picPicture控件image中的所有资源
File.Delete(Path + PictureFileName)
'2)删除当前记录
Dim DeleteCommand As New OleDbCommand
DeleteCommand.Connection = OleDbConnection1
DeleteCommand.CommandText = "delete from information2 where name=@Name and picture=@Picture"
DeleteCommand.Parameters.Add("@Name", OleDb.OleDbType.VarChar, 0, "name")
DeleteCommand.Parameters.Add("@Picture", OleDb.OleDbType.VarChar, 0, "picture")
DeleteCommand.Parameters("@Name").Value = txtName.Text
DeleteCommand.Parameters("@Picture").Value = PictureFileName
OleDbConnection1.Open()
DeleteCommand.ExecuteNonQuery()
OleDbConnection1.Close()
'3)显示第一条记录,目的是更新数据集
ShowFirstRecord()
(7)为“修改记录”按钮添加代码。如果修改前和修改后的图片不一样,则删除原有图片,将新的图片拷贝到指定目录上,然后修改记录并更新数据源。部分代码如下所示:
'1)如果修改前和修改后的图片不一样,则删除原有图片
If (NewPictureFilePath + NewPictureFileName).CompareTo(Path + PictureFileName) <> 0 Then
picPicture.Image.Dispose()
File.Delete(Path + PictureFileName)
End If
'2)如果在打开文件对话框中选中的文件的路径与picture文件夹的路径不同,则将在打开文件对话中选中的图片拷贝到文件夹picture中,代码与“插入记录”的代码相同,这里省略。
'3)修改记录
Dim ChangeCommand As New OleDbCommand
ChangeCommand.Connection = OleDbConnection1
ChangeCommand.CommandText = "update information2 set name=@Name,picture=@Picture where 编号=@Id"
ChangeCommand.Parameters.Add("@Name", OleDb.OleDbType.VarChar, 0, "name")
ChangeCommand.Parameters.Add("@Picture", OleDb.OleDbType.VarChar, 0, "picture")
ChangeCommand.Parameters.Add("@Id", OleDb.OleDbType.Integer, 0, "编号")
ChangeCommand.Parameters("@Name").Value = txtName.Text
ChangeCommand.Parameters("@Picture").Value = NewPictureFileName
ChangeCommand.Parameters("@Id").Value = id
OleDbConnection1.Open()
ChangeCommand.ExecuteNonQuery()
OleDbConnection1.Close()
'4)显示第一条记录,目的是更新数据集
ShowFirstRecord()
4小结
从程序的测试结果看,当两个数据库都存储相同的信息时,用OLE对象存储图像信息的数据库所占的存储空间是用文本存储图像信息的数据库和存放图像的picture文件夹所占的存储空间之和的一倍,并且对用OLE对象存储图像信息的数据库进行访问的时间很大程度是由图像的大小决定,图像越大访问时间越长,而对用文本存储图像信息的数据库中的不同图像大小的记录进行访问的时间基本都相同,并且比前者快得多。因此,从数据占用的存储空间和对数据库的访问效率上看,第二种方法的优势更大。