SQL.js 开源:在浏览器中运行 SQLite 数据库
liuian 2024-12-07 14:59 47 浏览
大家好,很高兴又见面了,我是"高级前端?进阶?",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力。
1.什么是 sql.js
sql.js is a port of SQLite to Webassembly, by compiling the SQLite C code with Emscripten. It uses a virtual database file stored in memory, and thus doesn't persist the changes made to the database. However, it allows you to import any existing sqlite file, and to export the created database as a JavaScript typed array.
sql.js 是 SQLite 到 WebAssembly 的端口,通过使用 Emscripten 编译 SQLite C 代码。
sql.js 允许开发者创建关系数据库并完全在浏览器中查询,而且使用存储在内存中的虚拟数据库文件,因此不会保留对数据库所做的更改。 但是,其允许开发者导入任何现有的 sqlite 文件,并将创建的数据库导出为 JavaScript 类型数组。
sql.js 可以像任何传统的 JavaScript 库一样使用,因此如果正在使用 JavaScript 构建本机应用程序(例如使用 Electron),或者正在使用 Node.js 则可能更喜欢使用 SQLite 到 JavaScript 的本机绑定 (Native Binding of SQLite to JavaScript)。
本机绑定不仅速度更快,而且还能够直接处理数据库文件,而不必将整个数据库加载到内存中,从而避免内存不足错误并进一步提高性能。
目前 sql.js 在 Github 通过 MIT 协议开源,有超过 12.2k 的star、1k 的fork、项目依赖量6.8k、代码贡献者 50+ ,妥妥的前端优质开源项目。
2.如何使用 sql.js
浏览器中使用
默认情况下,sql.js 使用 wasm,因此除了 javascript 库之外还需要加载 .wasm 文件。 从 npm 安装 sql.js 后,开发者可以在 ./node_modules/sql.js/dist/sql-wasm.wasm 中找到此文件,并指示捆绑程序将其添加到静态资产或从 CDN 加载。
然后使用传递给 initSqlJs 的配置对象的 locateFile 属性来指示文件所在的位置。 如果使用 webpack 等构建器,则可以自动执行此操作。
const initSqlJs = require('sql.js');
const SQL = await initSqlJs({
// 需要异步加载 wasm 二进制文件
// 在 node 中运行时可以完全省略 locateFile
locateFile: file => `https://sql.js.org/dist/${file}`
});
// 创建数据库
const db = new SQL.Database();
// 执行包含多个语句的单个 SQL 字符串
let sqlstr = "CREATE TABLE hello (a int, b char); \
INSERT INTO hello VALUES (0, 'hello'); \
INSERT INTO hello VALUES (1, 'world');";
db.run(sqlstr);
// 准备一条 sql 语句
const stmt = db.prepare("SELECT * FROM hello WHERE a=:aval AND b=:bval");
// 将值绑定到参数并获取查询结果
const result = stmt.getAsObject({':aval' : 1, ':bval' : 'world'});
console.log(result);
// 输出值 {a:1, b:'world'}
stmt.bind([0, 'hello']);
stmt.free();
const res = db.exec("SELECT * FROM hello");
/* 输出
[
{columns:['a','b'], values:[[0,'hello'],[1,'world']]}
]
*/
db.create_aggregate(
"json_agg",
{
init: () => [],
step: (state, val) => [...state, val],
finalize: (state) => JSON.stringify(state),
}
);
db.exec("SELECT json_agg(column1) FROM (VALUES ('hello'), ('world'))");
// -> 输出值 '["hello","world"]'
// 将数据库导出到包含 SQLite 数据库文件的 Uint8Array
const binaryArray = db.export();Node.js 环境中
sql.js 托管在 npm 上,只需运行 npm install sql.js 即可。或者,开发者可以简单地从下面的下载链接下载 sql-wasm.js 和 sql-wasm.wasm。
在 Node.js 环境中,可以通过下面代码从磁盘读取数据库:
const fs = require('fs');
const initSqlJs = require('sql-wasm.js');
const filebuffer = fs.readFileSync('test.sqlite');
initSqlJs().then(function(SQL){
// 读取 DB
const db = new SQL.Database(filebuffer);
});同时,可以通过下面方法将内容写入磁盘:
const fs = require("fs");
// [...] (create the database)
const data = db.export();
const buffer = Buffer.from(data);
fs.writeFileSync("filename.sqlite", buffer);同时,如果开发者不想在主应用程序线程中运行 CPU 密集型 SQL 查询,则可以使用更受限制的 WebWorker API。
const worker = new Worker("/dist/worker.sql-wasm.js");
worker.onmessage = () => {
console.log("Database opened");
worker.onmessage = event => {
console.log(event.data);
// 查询结果
};
worker.postMessage({
id: 2,
action: "exec",
sql: "SELECT age,name FROM test WHERE id=$id",
params: {"$id": 1}
});
};
worker.onerror = e => console.log("Worker error:", e);
worker.postMessage({
id:1,
action:"open",
buffer:buf,
/* 可选,代表 SQLite 数据库文件的 ArrayBuffer*/
});sql.js 还支持与 XMLHttpRequest 一起使用,比如下面的示例:
const xhr = new XMLHttpRequest();
// For example: https://github.com/lerocha/chinook-database/raw/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite
xhr.open('GET', '/path/to/database.sqlite', true);
xhr.responseType = 'arraybuffer';
xhr.onload = e => {
const uInt8Array = new Uint8Array(xhr.response);
const db = new SQL.Database(uInt8Array);
const contents = db.exec("SELECT * FROM my_table");
// contents is now [{columns:['col1','col2',...], values:[[first row], [second row], ...]}]
};
xhr.send();更多关于 Sql.js 的知识和用法可以参考文末资料,本文不再过多展开。
参考资料
https://madewithwebassembly.com/showcase/sqlite/
https://github.com/sql-js/sql.js
https://www.youtube.com/watch?app=desktop&v=0DZ472GiVNw
https://blog.logrocket.com/detailed-look-basic-sqljs-features/
相关推荐
- 苹果16突然黑屏关机(苹果11突然黑屏)
-
苹果手机突然黑屏但是没关机的原因:一般情况下,死机黑屏都是软件系统原因造成的,可能是由于你安装的软件内部冲突所导致的。严重的时候还会花屏重启。还有可能就是手机使用时间长,热量散发不及时。只要同时按住关...
- 子网掩码和网关怎么填(子网掩码与网关怎么设置)
-
1、以WIN10系统为例,电脑的ip地址、默认网关以及子网掩码可以通过进入到该电脑的网络连接属性界面进行填写。打开属性界面以后,选择手动。然后输入正确的编码即可(其中的默认网关与路由器IP地址相同)。...
- windows10不激活影响使用吗(win 10不激活有什么影响)
-
windows10不激活能用一般情况下,不激活的确可以正常使用,但是会有一些功能受到限制。具体的限制如下所示:首先,您的屏幕右下角会显示“激活Windows”的水印;其次,您无法在“个性化”下使用任...
-
- pdf转换器免费(pdf转换器在线版)
-
1.可检索内容的PDF(内容可以用鼠标选中的非双层PDF)文件,推荐用下面软件转换:PDFToWordConverter,是一款将AdobePDF文档转换成Word文档的工具软件,它支持文字,图像及其它内容的输出。这款软件可以...
-
2025-12-24 06:55 liuian
- office2013激活工具win11(office2013激活工具toolkit)
-
用专门的激活工具就可以啦。1、待安装完Office2013后,解压并运行“MicrosoftToolkit.exe”程序,在弹出的程序界面中点击“OfficeButton”按钮以便打开“Office破...
- 手机登录126邮箱网页登录入口
-
www.126.com126邮箱拥有3G超大存储空间,支持超大2G附件,采用了创新Ajax技术,同等网络环境下,页面响应时间最高减少90%,垃圾邮件及病毒有效拦截率超过98%和99.8%。126邮箱采...
- 全国中高风险地区最新名单(全国中高风险地区最新名单7.29)
-
浦东新区康桥镇环桥路1488弄小区,黄浦区南京东路街道西藏中路180号高盛商厦5楼,静安区共和新路街道沪太路785号B座501西区天空音乐量贩式KTV,松江区小昆山镇平原街86弄平原新村,虹口区北外滩...
- 爱吾游戏宝盒破解版(爱吾游戏宝盒破解版2023最新版本)
-
爱吾游戏宝盒闪退有以下原因:可能是游戏与手机系统不兼容,卸载游戏后重新安装最新版本,或者升级手机系统,2.有的游戏程序会与其它正在开启的应用有冲突,将后台运行的应用全部关闭再重新启动游戏就可以了要降低...
- win8激活码免费领取(windows8激活码免费)
-
1、首先我们下载一个能够永久激活win8系统的KMSpico激活工具。2、然后将“KMSpico_setup”双击打开进行安装。3、安装目录随便选择就行了,安装完成之后找到EXE文件,以管理员身份运行...
- 微信安装官方正版(2025版微信官方正版)
-
必须先安装微信,如果自己的微信号和密码忘了可以通过绑定的手机号码进行找回,操作步骤如下:1、在手机上点击打开微信,来到登陆窗口,点击”找回密码“。2、在找回密码界面,选择”通过手机号码找回”,然后...
- 大白菜u盘启动怎么装系统(大白菜u盘启动盘怎么装系统win10)
-
1、根据上面的教程制作好大白菜pe启动盘,然后将下载的操作系统iso文件直接复制到U盘的GHO目录下; 2、在需要装系统的电脑上插入U盘,重启后不停按F12、F11、Esc等快捷键打开启动菜单,...
- 360软件管家使用方法(360软件管家使用方法视频)
-
步骤:1、只要在提示条上点击“安全保存”按钮,即可方便快捷地将网站的帐号密码保存下来,且网站会出现在登录管家主面板的网站列表中。2、登录360安全浏览器后可使用云加密的网站列表,帐号密码安全性进一步提...
- originos下载(originos官方下载地址)
-
已经在官网上进行下载。originos3.0从目前已经在vivo手机的官网中可以进行下载。先登录进vivo官网,然后再找到系统的专区,找到最新版本的originos3.0,然后选择你手机的型号。进行...
- 文件夹怎样加密码保护(文件夹如何加密码锁)
-
1.鼠标右键点击电脑桌面里面要加密的文件或者文件夹,选择“属性”;2.在“常规”下方,选择“高级”选项;3.之后就会继续弹出一个窗口,在压缩或加密属性下,选择“加密内容以便保护数据”即可。.鼠标右键...
- 一周热门
- 最近发表
- 标签列表
-
- python判断字典是否为空 (50)
- crontab每周一执行 (48)
- aes和des区别 (43)
- bash脚本和shell脚本的区别 (35)
- canvas库 (33)
- dataframe筛选满足条件的行 (35)
- gitlab日志 (33)
- lua xpcall (36)
- blob转json (33)
- python判断是否在列表中 (34)
- python html转pdf (36)
- 安装指定版本npm (37)
- idea搜索jar包内容 (33)
- css鼠标悬停出现隐藏的文字 (34)
- linux nacos启动命令 (33)
- gitlab 日志 (36)
- adb pull (37)
- python判断元素在不在列表里 (34)
- python 字典删除元素 (34)
- vscode切换git分支 (35)
- python bytes转16进制 (35)
- grep前后几行 (34)
- hashmap转list (35)
- c++ 字符串查找 (35)
- mysql刷新权限 (34)
