如何在Kysely中实现带参数的原生SQL通用查询函数?
在Kysely中实现防注入的通用查询函数
完全可以实现,而且能保证SQL注入防护,核心是利用Kysely内置的参数绑定机制处理动态参数,而非直接拼接字符串。
实现方案
先确保你已初始化Kysely数据库实例(比如db),然后编写通用函数如下:
import { sql, Kysely } from 'kysely'; // 泛型函数支持指定返回类型 async function runQuery<T>(db: Kysely<any>, sqlStr: string, args: Record<string, unknown>): Promise<T[]> { // 拆分SQL字符串的静态部分与参数占位符 const segments = sqlStr.split(/\${(\w+)}/g); const queryParts: unknown[] = []; for (let i = 0; i < segments.length; i++) { if (i % 2 === 0) { // 处理静态SQL片段 if (segments[i]) { queryParts.push(sql.raw(segments[i])); } } else { // 绑定对应参数,Kysely会自动处理参数化 const paramKey = segments[i]; queryParts.push(args[paramKey]); } } // 拼接所有片段并执行查询 const query = sql.join(queryParts, ''); return query.execute(db); }
使用示例
假设你有Person类型定义,调用方式如下:
// 假设db是已初始化的Kysely实例 const result1 = await runQuery<Person>(db, 'SELECT * from person WHERE id = ${id}', { id: 123 }); const result2 = await runQuery<Person>(db, 'SELECT * from person WHERE name = ${name}', { name: 'John' });
注入防护说明
Kysely处理参数绑定时,不会直接将参数值拼接进SQL字符串,而是通过数据库原生的参数化查询机制传递参数,从根源上避免了SQL注入风险。
注意事项
- 函数必须是异步的,因为数据库查询是异步操作,返回值为
Promise<T[]>而非同步数组。 - 占位符仅支持
${参数名}格式,参数名需符合标识符规则(字母、数字、下划线)。 - 泛型
T用于指定返回结果的类型,保证类型安全。
内容的提问来源于stack exchange,提问作者igorludi
相关产品推荐
相关产品推荐

