Leafo/Lapis 数据库访问指南:从基础到实践
概述
Leafo/Lapis 是一个基于 OpenResty 的 Lua Web 框架,提供了强大的数据库访问功能。本文将深入介绍 Lapis 中的数据库访问机制,包括连接配置、查询接口以及高级用法。
支持的数据库类型
Lapis 支持三种主流数据库:
- PostgreSQL:通过 pgmoon 库实现,支持异步查询和连接池
- MySQL:在 OpenResty 环境下使用 lua-resty-mysql,其他环境使用 LuaSQL-MySQL
- SQLite:通过 LuaSQLite3 实现,查询是阻塞式的
数据库模块结构
Lapis 提供了分层模块结构来处理数据库操作:
lapis.db
:基础查询功能(连接管理、查询、插入等)lapis.db.model
:ORM 模型基类lapis.db.schema
:数据库模式变更(创建表、索引等)
这些模块会根据配置自动选择对应的数据库实现(如 PostgreSQL 或 MySQL)。
连接配置详解
PostgreSQL 配置示例
-- config.lua
local config = require("lapis.config")
config("development", {
postgres = {
host = "127.0.0.1",
user = "pg_user",
password = "the_password",
database = "my_database"
}
})
MySQL 配置示例
-- config.lua
local config = require("lapis.config")
config("development", {
mysql = {
host = "127.0.0.1",
user = "mysql_user",
password = "the_password",
database = "my_database"
}
})
SQLite 配置示例
-- config.lua
local config = require("lapis.config")
config("development", {
sqlite = {
database = "my_database.sqlite"
}
})
提示:可以使用
":memory:"
作为数据库名创建临时内存数据库
查询接口详解
基础查询方法
- 直接查询:使用
db.query
执行原始 SQL - 模型查询:通过 Model 类进行 ORM 风格操作
直接查询示例
local db = require("lapis.db")
local res = db.query("SELECT * FROM users WHERE id = ?", 10)
模型查询示例
local Model = require("lapis.db.model").Model
local Users = Model:extend("users")
local user = Users:find(10)
高级查询方法
1. db.query(query, params...)
执行原始 SQL 查询,支持参数化查询防止 SQL 注入:
local res = db.query("UPDATE products SET stock = ? WHERE id = ?", 5, 123)
2. db.insert(table, values, opts)
插入数据到指定表:
local res = db.insert("products", {
name = "Laptop",
price = 999.99,
in_stock = true
}, { returning = "id" })
3. db.update(table, values, conditions)
更新满足条件的数据:
local res = db.update("users", {
status = "active",
last_login = os.time()
}, {
id = 100
})
4. db.delete(table, conditions)
删除满足条件的数据:
local res = db.delete("sessions", {
expired = true,
user_id = 42
})
数据库原始类型
Lapis 提供了一系列原始类型来安全构建查询:
1. db.raw(str)
插入原始 SQL 片段:
db.update("counters", {
views = db.raw("views + 1")
}, { id = 5 })
2. db.NULL
表示 SQL NULL 值:
db.update("users", {
middle_name = db.NULL
}, { id = 10 })
3. db.list(array)
生成 SQL IN 子句:
local admins = db.select("* from users where id in ?", db.list({1, 5, 10}))
最佳实践
- 优先使用模型:Model 类提供了更高级的抽象,减少 SQL 错误
- 始终参数化查询:防止 SQL 注入攻击
- 合理使用连接池:Lapis 自动管理连接池,无需手动处理
- 日志监控:所有查询默认记录到 Nginx 日志,便于调试
常见问题
Q:如何处理事务?
A:Lapis 没有直接提供事务接口,但可以通过原始查询执行:
db.query("BEGIN")
db.query("UPDATE accounts SET balance = balance - 100 WHERE id = 1")
db.query("UPDATE accounts SET balance = balance + 100 WHERE id = 2")
db.query("COMMIT")
Q:如何执行复杂连接查询?
A:可以使用 raw SQL 或结合模型关系:
local res = db.query([[
SELECT p.*, u.name as user_name
FROM posts p
JOIN users u ON p.user_id = u.id
WHERE p.published = true
]])
通过本文的介绍,您应该已经掌握了 Lapis 数据库访问的核心概念和实用技巧。无论是简单的 CRUD 操作还是复杂的查询需求,Lapis 都提供了灵活而强大的工具来满足您的开发需求。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考