📦 安装
// npm
npm install @metona-team/metona-sqlark
// ESM
import { MetonaSqlark, MeSqlark } from 'metona-sqlark';
// Browser
<script src="metona-sqlark.min.js"></script>
// → window.MetonaSqlark / window.MeSqlark
🏗 创建数据库
MetonaSqlark.create(config) 工厂函数,返回初始化好的实例。
const db = await MetonaSqlark.create({
name: 'my-app',
mode: 'hybrid', // 'memory' | 'disk' | 'hybrid'
diskEngine: 'indexeddb', // 'indexeddb' | 'opfs'
version: 1,
});
| 属性 | 类型 | 默认 | 说明 |
name | string | - | 数据库名称 |
mode | 'memory'|'disk'|'hybrid' | 'hybrid' | 存储模式 |
diskEngine | 'indexeddb'|'opfs' | 'indexeddb' | 磁盘引擎 |
version | number | 1 | 版本号 |
📋 定义表
await db.defineTable('users', {
id: { type: 'string', primaryKey: true },
name: { type: 'string', required: true },
email: { type: 'string', unique: true, index: true },
age: { type: 'number', default: 0 },
dept_id: { type: 'number', references: 'departments.id' },
});
| 字段 | 类型 | 说明 |
type | string|number|boolean|date|json | 数据类型 |
primaryKey | boolean | 主键 |
required | boolean | 必填 |
unique | boolean | 唯一约束 |
index | boolean | 创建索引 |
default | unknown | 默认值 |
references | string | 外键引用 |
🔍 SQL 查询
// INSERT
await db.query("INSERT INTO users (id, name, age) VALUES ('1', 'Alice', 30)");
// SELECT
const rows = await db.query('SELECT * FROM users WHERE age > 18 ORDER BY name LIMIT 10');
// UPDATE
await db.query("UPDATE users SET age = 31 WHERE id = '1'");
// DELETE
await db.query("DELETE FROM users WHERE id = '1'");
// DDL
await db.query('DROP TABLE users');
⛓ Query Builder
const users = db.table('users');
// 插入
await users.insert({ id: '1', name: 'Alice' });
await users.insertMany([...]);
// 查询
const result = await users
.select(['name', 'age'])
.where({ age: { $gt: 18 }, name: { $like: 'A%' } })
.orderBy('age', 'desc')
.limit(10).offset(0)
.execute();
// 更新/删除
await users.update({ age: 31 }).where({ id: '1' }).execute();
await users.delete().where({ id: '1' }).execute();
🔗 JOIN 查询
// SQL
await db.query(`SELECT u.name, d.name
FROM users u
INNER JOIN departments d ON u.dept_id = d.id
WHERE d.name = 'Engineering'`);
// QueryBuilder
await db.table('users').select()
.innerJoin('departments', { 'users.dept_id': { $col: 'departments.id' } })
.execute();
// LEFT JOIN / RIGHT JOIN / CROSS JOIN
.leftJoin('table', on)
.rightJoin('table', on)
.crossJoin('table')
📊 GROUP BY & 聚合
await db.query(`SELECT dept, COUNT(*) as cnt, SUM(salary) as total
FROM employees
GROUP BY dept
HAVING COUNT(*) > 1
ORDER BY total DESC`);
// 支持的聚合函数:COUNT, SUM, AVG, MIN, MAX
// 支持别名:COUNT(*) AS cnt
🔒 事务
await db.transaction(async (trx) => {
await trx.table('users').insert({ id: '3', name: 'Charlie' });
await trx.table('orders').insert({ id: 'o1', userId: '3', amount: 99 });
// 任何一步失败 → 全部回滚
});
🔄 数据迁移
db.addMigration(2, async (db) => {
await db.defineTable('products', { ... });
});
await db.migrateTo(2); // 执行所有未执行的迁移
📤 导入导出
// 导出单表
const data = await db.exportTable('users');
// 导出全库
const all = await db.exportAll();
// 导入
await db.importTable('users', data);
🧩 插件钩子
// 14 个生命周期钩子
db.on('beforeInsert', async (row) => {
console.log('即将插入:', row);
});
db.on('afterQuery', async (sql, result) => {
console.log('查询完成:', sql);
});
| 钩子 | 触发时机 |
beforeCreateTable / afterCreateTable | 创建表前后 |
beforeDropTable / afterDropTable | 删除表前后 |
beforeInsert / afterInsert | 插入前后 |
beforeUpdate / afterUpdate | 更新前后 |
beforeDelete / afterDelete | 删除前后 |
beforeQuery / afterQuery | 查询前后 |
beforeTransaction / afterTransaction | 事务前后 |
📡 发布订阅
// 订阅表变更
const unsubscribe = db.subscribe('users', (event) => {
// event: { type: 'insert'|'update'|'delete', row: {...} }
});
// 取消订阅
unsubscribe();
🔷 TypeScript 泛型
interface User {
id: string;
name: string;
age: number;
}
const users = db.table<User>('users');
await users.insert({ id: '1', name: 'Alice', age: 30 }); // ✅ 类型安全
⚙️ 配置项
import { MetonaSqlark, MeSqlark } from 'metona-sqlark';
// MeSqlark 是 MetonaSqlark 的别名,完全等价