Lua进阶教程(五)数据库编程
简介
对于简单的数据操作,我们可能会使用文件,但有时,这些文件操作可能不高效、不可扩展,也不够强大。为此,需要使用数据库。LuaSQL是一个库,提供了Lua到许多数据库管理系统的简单接口。 它支持下面不同类型的SQL:
- SQLite
- Mysql
- ODBC
本教程将介绍Lua中MySQL和SQLite的数据库处理。两者都使用通用接口,可以移植到其他类型的数据库。首先,看看如何在MySQL中执行操作。
Mysql 数据库处理
设置MySQL数据库
首先按下面步骤设置MySQL数据库:
- 安装并设置MySQL,默认用户为root,密码为’123456’。
- 创建名为’test’的数据库。
- 假设你熟悉MySQL基础知识。
导入MySQL库
假设您的Lua实现正确,可以使用一个简单的require语句来导入mysql库:
mysql = require "luasql.mysql"
变量mysql将通过引用主表提供其中MySql数据库操作函数的访问。
设置连接
可以通过启动MySQL环境,然后为环境创建连接来设置连接。如下所示。
local env = mysql.mysql()
local conn = env:connect(’test‘,’root‘,’123456‘)
上述连接将连接到现有的MySQL数据库,并与新创建的数据库建立连接。
执行函数
连接有一个简单的execute函数,可以执行从创建、插入、删除、更新等所有数据库操作。语法如下所示:
conn:execute([[MySQL_STATEMENT]])
在上述语法中,需要确保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 )
运行上述程序时,将创建一个名为sample2表,其中包含两列,即id和name。
MySQL environment (004BB178) MySQL connection (004BE3C8)
0 nil
如果出现任何错误,将返回一个错误语句,而不是零。一个简单的错误语句如下所示:
status, errorString = conn:execute([[CREATE TABLE sample2 (id INTEGER, name TEXT);]])
示例:插入语句
conn:execute([[INSERT INTO sample values('11','Raj')]])
示例:更新语句
conn:execute([[UPDATE sample3 SET name='John' WHERE id ='12']])
示例:删除语句
conn:execute([[DELETE FROM sample3 WHERE id ='12']])
示例:选择语句
选择语句返回一组数据,需要循环遍历每行提取所需的数据。一个简单的选择语句如下所示:
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))
row = cursor:fetch(row, "a")
end
在上述代码中,conn是一个打开的MySQL连接。在执行语句返回的游标的帮助下,可以循环遍历表,并获取所需数据。
完整示例
下面是一个完整的示例,包括上述所有陈语句:
mysql = require "luasql.mysql"
local env = mysql.mysql()
local conn = env:connect('test', 'root', '123456')
status, errorString = conn:execute([[CREATE TABLE sample3 (id INTEGER, name TEXT)]])
status, errorString = conn:execute([[INSERT INTO sample3 VALUES('12', 'Raj')]])
cursor, errorString = conn:execute([[SELECT * FROM sample3]])
row = cursor:fetch({}, "a")
while row do
print(string.format("Id: %s, Name: %s", row.id, row.name))
row = cursor:fetch(row, "a")
end
cursor:close()
conn:close()
env:close()
运行上述程序时,将得到以下输出:
MySQL environment (0037B178) MySQL connection (0037EBA8)
0 nil
1 nil
MySQL cursor (003778A8) nil
Id: 12, Name: Raj
执行事务
事务是一种确保数据一致性的机制。事务应具有以下四个特性:
- 原子性:事务要么完全执行,要么完全不执行。
- 一致性:事务必须从一致状态开始,并在结束时保持系统处于一致状态。
- 隔离性:事务的中间结果在当前事务之外不可见。
- 持久性:一旦事务提交,其效果就是持久的,即使系统出现故障。
事务以START TRANSACTION语句开始,以commit或rollback语句结束。
开始事务
要启动事务,需要在Lua中执行以下语句,假设conn是一个打开的MySQL连接:
conn:execute([[START TRANSACTION;]])
回滚事务
要回滚在执行start transaction后所做的更改,需要执行以下语句:
conn:execute([[ROLLBACK;]])
提交事务
要提交在执行start transaction后所做的更改,需要执行以下语句:
conn:execute([[COMMIT;]])
上面介绍了MySQL,解释了基本的SQL操作。尽管没有为SQLite3再次解释,但相同的语句也应该适用于SQLite3。
SQLite数据库处理
导入SQLite
假设Lua实现正确,可以使用一个简单的require语句来导入SQLite库。在安装过程中,有一个包含数据库相关文件的文件夹libsql。
sqlite3 = require "luasql.sqlite3"
变量sqlite3将通过引用主sqlite3表来提供对SQL函数的访问。
建立连接
可以通过初始化SQLite环境然后为该环境创建一个连接来建立连接。如下所示:
local env = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')
执行函数
连接中有一个简单的execute函数,可以帮助我们执行所有数据库操作,包括创建、插入、删除、更新等。语法如下所示:
conn:execute([[ 'SQLite3_STATEMENT' ]])
在上述语法中,需要确保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 )
运行上述程序时,将创建一个名为sample的表,其中包含两列,即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')]])
选择语句示例
对于选择语句,需要循环遍历每一行并提取所需的数据。以下是一个简单的选择语句示例:
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))
row = cursor:fetch(row, "a")
end
在上述代码中,conn是一个打开的sqlite3连接。通过返回的游标,可以循环遍历表,并获取所需数据。
完整示例
以下是包含所有上述语句的完整示例:
sqlite3 = require "luasql.sqlite3"
local env = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')
status, errorString = conn:execute([[CREATE TABLE sample ('id' INTEGER, 'name' TEXT)]])
status, errorString = conn:execute([[INSERT INTO sample VALUES('1','Raj')]])
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))
row = cursor:fetch(row, "a")
end
-- 关闭所有连接
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 库,我们可以执行所有可用的查询。因此,请不要止步于这些示例,我们鼓励你在在相应的MySQL、SQLite3和Lua支持的其他数据库中, 尝试各种不同的查询语句。