查询构建器
查询构建器是 Sleet ORM 的核心功能,提供了类型安全的 SQL 查询构建方法。
SELECT 查询
基础查询
lua
local sl = Sleet
local db = sl.connect()
-- 查询所有记录
local allPlayers = db.select().from(s.players).execute()
-- 查询指定列
local names = db.select({ s.players.id, s.players.name })
.from(s.players)
.execute()条件查询
lua
-- WHERE 条件
local player = db.select()
.from(s.players)
.where(sl.eq(s.players.id, 123))
.execute()
-- 复杂条件
local activePlayers = db.select()
.from(s.players)
.where(sl.and_(
sl.eq(s.players.is_active, true),
sl.gte(s.players.level, 10)
))
.execute()排序和分页
lua
-- 排序查询
local sortedPlayers = db.select()
.from(s.players)
.orderBy(s.players.name, 'asc') -- 'asc' 或 'desc'
.execute()
-- 分页查询
local page2 = db.select()
.from(s.players)
.limit(20)
.offset(40)
.execute()JOIN 查询
lua
-- LEFT JOIN
local playerOrders = db.select()
.from(s.orders)
.leftJoin(s.players, sl.eq(s.orders.player_id, s.players.id))
.where(sl.eq(s.players.identifier, identifier))
.execute()
-- INNER JOIN
local activeOrders = db.select()
.from(s.orders)
.innerJoin(s.players, sl.eq(s.orders.player_id, s.players.id))
.where(sl.eq(s.players.is_active, true))
.execute()
-- RIGHT JOIN
local allPlayersWithOrders = db.select()
.from(s.orders)
.rightJoin(s.players, sl.eq(s.orders.player_id, s.players.id))
.execute()分组查询
lua
-- GROUP BY
local groupedStats = db.select({
s.players.level,
sl.sql('COUNT(*) as player_count')
})
.from(s.players)
.groupBy(s.players.level)
.execute()软删除支持
lua
-- 包含已软删除的记录
local allPlayers = db.select()
.from(s.players)
.withDeleted()
.execute()INSERT 操作
插入单条记录
lua
-- 插入新记录
local newId = db.insert(s.players)
.values({
identifier = 'steam:110000103fa6cc0',
name = 'NewPlayer',
money = 1000
})
.execute()
print("新插入的 ID:", newId)批量插入
lua
-- 批量插入多条记录
local ids = db.insert(s.players)
.values({
{ identifier = 'steam:001', name = '玩家1' },
{ identifier = 'steam:002', name = '玩家2' },
{ identifier = 'steam:003', name = '玩家3' }
})
.execute()UPDATE 操作
基础更新
lua
-- 更新记录
local affected = db.update(s.players)
.set({
money = 5000,
last_seen = sl.sql('NOW()')
})
.where(sl.eq(s.players.id, playerId))
.execute()
print("更新了", affected, "行记录")原子操作
lua
-- 安全的数值增减(防止并发问题)
db.update(s.players)
.set({
money = sl.sql('`money` + ?', { 1000 }),
bank = sl.sql('`bank` - ?', { 500 })
})
.where(sl.eq(s.players.id, playerId))
.execute()DELETE 操作
基础删除
lua
-- 删除记录
local deleted = db.delete(s.players)
.where(sl.eq(s.players.id, playerId))
.execute()
print("删除了", deleted, "行记录")批量删除
lua
-- 删除多条记录
db.delete(s.players)
.where(sl.lt(s.players.last_seen, '2024-01-01'))
.execute()方法参考
SELECT 方法
| 方法 | 参数 | 描述 |
|---|---|---|
from(table) | table: 表定义 | 指定查询的表 |
where(condition) | condition: 条件表达式 | 添加 WHERE 条件 |
limit(n) | n: number | 限制返回结果数量 |
offset(n) | n: number | 跳过指定数量的记录 |
orderBy(column, direction) | column: 列定义, direction: 'asc'|'desc' | 排序 |
groupBy(column) | column: 列定义 | 分组 |
leftJoin(table, on) | table: 表定义, on: 条件表达式 | LEFT JOIN |
innerJoin(table, on) | table: 表定义, on: 条件表达式 | INNER JOIN |
rightJoin(table, on) | table: 表定义, on: 条件表达式 | RIGHT JOIN |
withDeleted() | 无 | 包含软删除的记录 |
execute() | 无 | 执行查询并返回结果 |
toSQL() | 无 | 返回 SQL 字符串和参数 |
INSERT 方法
| 方法 | 参数 | 描述 |
|---|---|---|
values(data) | data: table|table[] | 要插入的数据 |
execute() | 无 | 执行插入并返回新记录的 ID |
toSQL() | 无 | 返回 SQL 字符串和参数 |
UPDATE 方法
| 方法 | 参数 | 描述 |
|---|---|---|
set(data) | data: table | 要更新的数据 |
where(condition) | condition: 条件表达式 | 添加 WHERE 条件 |
execute() | 无 | 执行更新并返回受影响的行数 |
toSQL() | 无 | 返回 SQL 字符串和参数 |
DELETE 方法
| 方法 | 参数 | 描述 |
|---|---|---|
where(condition) | condition: 条件表达式 | 添加 WHERE 条件 |
execute() | 无 | 执行删除并返回受影响的行数 |
toSQL() | 无 | 返回 SQL 字符串和参数 |
调试查询
查看生成的 SQL
lua
-- 获取 SQL 和参数而不执行
local sql, params = db.select()
.from(s.players)
.where(sl.eq(s.players.id, 123))
.toSQL()
print("SQL:", sql)
print("参数:", json.encode(params))
-- 输出: SQL: SELECT * FROM `players` WHERE `players`.`id` = ?
-- 参数: [123]调试复杂查询
lua
local sql, params = db.select()
.from(s.orders)
.leftJoin(s.players, sl.eq(s.orders.player_id, s.players.id))
.where(sl.and_(
sl.gte(s.orders.total, 100),
sl.eq(s.players.is_active, true)
))
.orderBy(s.orders.created_at, 'desc')
.limit(10)
.toSQL()
print("复杂查询 SQL:", sql)最佳实践
1. 使用链式调用
lua
-- 推荐:链式调用
local result = db.select()
.from(s.players)
.where(sl.eq(s.players.is_active, true))
.orderBy(s.players.name)
.limit(100)
.execute()2. 条件构建
lua
-- 动态构建查询条件
local query = db.select().from(s.players)
if isAdmin then
query = query.where(sl.eq(s.players.is_admin, true))
end
if minLevel then
query = query.where(sl.gte(s.players.level, minLevel))
end
local results = query.execute()3. 安全的参数传递
lua
-- 正确:使用参数绑定
db.select()
.from(s.players)
.where(sl.eq(s.players.name, playerName)) -- 自动转义
.execute()
-- 错误:直接拼接字符串(SQL 注入风险)
-- db.select().from(s.players).where(sl.sql("name = '" .. playerName .. "'"))4. 性能优化
lua
-- 只查询需要的列
local playerIds = db.select({ s.players.id })
.from(s.players)
.where(sl.eq(s.players.is_active, true))
.execute()
-- 使用索引友好的查询
db.select()
.from(s.players)
.where(sl.eq(s.players.identifier, identifier)) -- identifier 应该有索引
.limit(1)
.execute()