SQLite Visual Basic 教程介绍
最后修改于 2020 年 7 月 6 日
在 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 是基于 ECMA 标准的 Microsoft .NET Framework 的开源实现,用于 C# 和公共语言运行时。 我们需要安装 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 的软链接,它位于 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 块时,要么到达它的末尾,要么抛出异常,资源就会被释放。
在内部,Using
语句被转换为 Try
、Finally
块,并在 Finally
块中调用 Dispose
。 请注意,您可能更喜欢使用 Try
、Catch
、Finally
块而不是 Using 语句。 特别是,如果您想显式使用 Catch
块。 在本教程中,我们选择了 Using
语句。
通常,当我们使用 IDisposable
对象时,我们应该在 Using 语句中声明和实例化它。(或在 Finally
块中调用 Dispose
。)对于 SQLite ADO.NET 驱动程序,我们对 SqliteConnection
、SqliteCommand
、SqliteDataReader
、SqliteCommandBuilder
和 SqliteDataAdapter
类使用 Using
语句。 我们不必对 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
在上面的代码示例中,我们创建了一个 Cars
表,其中包含 8 行。
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 教程的介绍性章节。