数据库集成 #
一、数据库选择 #
1.1 数据库对比 #
| 数据库 | 类型 | 适用场景 | 特点 |
|---|---|---|---|
| SQLite | 关系型 | 结构化数据 | 轻量、无服务、SQL支持 |
| LevelDB | 键值对 | 简单存储 | 高性能、嵌入式 |
| NeDB | 文档型 | 小型应用 | 纯JS、类MongoDB |
| PouchDB | 文档型 | 离线应用 | 同步支持 |
1.2 选择建议 #
text
- 简单键值存储 → electron-store / LevelDB
- 结构化数据 → SQLite
- 文档型数据 → NeDB / PouchDB
- 需要同步 → PouchDB
二、SQLite #
2.1 安装 #
bash
npm install better-sqlite3
# 或
npm install sqlite3
2.2 基本使用 #
javascript
const Database = require('better-sqlite3');
const path = require('path');
const { app } = require('electron');
// 创建数据库连接
const dbPath = path.join(app.getPath('userData'), 'app.db');
const db = new Database(dbPath);
// 创建表
db.exec(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
// 插入数据
const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)');
const result = insert.run('John', 'john@example.com');
console.log('插入ID:', result.lastInsertRowid);
// 查询数据
const query = db.prepare('SELECT * FROM users WHERE id = ?');
const user = query.get(1);
// 查询所有
const allUsers = db.prepare('SELECT * FROM users').all();
// 更新数据
const update = db.prepare('UPDATE users SET name = ? WHERE id = ?');
update.run('Jane', 1);
// 删除数据
const deleteStmt = db.prepare('DELETE FROM users WHERE id = ?');
deleteStmt.run(1);
// 关闭连接
db.close();
2.3 事务处理 #
javascript
const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)');
const insertMany = db.transaction((users) => {
for (const user of users) {
insert.run(user.name, user.email);
}
});
insertMany([
{ name: 'User1', email: 'user1@example.com' },
{ name: 'User2', email: 'user2@example.com' }
]);
2.4 封装 SQLite #
javascript
// database/sqlite.js
const Database = require('better-sqlite3');
const path = require('path');
const { app } = require('electron');
class SQLiteDatabase {
constructor(dbName = 'app.db') {
const dbPath = path.join(app.getPath('userData'), dbName);
this.db = new Database(dbPath);
this.db.pragma('journal_mode = WAL');
}
init() {
this.db.exec(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
}
get(sql, params = []) {
const stmt = this.db.prepare(sql);
return stmt.get(...params);
}
all(sql, params = []) {
const stmt = this.db.prepare(sql);
return stmt.all(...params);
}
run(sql, params = []) {
const stmt = this.db.prepare(sql);
return stmt.run(...params);
}
transaction(fn) {
return this.db.transaction(fn);
}
close() {
this.db.close();
}
}
module.exports = SQLiteDatabase;
三、LevelDB #
3.1 安装 #
bash
npm install level
3.2 基本使用 #
javascript
const { Level } = require('level');
const path = require('path');
const { app } = require('electron');
// 创建数据库
const dbPath = path.join(app.getPath('userData'), 'leveldb');
const db = new Level(dbPath, { valueEncoding: 'json' });
// 存储数据
await db.put('user:1', { name: 'John', email: 'john@example.com' });
// 读取数据
const user = await db.get('user:1');
// 删除数据
await db.del('user:1');
// 检查是否存在
try {
await db.get('key');
console.log('存在');
} catch (err) {
if (err.code === 'LEVEL_NOT_FOUND') {
console.log('不存在');
}
}
// 批量操作
await db.batch([
{ type: 'put', key: 'user:1', value: { name: 'User1' } },
{ type: 'put', key: 'user:2', value: { name: 'User2' } },
{ type: 'del', key: 'user:3' }
]);
// 遍历所有数据
for await (const [key, value] of db.iterator()) {
console.log(key, value);
}
// 关闭数据库
await db.close();
3.3 封装 LevelDB #
javascript
// database/leveldb.js
const { Level } = require('level');
const path = require('path');
const { app } = require('electron');
class LevelDBStore {
constructor(dbName = 'store') {
const dbPath = path.join(app.getPath('userData'), dbName);
this.db = new Level(dbPath, { valueEncoding: 'json' });
}
async get(key, defaultValue = null) {
try {
return await this.db.get(key);
} catch (err) {
if (err.code === 'LEVEL_NOT_FOUND') {
return defaultValue;
}
throw err;
}
}
async set(key, value) {
await this.db.put(key, value);
}
async delete(key) {
await this.db.del(key);
}
async has(key) {
try {
await this.db.get(key);
return true;
} catch {
return false;
}
}
async clear() {
await this.db.clear();
}
async keys() {
const keys = [];
for await (const key of this.db.keys()) {
keys.push(key);
}
return keys;
}
async values() {
const values = [];
for await (const value of this.db.values()) {
values.push(value);
}
return values;
}
async entries() {
const entries = [];
for await (const entry of this.db.iterator()) {
entries.push(entry);
}
return entries;
}
async close() {
await this.db.close();
}
}
module.exports = LevelDBStore;
四、NeDB #
4.1 安装 #
bash
npm install @seald-io/nedb
4.2 基本使用 #
javascript
const Nedb = require('@seald-io/nedb');
const path = require('path');
const { app } = require('electron');
// 创建数据库
const dbPath = path.join(app.getPath('userData'), 'data.db');
const db = new Nedb({ filename: dbPath, autoload: true });
// 插入文档
db.insert({ name: 'John', age: 30 }, (err, doc) => {
console.log('插入文档:', doc);
});
// Promise 方式
const doc = await db.insertAsync({ name: 'Jane', age: 25 });
// 查询文档
const docs = await db.findAsync({ name: 'John' });
// 查询单个
const doc = await db.findOneAsync({ _id: 'someId' });
// 更新文档
await db.updateAsync(
{ name: 'John' },
{ $set: { age: 31 } },
{ multi: true }
);
// 删除文档
await db.removeAsync({ name: 'John' }, { multi: true });
4.3 封装 NeDB #
javascript
// database/nedb.js
const Nedb = require('@seald-io/nedb');
const path = require('path');
const { app } = require('electron');
class NeDBStore {
constructor(collection) {
const dbPath = path.join(app.getPath('userData'), `${collection}.db`);
this.db = new Nedb({ filename: dbPath, autoload: true });
}
async insert(doc) {
return this.db.insertAsync(doc);
}
async find(query = {}, options = {}) {
let cursor = this.db.findAsync(query);
if (options.sort) {
cursor = cursor.sort(options.sort);
}
if (options.skip) {
cursor = cursor.skip(options.skip);
}
if (options.limit) {
cursor = cursor.limit(options.limit);
}
return cursor;
}
async findOne(query) {
return this.db.findOneAsync(query);
}
async update(query, update, options = {}) {
return this.db.updateAsync(query, update, {
multi: options.multi || false,
upsert: options.upsert || false,
returnUpdatedDocs: true
});
}
async remove(query, options = {}) {
return this.db.removeAsync(query, { multi: options.multi || false });
}
async count(query = {}) {
return this.db.countAsync(query);
}
}
module.exports = NeDBStore;
五、PouchDB #
5.1 安装 #
bash
npm install pouchdb
5.2 基本使用 #
javascript
const PouchDB = require('pouchdb');
const path = require('path');
const { app } = require('electron');
// 创建本地数据库
const dbPath = path.join(app.getPath('userData'), 'pouchdb');
const db = new PouchDB(dbPath);
// 插入文档
const response = await db.post({
name: 'John',
email: 'john@example.com'
});
console.log('插入成功:', response.id);
// 获取文档
const doc = await db.get(response.id);
// 更新文档
await db.put({
_id: response.id,
_rev: response.rev,
name: 'Jane',
email: 'jane@example.com'
});
// 删除文档
await db.remove(doc);
// 查询所有文档
const result = await db.allDocs({ include_docs: true });
result.rows.forEach(row => {
console.log(row.doc);
});
5.3 同步功能 #
javascript
// 本地数据库
const localDB = new PouchDB('local');
// 远程数据库
const remoteDB = new PouchDB('http://localhost:5984/mydb');
// 双向同步
localDB.sync(remoteDB, {
live: true,
retry: true
}).on('change', (info) => {
console.log('同步变化:', info);
}).on('error', (err) => {
console.error('同步错误:', err);
});
六、数据库管理器 #
6.1 统一接口 #
javascript
// database/manager.js
class DatabaseManager {
constructor() {
this.connections = new Map();
}
getSQLite(name) {
if (!this.connections.has(name)) {
const SQLiteDatabase = require('./sqlite');
this.connections.set(name, new SQLiteDatabase(`${name}.db`));
}
return this.connections.get(name);
}
getLevelDB(name) {
if (!this.connections.has(name)) {
const LevelDBStore = require('./leveldb');
this.connections.set(name, new LevelDBStore(name));
}
return this.connections.get(name);
}
getNeDB(name) {
if (!this.connections.has(name)) {
const NeDBStore = require('./nedb');
this.connections.set(name, new NeDBStore(name));
}
return this.connections.get(name);
}
async closeAll() {
for (const db of this.connections.values()) {
if (db.close) {
await db.close();
}
}
this.connections.clear();
}
}
module.exports = new DatabaseManager();
6.2 IPC 集成 #
javascript
// main.js
const dbManager = require('./database/manager');
// 初始化数据库
app.whenReady().then(() => {
const db = dbManager.getSQLite('main');
db.init();
});
// IPC 处理
ipcMain.handle('db:query', async (event, { db, method, args }) => {
const database = dbManager.getSQLite(db);
return database[method](...args);
});
// 应用退出时关闭数据库
app.on('will-quit', async () => {
await dbManager.closeAll();
});
七、最佳实践 #
7.1 数据库选择指南 #
javascript
function chooseDatabase(requirements) {
if (requirements.type === 'key-value') {
return 'LevelDB';
}
if (requirements.type === 'relational') {
return 'SQLite';
}
if (requirements.type === 'document') {
return requirements.sync ? 'PouchDB' : 'NeDB';
}
return 'SQLite';
}
7.2 数据备份 #
javascript
const fs = require('fs');
const path = require('path');
async function backupDatabase(dbPath, backupPath) {
const date = new Date().toISOString().split('T')[0];
const backupFile = path.join(backupPath, `backup-${date}.db`);
await fs.promises.copyFile(dbPath, backupFile);
return backupFile;
}
7.3 错误处理 #
javascript
async function safeQuery(fn) {
try {
return await fn();
} catch (error) {
console.error('数据库错误:', error);
throw new Error('数据库操作失败');
}
}
八、总结 #
8.1 核心要点 #
| 要点 | 说明 |
|---|---|
| SQLite | 结构化数据,SQL支持 |
| LevelDB | 高性能键值存储 |
| NeDB | 简单文档存储 |
| PouchDB | 支持同步的文档存储 |
| 统一管理 | 使用管理器统一管理连接 |
8.2 下一步 #
现在你已经掌握了数据库集成,接下来让我们学习 安全最佳实践,深入了解 Electron 应用的安全防护!
最后更新:2026-03-28