Lua - 数据库访问

  • 简述

    对于简单的数据操作,我们可能会使用文件,但有时,这些文件操作可能效率不高、可扩展性不强、功能不强大。为此,我们可能经常切换到使用数据库。LuaSQL 是一个从 Lua 到许多数据库管理系统的简单接口。LuaSQL 是一个库,它为不同类型的 SQL 提供支持。这包括,
    • SQLite
    • mysql
    • ODBC
    在本教程中,我们将介绍 Lua 中 MySQL 和 SQLite 的数据库处理。这对两者都使用通用接口,并且应该可以将此实现移植到其他类型的数据库。首先让我们看看如何在 MySQL 中进行操作。
  • MySQL 数据库设置

    为了使用以下示例按预期工作,我们需要初始数据库设置。下面列出了这些假设。
    • 您已安装并设置 MySQL,默认用户为 root,密码为“123456”。
    • 您已经创建了一个数据库测试。
    • 你已经通过 MySQL 教程了解了 MySQL 教程.
  • 导入 MySQL

    我们可以使用一个简单的 require 假设您的 Lua 实现已正确完成,则导入 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 类型整数和名称类型 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 )
    
    当您运行上述程序时,将创建一个名为 sample 的表,其中包含 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 语句而言,我们需要遍历每一行并提取所需的数据。一个简单的选择语句如下所示。
    
    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 连接。借助 execute 语句返回的游标,您可以遍历表响应并获取所需的选择数据。
  • 一个完整的例子

    下面给出了包括上述所有语句的完整示例。
    
    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
    
  • 执行事务

    事务是一种确保数据一致性的机制。事务应具有以下四个属性 -
    • Atomicity - 事务完成或什么也没有发生。
    • Consistency − 事务必须以一致状态开始,并使系统处于一致状态。
    • Isolation − 事务的中间结果在当前事务之外不可见。
    • Durability − 一旦事务被提交,即使在系统出现故障之后,影响也是持久的。
    事务以 START TRANSACTION 开始;并以 commit 或 rollback 语句结束。
  • 开始事务

    为了发起一个事务,我们需要在 Lua 中执行以下语句,假设 conn 是一个开放的 MySQL 连接。
    
    conn:execute([[START TRANSACTION;]])
    
  • 回滚事务

    我们需要执行以下语句来回滚执行 start 事务后所做的更改。
    
    conn:execute([[ROLLBACK;]])
    
  • 提交事务

    我们需要执行以下语句来提交执行 start 事务后所做的更改。
    
    conn:execute([[COMMIT;]])
    
    我们在上面已经了解了 MySQL,下面的部分将解释基本的 SQL 操作。记住事务,虽然没有为 SQLite3 再次解释,但同样的语句也适用于 SQLite3。
  • 导入 SQLite

    我们可以使用一个简单的 require 语句来导入 SQLite 库,假设您的 Lua 实现已正确完成。在安装过程中,包含数据库相关文件的文件夹 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 类型整数和名称类型 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')]])
    
  • 选择语句示例

    就 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 连接。借助 execute 语句返回的游标,您可以遍历表响应并获取所需的选择数据。
  • 一个完整的例子

    下面给出了包括上述所有语句的完整示例。
    
    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 库的帮助下执行所有可用的查询。所以,请不要停留在这些例子上。在各自的 MySQL、SQLite3 和 Lua 中支持的其他数据库中试验各种可用的查询语句。