Lua - 数据库访问


对于简单的数据操作,我们可能会使用文件,但是,有时,这些文件操作可能并不高效、可扩展且功能强大。为此,我们可能经常转而使用数据库。LuaSQL 是 Lua 到许多数据库管理系统的简单接口。LuaSQL 是一个库,它提供了对不同类型 SQL 的支持。这包括,

  • SQLite
  • mysql
  • ODBC

在本教程中,我们将介绍 Lua 中 MySQL 和 SQLite 的数据库处理。这对两者使用通用接口,并且也应该可以将此实现移植到其他类型的数据库。首先让我们看看如何在 MySQL 中进行操作。

MySQL 数据库设置

为了使用以下示例按预期工作,我们需要初始数据库设置。下面列出了假设。

  • 您已经安装并设置了 MySQL,默认用户为 root,密码为“123456”。

  • 您已经创建了一个数据库测试。

  • 您已完成 MySQL 教程以了解MySQL 基础知识。

导入MySQL

假设您的 Lua 实现正确完成,我们可以使用一个简单的require语句来导入 sqlite 库。

mysql = require "luasql.mysql"

变量 mysql 将通过引用主 mysql 表来提供对函数的访问。

设置连接

我们可以通过启动MySQL环境,然后为该环境创建连接来建立连接。如下所示。

local env  = mysql.mysql()
local conn = env:connect('test','root','123456')

上述连接将连接到现有的 MySQL 文件并与新创建的文件建立连接。

执行函数

连接有一个简单的执行函数,可以帮助我们执行创建、插入、删除、更新等所有数据库操作。语法如下所示 -

conn:execute([[ 'MySQLSTATEMENT' ]])

在上面的语法中,我们需要确保 conn 已打开且存在 MySQL 连接,并将“MySQLSTATEMENT”替换为正确的语句。

创建表示例

下面显示了一个简单的创建表示例。它创建一个带有两个参数 id(整数类型)和 name(varchar 类型)的表。

mysql = require "luasql.mysql"

local env  = mysql.mysql()
local conn = env:connect('test','root','123456')

print(env,conn)

status,errorString = conn:execute([[CREATE TABLE sample2 (id INTEGER, name TEXT);]])
print(status,errorString )

当您运行上述程序时,将创建一个名为 example 的表,其中包含两列,即 id 和 name。

MySQL environment (004BB178)	MySQL connection (004BE3C8)
0	nil

如果出现任何错误,您将返回错误语句而不是 nil。一个简单的错误语句如下所示。

LuaSQL: Error executing query. MySQL: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"id INTEGER, name TEXT)' at line 1

插入语句示例

MySQL 的插入语句如下所示。

conn:execute([[INSERT INTO sample values('11','Raj')]])

更新语句示例

MySQL 的更新语句如下所示。

conn:execute([[UPDATE sample3 SET name='John' where id ='12']])

删除语句示例

MySQL 的删除语句如下所示。

conn:execute([[DELETE from sample3 where id ='12']])

选择语句示例

就 select 语句而言,我们需要循环遍历每一行并提取所需的数据。一个简单的 select 语句如下所示。

cursor,errorString = conn:execute([[select * from sample]])
row = cursor:fetch ({}, "a")

while row do
   print(string.format("Id: %s, Name: %s", row.id, row.name))
   -- reusing the table of results
   row = cursor:fetch (row, "a")
end

在上面的代码中,conn是一个打开的MySQL连接。借助执行语句返回的游标,您可以循环遍历表响应并获取所需的选择数据。

一个完整的例子

下面给出了包含所有上述语句的完整示例。

mysql = require "luasql.mysql"

local env  = mysql.mysql()
local conn = env:connect('test','root','123456')
print(env,conn)

status,errorString = conn:execute([[CREATE TABLE sample3 (id INTEGER, name TEXT)]])
print(status,errorString )

status,errorString = conn:execute([[INSERT INTO sample3 values('12','Raj')]])
print(status,errorString )

cursor,errorString = conn:execute([[select * from sample3]])
print(cursor,errorString)

row = cursor:fetch ({}, "a")

while row do
   print(string.format("Id: %s, Name: %s", row.id, row.name))
   row = cursor:fetch (row, "a")
end

-- close everything
cursor:close()
conn:close()
env:close()

当您运行上述程序时,您将得到以下输出。

MySQL environment (0037B178)	MySQL connection (0037EBA8)
0	nil
1	nil
MySQL cursor (003778A8)	nil
Id: 12, Name: Raj

执行交易

