Electron框架中实现数据库的连接、读取和写入详细方案

 更新时间:2026年02月07日 10:58:28   作者:涔溪  
在Electron应用中,数据库扮演着存储和管理数据的重要角色,无论是本地数据存储、数据同步还是远程数据库操作,都离不开数据库的支持,这篇文章主要介绍了Electron框架中实现数据库的连接、读取和写入的相关资料,需要的朋友可以参考下

前言

在 Electron 框架中实现数据库的连接、读取和写入,核心思路是在主进程中处理数据库逻辑(避免敏感信息暴露),通过 IPC(进程间通信)与渲染进程交互。以下是详细实现方案(以本地嵌入式数据库 SQLite 为例,兼顾其他数据库思路)。

一、技术选型与准备

1. 数据库选择

  • 推荐 SQLite:嵌入式数据库,无需独立服务器,数据存储在本地文件,适合 Electron 桌面应用。
  • 其他数据库(MySQL/PostgreSQL):需额外部署服务器,适合多端共享数据场景。

2. 核心依赖

  • electron:Electron 框架核心。
  • sqlite3:SQLite 的 Node.js 驱动(异步操作)。
  • electron-rebuild:解决原生模块(如sqlite3)与 Electron 的兼容性问题。

3. 项目初始化

# 创建项目
mkdir electron-db-demo && cd electron-db-demo
npm init -y

# 安装依赖
npm install electron sqlite3 --save
npm install electron-rebuild --save-dev

4. 重建原生模块(关键步骤)

sqlite3是原生模块,需与 Electron 的 Node 版本匹配,执行重建:

# 配置重建脚本(package.json中添加)
"scripts": {
  "rebuild": "electron-rebuild -f -w sqlite3"
}

# 执行重建
npm run rebuild

二、实现核心逻辑

1. 项目结构

electron-db-demo/
├─ main.js        # 主进程(数据库操作+窗口管理)
├─ preload.js     # 预加载脚本(安全暴露IPC接口)
├─ index.html     # 渲染进程(UI+用户交互)
└─ package.json

2. 主进程(main.js):数据库操作 + IPC 监听

主进程负责数据库连接、CRUD 操作,并通过ipcMain接收渲染进程的请求。

const { app, BrowserWindow, ipcMain } = require('electron');
const sqlite3 = require('sqlite3').verbose();
const path = require('path');

// 数据库文件路径(存放在Electron默认的用户数据目录,避免权限问题)
const dbPath = path.join(app.getPath('userData'), 'mydb.db');

// 初始化数据库连接
let db;
function initDB() {
  return new Promise((resolve, reject) => {
    db = new sqlite3.Database(dbPath, (err) => {
      if (err) {
        console.error('数据库连接失败:', err.message);
        reject(err);
      } else {
        console.log('数据库连接成功');
        // 创建示例表(如users表)
        db.run(`CREATE TABLE IF NOT EXISTS users (
          id INTEGER PRIMARY KEY AUTOINCREMENT,
          name TEXT NOT NULL,
          age INTEGER
        )`, (err) => {
          if (err) reject(err);
          else resolve();
        });
      }
    });
  });
}

// 封装数据库操作(Promise化,避免回调地狱)
const dbHelper = {
  // 插入数据
  insert: (table, data) => {
    return new Promise((resolve, reject) => {
      const keys = Object.keys(data).join(',');
      const placeholders = Object.keys(data).map(() => '?').join(',');
      const values = Object.values(data);
      const sql = `INSERT INTO ${table} (${keys}) VALUES (${placeholders})`;
      
      db.run(sql, values, function(err) {
        if (err) reject(err);
        else resolve({ id: this.lastID }); // 返回插入的ID
      });
    });
  },
  // 查询数据(全部)
  queryAll: (table) => {
    return new Promise((resolve, reject) => {
      const sql = `SELECT * FROM ${table}`;
      db.all(sql, (err, rows) => {
        if (err) reject(err);
        else resolve(rows);
      });
    });
  }
};

// 创建窗口
function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'), // 预加载脚本
      contextIsolation: true // 开启上下文隔离(安全要求)
    }
  });
  mainWindow.loadFile('index.html');
}

// 初始化流程
app.whenReady().then(async () => {
  await initDB(); // 等待数据库初始化完成
  createWindow();
  
  // IPC监听:处理渲染进程的数据库请求
  // 1. 插入数据
  ipcMain.handle('db-insert', async (event, table, data) => {
    try {
      return await dbHelper.insert(table, data);
    } catch (err) {
      throw err; // 抛出错误,让渲染进程捕获
    }
  });
  
  // 2. 查询所有数据
  ipcMain.handle('db-query-all', async (event, table) => {
    try {
      return await dbHelper.queryAll(table);
    } catch (err) {
      throw err;
    }
  });

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit();
});

3. 预加载脚本(preload.js):安全暴露 IPC 接口

由于 Electron 开启上下文隔离后,渲染进程无法直接访问ipcRenderer,需通过预加载脚本暴露有限接口。

const { contextBridge, ipcRenderer } = require('electron');

// 暴露安全的IPC接口给渲染进程(仅允许必要操作)
contextBridge.exposeInMainWorld('electronAPI', {
  // 插入数据
  dbInsert: (table, data) => ipcRenderer.invoke('db-insert', table, data),
  // 查询所有数据
  dbQueryAll: (table) => ipcRenderer.invoke('db-query-all', table)
});

