在 Electron 应用中,使用 IPC(进程间通信)来控制 SQL 数据库是一个常见的做法。主进程通常负责数据库操作,而渲染进程通过 IPC 请求这些操作。在这里以 SQLite 数据库为例,介绍怎么使用 IPC 来结合 SQL 的相关开发。其他SQL开发大同小异。
1. 安装必要的依赖
首先,您需要安装 sqlite3
模块来操作 SQLite 数据库。您可以在主进程中安装这个模块。
npm install sqlite3
2. 设置 Electron 项目结构
假设您的项目结构如下:
my-electron-app/
├── main.js # 主进程文件
├── renderer.js # 渲染进程文件
├── index.html # 主页面
├── package.json # 项目配置
└── db.sqlite # SQLite 数据库文件
3. 配置 main.js
(主进程)
在主进程中,设置 SQLite 数据库连接,并定义 IPC 事件来处理数据库操作。
// main.js
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
const sqlite3 = require('sqlite3').verbose();
// 创建数据库连接
const db = new sqlite3.Database(path.join(__dirname, 'db.sqlite'), (err) => {
if (err) {
return console.error(err.message);
}
console.log('Connected to the SQLite database.');
});
// 初始化数据库表(如果需要)
db.serialize(() => {
db.run(`CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE
)`);
});
// 创建主窗口
function createWindow () {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
enableRemoteModule: false,
}
});
mainWindow.loadFile('index.html');
}
app.whenReady().then(() => {
createWindow();
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit();
});
// IPC 事件处理
// 插入数据
ipcMain.handle('insert-user', async (event, name, email) => {
return new Promise((resolve, reject) => {
db.run(`INSERT INTO users (name, email) VALUES (?, ?)`, [name, email], function(err) {
if (err) {
reject(err.message);
} else {
resolve(this.lastID);
}
});
});
});
// 查询数据
ipcMain.handle('get-users', async (event) => {
return new Promise((resolve, reject) => {
db.all(`SELECT * FROM users`, [], (err, rows) => {
if (err) {
reject(err.message);
} else {
resolve(rows);
}
});
});
});
// 关闭数据库连接
app.on('before-quit', () => {
db.close((err) => {
if (err) {
return console.error(err.message);
}
console.log('Close the database connection.');
});
});
4. 配置 preload.js
preload.js
用于暴露 IPC 通道给渲染进程。
// preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
insertUser: (name, email) => ipcRenderer.invoke('insert-user', name, email),
getUsers: () => ipcRenderer.invoke('get-users'),
});
5. 配置 renderer.js
(渲染进程)
在渲染进程中,通过 electronAPI
调用主进程的 IPC 事件来操作数据库。
// renderer.js
document.getElementById('insert-button').addEventListener('click', async () => {
const name = document.getElementById('name').value;
const email = document.getElementById('email').value;
try {
const userId = await window.electronAPI.insertUser(name, email);
console.log(`User inserted with ID: ${userId}`);
alert(`User inserted with ID: ${userId}`);
} catch (error) {
console.error(error);
alert(`Error: ${error}`);
}
});
document.getElementById('fetch-button').addEventListener('click', async () => {
try {
const users = await window.electronAPI.getUsers();
console.log(users);
const userList = document.getElementById('user-list');
userList.innerHTML = '';
users.forEach(user => {
const li = document.createElement('li');
li.textContent = `ID: ${user.id}, Name: ${user.name}, Email: ${user.email}`;
userList.appendChild(li);
});
} catch (error) {
console.error(error);
alert(`Error: ${error}`);
}
});
6. 配置 index.html
创建一个简单的 HTML 页面来测试数据库操作。
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Electron SQLite Example</title>
</head>
<body>
<h1>Electron SQLite Example</h1>
<div>
<h2>Insert User</h2>
<input type="text" id="name" placeholder="Name">
<input type="email" id="email" placeholder="Email">
<button id="insert-button">Insert User</button>
</div>
<div>
<h2>Fetch Users</h2>
<button id="fetch-button">Fetch Users</button>
<ul id="user-list"></ul>
</div>
<script src="./renderer.js"></script>
</body>
</html>
7. 配置 package.json
确保您的 package.json
文件正确配置了主进程文件。
{
"name": "my-electron-app",
"version": "1.0.0",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"dependencies": {
"electron": "^24.0.0",
"sqlite3": "^5.1.6"
}
}
8. 运行应用
o( ̄︶ ̄)o至此简单的通信控制完成