Skip to content

数据库访问

在 Lua 中,我们可以通过各种库来访问不同类型的数据库。本章节将介绍 Lua 中数据库访问的基本方法和常用库。

LuaSQL

LuaSQL 是 Lua 中最常用的数据库访问库,它支持多种数据库,如 MySQL、PostgreSQL、SQLite 等。

安装 LuaSQL

使用 LuaRocks 安装 LuaSQL:

bash
luarocks install luasql-mysql
luarocks install luasql-postgres
luarocks install luasql-sqlite3

连接 MySQL 数据库

lua
local luasql = require "luasql.mysql"

-- 创建环境
local env = luasql.mysql()

-- 连接数据库
local conn = env:connect("database_name", "username", "password", "localhost", 3306)

-- 执行 SQL 语句
local cursor = conn:execute("SELECT * FROM users")

-- 获取结果
local row = cursor:fetch({} , "a")
while row do
  print(row.id, row.name, row.email)
  row = cursor:fetch(row, "a")
end

-- 关闭资源
cursor:close()
conn:close()
env:close()

连接 SQLite 数据库

lua
local luasql = require "luasql.sqlite3"

-- 创建环境
local env = luasql.sqlite3()

-- 连接数据库
local conn = env:connect("test.db")

-- 创建表
conn:execute[[
  CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT,
    email TEXT
  )
]]

-- 插入数据
conn:execute("INSERT INTO users (name, email) VALUES ('张三', 'zhangsan@example.com')")
conn:execute("INSERT INTO users (name, email) VALUES ('李四', 'lisi@example.com')")

-- 查询数据
local cursor = conn:execute("SELECT * FROM users")
local row = cursor:fetch({} , "a")
while row do
  print(row.id, row.name, row.email)
  row = cursor:fetch(row, "a")
end

-- 关闭资源
cursor:close()
conn:close()
env:close()

LuaDBI

LuaDBI 是另一个流行的数据库访问库,它提供了更高级的接口。

安装 LuaDBI

bash
luarocks install luadbi-mysql
luarocks install luadbi-postgresql
luarocks install luadbi-sqlite3

使用 LuaDBI 连接 MySQL 数据库

lua
local db = require "DBI"

-- 连接数据库
local conn = assert(dbi.Connect("MySQL", "database_name", "username", "password", "localhost", 3306))

-- 准备语句
local stmt = assert(conn:prepare("SELECT * FROM users WHERE id = ?"))

-- 绑定参数并执行
assert(stmt:execute(1))

-- 获取结果
local row = assert(stmt:fetch())
while row do
  print(row[1], row[2], row[3])
  row = stmt:fetch()
end

-- 关闭资源
stmt:close()
conn:close()

Redis 访问

对于 Redis 数据库,可以使用 lua-resty-redis 库(在 OpenResty 环境中)或 lua-redis 库。

使用 lua-redis 连接 Redis

bash
luarocks install redis
lua
local redis = require "redis"

-- 创建连接
local client = redis.connect("127.0.0.1", 6379)

-- 认证(如果需要)
-- client:auth("password")

-- 设置键值
client:set("name", "Lua")

-- 获取键值
local name = client:get("name")
print(name)

-- 关闭连接
client:quit()

MongoDB 访问

对于 MongoDB 数据库,可以使用 lua-mongo 库。

安装 lua-mongo

bash
luarocks install lua-mongo

使用 lua-mongo 连接 MongoDB

lua
local mongo = require "mongo"

-- 创建客户端
local client = mongo.Client("mongodb://127.0.0.1:27017")

-- 获取数据库
local db = client:getDatabase("test")

-- 获取集合
local collection = db:getCollection("users")

-- 插入文档
collection:insert({name = "张三", age = 30, email = "zhangsan@example.com"})

-- 查询文档
local cursor = collection:find({age = {["$gt"] = 25}})
for doc in cursor do
  print(doc.name, doc.age, doc.email)
end

-- 关闭客户端
client:close()

数据库访问的最佳实践

  1. 使用参数化查询:避免 SQL 注入攻击
  2. 错误处理:捕获并处理数据库操作中的错误
  3. 资源管理:及时关闭数据库连接和游标
  4. 连接池:使用连接池来提高性能
  5. 事务处理:对于需要原子性的操作,使用事务

示例:使用事务

lua
local luasql = require "luasql.mysql"

local env = luasql.mysql()
local conn = env:connect("database_name", "username", "password", "localhost", 3306)

-- 开始事务
conn:execute("START TRANSACTION")

begin
  -- 执行操作
  conn:execute("UPDATE accounts SET balance = balance - 100 WHERE id = 1")
  conn:execute("UPDATE accounts SET balance = balance + 100 WHERE id = 2")
  -- 提交事务
  conn:execute("COMMIT")
  print("事务成功")
except
  -- 回滚事务
  conn:execute("ROLLBACK")
  print("事务失败")
end

conn:close()
env:close()

示例:使用连接池

lua
local luasql = require "luasql.mysql"

-- 创建连接池
local pool = {}
local poolSize = 5
local env = luasql.mysql()

-- 初始化连接池
for i = 1, poolSize do
  local conn = env:connect("database_name", "username", "password", "localhost", 3306)
  table.insert(pool, conn)
end

-- 获取连接
function getConnection()
  if #pool > 0 then
    return table.remove(pool)
  else
    -- 创建新连接
    return env:connect("database_name", "username", "password", "localhost", 3306)
  end
end

-- 归还连接
function returnConnection(conn)
  table.insert(pool, conn)
end

-- 使用连接
local conn = getConnection()
-- 执行操作
conn:execute("SELECT * FROM users")
-- 归还连接
returnConnection(conn)

-- 关闭所有连接
for _, conn in ipairs(pool) do
  conn:close()
end
env:close()

小结

本章节介绍了 Lua 中数据库访问的基本方法和常用库,包括 LuaSQL、LuaDBI、Redis 和 MongoDB 的访问。掌握这些内容,对于编写需要与数据库交互的 Lua 程序非常重要。