fontcolor_theme
Deepkit ORM

原始访问

经常需要直接访问数据库,例如运行 ORM 不支持的 SQL 查询。这可以通过 Database 类上的 raw 方法完成。

import { PrimaryKey, AutoIncrement, @entity } from '@deepkit/type';
import { Database } from '@deepkit/orm';
import { sql } from '@deepkit/sql';
import { SqliteDatabaseAdapter } from '@deepkit/sqlite';

@entity.collection('users')
class User {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;
    constructor(public username: string) {}
}

const database = new Database(new SQLiteDatabaseAdapter(':memory:'), [User]);

const query = 'Pet%';
const rows = await database.raw<User>(sql`SELECT * FROM users WHERE username LIKE ${query}`).find();

const result = await database.raw<{ count: number }>(sql`SELECT count(*) as count FROM users WHERE username LIKE ${query}`).findOne();
console.log('Found', result.count, 'users');

SQL 查询是使用 sql 模板字符串标签构建的。这是一个特殊的模板字符串标签,允许以参数的形式传递值。这些参数随后会被自动解析并转换为安全的预处理语句。这对于避免 SQL 注入攻击非常重要。

要传递列名等动态标识符,可以使用 identifier

import { identifier, sql } from '@deepkit/sql';

let column = 'username';
const rows = await database.raw<User>(sql`SELECT * FROM users WHERE ${identifier(column)} LIKE ${query}`).find();

对于 SQL 适配器,raw 方法会返回一个带有 findOnefind 方法以获取结果的 RawQuery。要执行不返回行(如 UPDATE/DELETE/等)的 SQL,可使用 execute

let username = 'Peter';
await database.raw(sql`UPDATE users SET username = ${username} WHERE id = 1`).execute();

RawQuery 还支持获取最终的 SQL 字符串和参数,并为数据库适配器正确格式化:

const query = database.raw(sql`SELECT * FROM users WHERE username LIKE ${query}`);
console.log(query.sql);
console.log(query.params);

这样,SQL 也可以在其他数据库客户端中执行,例如。

类型

请注意,你可以向 raw 传递任意类型,数据库返回的结果会被自动转换为该类型。这对 SQL 适配器尤其有用,你可以传递一个类,返回结果会自动转换为该类的实例。

但这也有局限性。以这种方式不支持 SQL JOIN。如果你想使用 JOIN,必须使用 ORM 的查询构建器。

Mongo

MongoDB 适配器的工作方式稍有不同,因为它不是基于 SQL 查询,而是基于 Mongo 命令。

命令可以是聚合管道、查找查询或写入命令。

import { MongoDatabaseAdapter } from '@deepkit/mongo';

const database = new Database(MongoDatabaseAdapter('mongodb://localhost:27017/mydatabase'));

// 第一个参数是入口集合,第二个是命令的返回类型
const items = await database.raw<ChatMessage, { count: number }>([
    { $match: { roomId: 'room1' } },
    { $group: { _id: '$userId', count: { $sum: 1 } } },
]).find();
English中文 (Chinese)한국어 (Korean)日本語 (Japanese)Deutsch (German)