4. 渲染进程(index.html):UI 交互 + 调用数据库

渲染进程负责用户交互(输入数据、触发操作),通过预加载暴露的接口调用主进程的数据库逻辑。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Electron数据库示例</title>
</head>
<body>
  <h1>用户管理</h1>
  
  <!-- 插入数据表单 -->
  <div>
    <input type="text" id="name" placeholder="姓名">
    <input type="number" id="age" placeholder="年龄">
    <button onclick="addUser()">添加用户</button>
  </div>
  
  <!-- 数据展示 -->
  <div>
    <h3>用户列表</h3>
    <ul id="userList"></ul>
  </div>

  <script>
    // 调用预加载暴露的API
    const { electronAPI } = window;

    // 添加用户(写入数据库)
    async function addUser() {
      const name = document.getElementById('name').value;
      const age = document.getElementById('age').value;
      if (!name || !age) return alert('请输入姓名和年龄');

      try {
        const result = await electronAPI.dbInsert('users', { name, age: Number(age) });
        alert(`添加成功!ID: ${result.id}`);
        loadUsers(); // 刷新列表
      } catch (err) {
        alert(`添加失败:${err.message}`);
      }
    }

    // 加载用户(读取数据库)
    async function loadUsers() {
      try {
        const users = await electronAPI.dbQueryAll('users');
        const list = document.getElementById('userList');
        list.innerHTML = users.map(u => `<li>${u.id}: ${u.name} (${u.age}岁)</li>`).join('');
      } catch (err) {
        alert(`查询失败:${err.message}`);
      }
    }

    // 页面加载时初始化列表
    window.onload = loadUsers;
  </script>
</body>
</html>

三、运行与测试

package.json中添加启动脚本:

"scripts": {
  "start": "electron .",
  "rebuild": "electron-rebuild -f -w sqlite3"
}

执行npm start即可启动应用,测试添加用户和查询功能。

四、其他数据库适配思路

1. MySQL/PostgreSQL

  • 安装对应驱动:npm install mysql2(MySQL)或npm install pg(PostgreSQL)。

  • 主进程中通过驱动连接数据库(需配置 host、user、password 等):

    // MySQL示例(main.js中)
    const mysql = require('mysql2/promise');
    const connection = await mysql.createConnection({
      host: 'localhost',
      user: 'root',
      password: '123456',
      database: 'mydb'
    });
    
  • 后续 CRUD 操作通过 SQL 语句执行(与 SQLite 逻辑类似,替换dbHelper即可)。

2. 关键注意事项

  • 安全性:数据库凭证(如 MySQL 密码)不要硬编码,可加密存储在本地配置文件。
  • 路径处理:本地数据库文件(如 SQLite)优先使用app.getPath('userData')(用户数据目录),避免权限问题。
  • 错误处理:所有数据库操作需捕获错误并返回给渲染进程,避免应用崩溃。

通过以上方案,可在 Electron 中实现安全、稳定的数据库读写功能,适配本地或远程数据库场景。

总结

到此这篇关于Electron框架中实现数据库的连接、读取和写入详细方案的文章就介绍到这了,更多相关Electron数据库连接、读取和写入内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JavaScript 语法集锦 脚本之家基础推荐

    JavaScript 语法集锦 脚本之家基础推荐

    JavaScript语法集锦是对javascript常用函数的一些小结,比较实用,建议收藏,方便查找需要的资料。
    2009-11-11
  • 子窗体与父窗体传值示例js代码

    子窗体与父窗体传值示例js代码

    子窗体与父窗体之见互相传值实现使用中很频繁,本文以一个小示例抛砖引玉,希望大家可以举一反三
    2013-08-08
  • ie与ff下的event事件使用介绍

    ie与ff下的event事件使用介绍

    event是ie自带的一个对象,而ff中不存在该对象,只能通过传递参数的方式来模拟event,下面简单为大家介绍下
    2013-11-11
  • JS前端的内存处理的方法全面详解

    JS前端的内存处理的方法全面详解

    这篇文章主要为大家介绍了JS前端的内存处理的方法全面详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • JS解惑之Object中的key是有序的么

    JS解惑之Object中的key是有序的么

    这篇文章主要介绍了JS解惑之Object中的key是有序的么,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-05-05
  • 第一次接触Bootstrap框架

    第一次接触Bootstrap框架

    这篇文章主要为大家详细介绍了Bootstrap框架,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • js完整倒计时代码分享

    js完整倒计时代码分享

    这篇文章主要为大家详细介绍了js完整倒计时代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • javascript实现表格信息增添与删除

    javascript实现表格信息增添与删除

    这篇文章主要为大家详细介绍了javascript实现表格信息增添与删除,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-04-04
  • JavaScript localStorage使用教程详解

    JavaScript localStorage使用教程详解

    JavaScriptlocalStorage基本上是浏览器Window对象中的存储,您可以在中存储任何内容localStorage,localStorage及其相关的sessionStorage是 Web Storage API的一部分,我们将在本文详细了解这些,需要的朋友可以参考下
    2023-06-06
  • 高性能JavaScript循环语句和条件语句

    高性能JavaScript循环语句和条件语句

    这篇文章主要为大家介绍了高性能JavaScript循环语句和条件语句,感兴趣的小伙伴们可以参考一下
    2016-01-01

最新评论