事务是一种保证数据一致性的机制。交易应具有以下四个属性 -

  • Atomics性- 事务要么完成,要么什么也没有发生。

  • 一致性- 事务必须以一致的状态开始并使系统处于一致的状态。

  • 隔离- 事务的中间结果在当前事务之外不可见。

  • 持久性- 一旦事务被提交,即使在系统发生故障之后,其影响也是持久的。

事务以 START TRANSACTION 开始;并以提交或回滚语句结束。

开始交易

为了启动事务,我们需要在 Lua 中执行以下语句,假设 conn 是一个打开的 MySQL 连接。

conn:execute([[START TRANSACTION;]])

回滚事务

我们需要执行以下语句来回滚执行 start transaction 后所做的更改。

conn:execute([[ROLLBACK;]])

提交交易

我们需要执行以下语句来提交执行 start transaction 后所做的更改。

conn:execute([[COMMIT;]])

上面我们已经了解了MySQL,下面将介绍基本的SQL操作。请记住事务,虽然没有针对 SQLite3 再次解释,但相同的语句也应该适用于 SQLite3。

导入 SQLite

假设您的 Lua 实现正确完成,我们可以使用一个简单的 require 语句来导入 SQLite 库。在安装过程中,会出现一个包含数据库相关文件的文件夹 libsql。

sqlite3 = require "luasql.sqlite3"

变量 sqlite3 将通过引用主 sqlite3 表来提供对函数的访问。

设置连接

我们可以通过启动 SQLite 环境然后为该环境创建连接来设置连接。如下所示。

local env  = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')

上述连接将连接到现有的 SQLite 文件或创建新的 SQLite 文件并与新创建的文件建立连接。

执行函数

连接有一个简单的执行函数,可以帮助我们执行创建、插入、删除、更新等所有数据库操作。语法如下所示 -

conn:execute([[ 'SQLite3STATEMENT' ]])

在上面的语法中,我们需要确保 conn 已打开并且存在 sqlite3 连接,并将“SQLite3STATEMENT”替换为正确的语句。

创建表示例

下面显示了一个简单的创建表示例。它创建一个带有两个参数 id(整数类型)和 name(varchar 类型)的表。

sqlite3 = require "luasql.sqlite3"

local env  = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')
print(env,conn)

status,errorString = conn:execute([[CREATE TABLE sample ('id' INTEGER, 'name' TEXT)]])
print(status,errorString )

当您运行上述程序时,将创建一个名为 example 的表,其中包含两列,即 id 和 name。

SQLite3 environment (003EC918)	SQLite3 connection (00421F08)
0	nil

如果出现错误,您将返回错误语句而不是 nil。一个简单的错误语句如下所示。

LuaSQL: unrecognized token: ""'id' INTEGER, 'name' TEXT)"

插入语句示例

SQLite 的插入语句如下所示。

 conn:execute([[INSERT INTO sample values('11','Raj')]])

选择语句示例

就 select 语句而言,我们需要循环遍历每一行并提取所需的数据。一个简单的 select 语句如下所示。

cursor,errorString = conn:execute([[select * from sample]])
row = cursor:fetch ({}, "a")

while row do
   print(string.format("Id: %s, Name: %s", row.id, row.name))
   -- reusing the table of results
   row = cursor:fetch (row, "a")
end

在上面的代码中,conn是一个打开的sqlite3连接。借助执行语句返回的游标,您可以循环遍历表响应并获取所需的选择数据。

一个完整的例子

下面给出了包含所有上述语句的完整示例。

sqlite3 = require "luasql.sqlite3"

local env  = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')
print(env,conn)

status,errorString = conn:execute([[CREATE TABLE sample ('id' INTEGER, 'name' TEXT)]])
print(status,errorString )

status,errorString = conn:execute([[INSERT INTO sample values('1','Raj')]])
print(status,errorString )

cursor,errorString = conn:execute([[select * from sample]])
print(cursor,errorString)

row = cursor:fetch ({}, "a")

while row do
   print(string.format("Id: %s, Name: %s", row.id, row.name))
   row = cursor:fetch (row, "a")
end

-- close everything
cursor:close()
conn:close()
env:close()

当您运行上述程序时,您将得到以下输出。

SQLite3 environment (005EC918)	SQLite3 connection (005E77B0)
0	nil
1	nil
SQLite3 cursor (005E9200)	nil
Id: 1, Name: Raj

我们可以借助这个 libsql 库执行所有可用的查询。所以,请不要仅限于这些例子。在 Lua 中试验各自 MySQL、SQLite3 和其他支持的数据库中可用的各种查询语句。