SQLite Visual Basic 简介
在 SQLite Visual Basic 教程的第一章中,我们将提供必要的定义。 我们将展示如何安装 Mono & Visual Basic。 本教程中的所有示例都将在 Mono 上运行。 稍后,我们创建第一个工作示例。
关于 SQLite 数据库
SQLite
是嵌入式关系数据库引擎。 它的开发者称其为自包含,无服务器,零配置和事务型 SQL 数据库引擎。 它非常受欢迎,当今全球有数亿本使用。 SQLite 用于 Solaris 10 和 Mac OS 操作系统,iPhone 或 Skype。 Qt4 库对 SQLite 以及 Python 或 PHP 语言提供了内置支持。 许多流行的应用内部都使用 SQLite,例如 Firefox 或 Amarok。
$ sudo apt-get install sqlite3
如果尚未安装sqlite3
库,则需要安装它。
SQLite 附带sqlite3
命令行工具。 它可用于对数据库发出 SQL 命令。 现在,我们将使用sqlite3
命令行工具创建一个新数据库。
$ sqlite3 test.db
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
我们为sqlite3
工具提供了一个参数。 test.db
是数据库名称。 它是我们磁盘上的单个文件。 如果存在,则将其打开。 如果不是,则创建它。
sqlite> .tables
sqlite> .exit
$ ls
test.db
.tables
命令提供了test.db
数据库中的表列表。 当前没有表。 .exit
命令终止sqlite3
命令行工具的交互式会话。 ls
Unix 命令显示当前工作目录的内容。 我们可以看到test.db
文件。 所有数据将存储在该单个文件中。
Mono
Mono 是基于 C# 和公共语言运行时的 ECMA 标准的 Microsoft .NET Framework 的开源实现。 在本教程中,我们需要安装 Mono 才能编译和运行示例。
可以从 Linux 发行版的包中安装 Mono,也可以从源代码中安装 Mono,以获得更多最新版本。
$ bunzip2 mono-2.10.8.tar.bz2
$ tar -xf mono-2.10.8.tar
$ cd mono-2.10.8/
$ ./configure
$ make
$ sudo make install
我们从 Mono 网站下载mono-2.10.8.tar.bz2
tarball。 我们将其解压缩,构建并安装库。 我们安装了 Mono 运行时,C# 语言和 SQLite .NET 数据适配器。
$ bunzip2 libgdiplus-2.10.9.tar.bz2
$ tar -xf libgdiplus-2.10.9.tar
$ cd libgdiplus-2.10.9/
$ ./configure
$ make
$ sudo make install
对于带有 Winforms 控件的示例,我们还需要libgdiplus
库。 它位于单独的文件中。 我们构建并安装它。
$ sudo ldconfig
$ ldconfig -p | grep libgdiplus
libgdiplus.so.0 (libc6) => /usr/local/lib/libgdiplus.so.0
libgdiplus.so (libc6) => /usr/local/lib/libgdiplus.so
我们还运行ldconfig
工具来更新动态库的数据库。 ldconfig
扫描正在运行的系统,并设置用于加载共享库的符号链接。
Mono.Data.Sqlite
程序集包含 SQLite 数据库的 ADO.NET 数据供应器。 它用 C# 编写,并且可用于所有 CLI 语言,包括 C# ,Visual Basic 和 Boo。
$ ls /usr/local/lib/mono/4.0/Mono.Data.Sqlite.dll
/usr/local/lib/mono/4.0/Mono.Data.Sqlite.dll
从技术角度来看,我们需要一个 DLL。 在我们的系统上,它位于上述路径下。 (实际上,上面的链接是指向 DLL 的软链接,该 DLL 位于gac
子目录中。)
Visual Basic
Visual Basic
是一种现代的,高层通用的,基于对象的编程语言。 它是.NET 框架中第二重要的语言。 该语言的主要设计目标是创建一种易于使用和学习的编程语言。 它源自经典的 BASIC 语言。 Mono 将 Visual Basic 引入 Unix 平台。 它在单独的包中具有 Visual Basic 编译器。
$ bunzip2 mono-basic-2.10.tar.bz2
$ tar xvf mono-basic-2.10.tar
$ cd mono-basic-2.10/
我们从 Mono 项目网站下载资源。 我们对文件进行压缩,然后进入新创建的子目录。
$ ./configure
$ make
$ sudo make install
我们建立&安装编译器。
$ ls /usr/local/bin/vbnc*
/usr/local/bin/vbnc /usr/local/bin/vbnc2
编译器称为 vbnc,默认情况下位于/usr/local/lib/bin
目录中。
ADO.NET
ADO.NET
是.NET 框架的重要组成部分。 该规范统一了对关系数据库,XML 文件和其他应用数据的访问。 从程序员的角度来看,它是一组与数据库和其他数据源一起使用的库和类。 Mono.Data.SQLite
是 SQLite 数据库的 ADO.NET 规范的实现。 它是用 C# 语言编写的驱动程序,可用于所有 .NET 语言。
SqliteConnection
,SqliteCommand
,SqliteDataReader
和SqliteDataAdapter
是.NET 数据供应器模型的核心元素。 SqliteConnection
创建到特定数据源的连接。 SqliteCommand
对象针对数据源执行一条 SQL 语句。 SqliteDataReader
从数据源读取数据流。 SqliteDataAdapter
是DataSet
和数据源之间的中介。 它填充DataSet
并解析数据源的更新。
DataSet
对象用于大量数据的离线工作。 它是一种断开连接的数据表示形式,可以保存来自各种不同来源的数据。 SqliteDataReader
和DataSet
都用于处理数据。 它们在不同的情况下使用。 如果只需要读取查询结果,则SqliteDataReader
是更好的选择。 如果我们需要更广泛的数据处理,或者要将 Winforms 控件绑定到数据库表,则首选DataSet
。
SQLite 版本
如果是第一个程序,我们将检查 SQLite 数据库的版本。
Option Strict On
Imports Mono.Data.Sqlite
Module Example
Sub Main()
Dim con As SqliteConnection
Dim cmd As SqliteCommand
Try
Dim cs As String = "Data Source=:memory:"
con = New SqliteConnection(cs)
con.Open()
Dim stm As String = "SELECT SQLITE_VERSION()"
cmd = New SqliteCommand(stm, con)
Dim version As String = Convert.ToString(cmd.ExecuteScalar())
Console.WriteLine("SQLite version : {0}", version)
Catch ex As SqliteException
Console.WriteLine("Error: " & ex.ToString())
Finally
If cmd IsNot Nothing
cmd.Dispose()
End If
If con IsNot Nothing
Try
con.Close()
Catch ex As SqliteException
Console.WriteLine("Failed closing connection")
Console.WriteLine("Error: " & ex.ToString())
Finally
con.Close()
con.Dispose()
End Try
End If
End Try
End Sub
End Module
我们连接到内存数据库,然后选择 SQLite 版本。
Imports Mono.Data.Sqlite
Mono.Data.SqliteClient
程序集包含 SQLite 数据库引擎的 ADO.NET 数据供应器。 我们导入 SQLite 数据供应器的元素。
Dim con As SqliteConnection
Dim cmd As SqliteCommand
我们声明两个变量。 它们被放置在Try
关键字之前,因为我们稍后将在它们上调用Dispose()
和Close()
方法。
Dim cs As String = "Data Source=:memory:"
这是连接字符串。 数据提供者使用它来建立与数据库的连接。 我们创建一个内存数据库。
con = New SqliteConnection(cs)
创建一个SqliteConnection
对象。 该对象用于打开与数据库的连接。
con.Open()
这行打开数据库连接。
Dim stm As String = "SELECT SQLITE_VERSION()"
这是 SQL SELECT
语句。 它返回数据库的版本。 SQLITE_VERSION()
是内置的 SQLite 函数。
Dim cmd As New SqliteCommand(stm, con)
SqliteCommand
是一个对象,用于在数据库上执行查询。 参数是 SQL 语句和连接对象。
Dim version As String = Convert.ToString(cmd.ExecuteScalar())
有些查询仅返回标量值。 在我们的例子中,我们需要一个简单的字符串来指定数据库的版本。 在这种情况下使用ExecuteScalar()
。 我们避免了使用更复杂的对象的开销。
Console.WriteLine("SQLite version : {0}", version)
数据库的版本将打印到控制台。
Catch ex As SqliteException
Console.WriteLine("Error: " & ex.ToString())
如果发生异常,我们将错误消息打印到控制台。
Finally
If cmd IsNot Nothing
cmd.Dispose()
End If
SqliteCommand
类实现IDisposable
接口。 因此,必须将其显式放置在Finally
块中。
If con IsNot Nothing
Try
con.Close()
Catch ex As SqliteException
Console.WriteLine("Failed closing connection")
Console.WriteLine("Error: " & ex.ToString())
Finally
con.Close()
con.Dispose()
End Try
End If
关闭连接可能会引发另一个异常。 我们处理这种情况。 (尽管这种情况更有可能发生在基于服务器的数据库中,例如 MySQL 或 PostgreSQL。)
$ vbnc version.vb -r:Mono.Data.Sqlite.dll
我们汇编示例。 提供了 SQLite 数据供应器 DLL 的路径。
$ mono version.exe
SQLite version : 3.7.7
这是我们系统上程序的输出。
using
语句
Visual Basic 语言实现垃圾回收。 这是一个自动释放不再需要的对象的过程。 该过程是不确定的。 我们不能确定 CLR(公共语言运行时)何时决定释放资源。 对于有限的资源,例如文件句柄或网络连接,最好尽快释放它们。 使用Using
语句,程序员可以控制何时释放资源。 当程序不在Using
块中时,到达其末尾或引发异常,资源将被释放。
在内部,通过Finally
块中的Dispose()
调用将Using
语句转换为Try
和Finally
块。 请注意,您可能更喜欢使用Try
,Catch
和Finally
块,而不是Using
语句。 特别是,如果您想显式地利用Catch
块。 在本教程中,我们选择了Using
语句。
通常,当我们使用IDisposable
对象时,应在Using
语句中声明并实例化它。 (或在Finally
块中调用Dispose()
。)对于 SQLite ADO.NET 驱动程序,我们对SqliteConnection
,SqliteCommand
,SqliteDataReader
,SqliteCommandBuilder
使用Using
语句。 和SqliteDataAdapter
类。 我们不必将其用于DataSet
。 或DataTable
类。 他们可以留给垃圾收集器。
Option Strict On
Imports Mono.Data.Sqlite
Module Example
Sub Main()
Dim cs As String = "URI=file:test.db"
Using con As New SqliteConnection(cs)
con.Open()
Using cmd As New SqliteCommand(con)
cmd.CommandText = "SELECT SQLITE_VERSION()"
Dim version As String = Convert.ToString(cmd.ExecuteScalar())
Console.WriteLine("SQLite version : {0}", version)
End Using
con.Close()
End Using
End Sub
End Module
我们有同样的例子。 这次我们实现了Using
关键字。
Using con As New SqliteConnection(cs)
con.Open()
Using cmd As New SqliteCommand(con)
SqliteConnection
和SqliteCommand
都实现IDisposable
接口。 因此,它们用Using
关键字包装。
创建并填充表
接下来,我们将创建一个数据库表并用数据填充它。
Option Strict On
Imports Mono.Data.Sqlite
Module Example
Sub Main()
Dim cs As String = "URI=file:test.db"
Using con As New SqliteConnection(cs)
con.Open()
Using cmd As New SqliteCommand(con)
cmd.CommandText = "DROP TABLE IF EXISTS Cars"
cmd.ExecuteNonQuery()
cmd.CommandText = "CREATE TABLE Cars(Id INTEGER PRIMARY KEY," _
& "Name TEXT, Price INT)"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Cars VALUES(1,'Audi',52642)"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Cars VALUES(2,'Mercedes',57127)"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Cars VALUES(3,'Skoda',9000)"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Cars VALUES(4,'Volvo',29000)"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Cars VALUES(5,'Bentley',350000)"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Cars VALUES(6,'Citroen',21000)"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Cars VALUES(7,'Hummer',41400)"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Cars VALUES(8,'Volkswagen',21600)"
cmd.ExecuteNonQuery()
End Using
con.Close()
End Using
End Sub
End Module
在上面的代码示例中,我们创建具有 8 行的Cars
表。
cmd.CommandText = "DROP TABLE IF EXISTS Cars"
cmd.ExecuteNonQuery()
首先,如果该表已经存在,则将其删除。 如果我们不想要结果集,则可以使用ExecuteNonQuery()
方法。 例如,对于DROP
,INSERT
或DELETE
语句。
cmd.CommandText = "CREATE TABLE Cars(Id INTEGER PRIMARY KEY," _
& "Name TEXT, Price INT)"
cmd.ExecuteNonQuery()
Cars
表已创建。 INTEGER PRIMARY KEY
列在 SQLite 中自动增加。
cmd.CommandText = "INSERT INTO Cars VALUES(1,'Audi',52642)"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Cars VALUES(2,'Mercedes',57127)"
cmd.ExecuteNonQuery()
我们在表中插入两行。
sqlite> .mode column
sqlite> .headers on
在sqlite3
命令行工具中,我们修改了数据在控制台中的显示方式。 我们使用列模式并打开标题。
sqlite> SELECT * FROM Cars;
Id Name Price
---------- ---------- ----------
1 Audi 52642
2 Mercedes 57127
3 Skoda 9000
4 Volvo 29000
5 Bentley 350000
6 Citroen 21000
7 Hummer 41400
8 Volkswagen 21600
我们验证数据。 Cars
表已成功创建。
预备语句
现在,我们将以预备语句来关注自己。 在编写预备语句时,我们使用占位符,而不是直接将值写入语句中。 预准备的语句可提高安全性和性能。
Option Strict On
Imports Mono.Data.Sqlite
Module Example
Sub Main()
Dim cs As String = "URI=file:test.db"
Using con As New SqliteConnection(cs)
con.Open()
Using cmd As New SqliteCommand(con)
cmd.CommandText = "INSERT INTO Cars(Name, Price) VALUES(@Name, @Price)"
cmd.Prepare()
cmd.Parameters.AddWithValue("@Name", "BMW")
cmd.Parameters.AddWithValue("@Price", 36600)
cmd.ExecuteNonQuery()
End Using
con.Close()
End Using
End Sub
End Module
我们向Cars
表添加一行。 我们使用参数化命令。
cmd.CommandText = "INSERT INTO Cars(Name, Price) VALUES(@Name, @Price)"
cmd.Prepare()
在这里,我们创建一个预备语句。 在编写预备语句时,我们使用占位符,而不是直接将值写入语句中。 预备语句更快,并且可以防止 SQL 注入攻击。 @Name
和@Price
是占位符,稍后将填充。
cmd.Parameters.AddWithValue("@Name", "BMW")
cmd.Parameters.AddWithValue("@Price", 36600)
值绑定到占位符。
cmd.ExecuteNonQuery()
执行预备语句。 当我们不希望返回任何数据时,我们使用SqliteCommand
对象的ExecuteNonQuery()
方法。
$ mono prepared.exe
sqlite> SELECT * FROM Cars;
Id Name Price
---------- ---------- ----------
1 Audi 52642
2 Mercedes 57127
3 Skoda 9000
4 Volvo 29000
5 Bentley 350000
6 Citroen 21000
7 Hummer 41400
8 Volkswagen 21600
9 BMW 36600
我们有一辆新车插入表。
数据来源
已咨询 MSDN(Microsoft 开发者网络)来创建本教程。 该网站有几种定义。
这是 SQLite Visual Basic 教程的介绍性章节。