当前位置: 首页 > article >正文

前端项目接入sqlite轻量级数据库sql.js指南

前端项目接入sqlite轻量级数据库sql.js指南

引言

sql.js 是一个强大的JavaScript库,它使得SQLite数据库能够在网页浏览器中运行。这个开源项目提供了一种方式,让开发者可以在前端环境中实现轻量级的数据库操作,无需依赖服务器端数据存储,极大地增强了Web应用的数据处理能力。通过将SQLite编译成WebAssembly(wasm),sql.js实现了高效的数据库操作,支持标准的SQL查询语言。

如果你需要在浏览器中处理大量数据,并且希望使用 SQL 语法来操作这些数据,那么 SQL.js 将是一个不错的选择。

如果您不想在主应用程序线程中运行 CPU 密集型 SQL 查询, 您可以使用更有限的 WebWorker API。

详细api请移步官方文档sql.js sqlite 官网:https://sql.js.org/#/?id=inside-the-browser

sqlite 不会持久化缓存数据,只会存在运行内存中,需要自行导入导出文件。

我们的目标

本指南将sqlite数据集成到网页项目中,并学习相应api操作,

实现案例效果

本教程使用版本*“sql.js”: “^1.11.0”*

项目中加载sql.js

实现的最终效果,浏览器无任何错误,且,会在控制打印{a:1,b:'world'}

您始终可以在 https://github.com/sql-js/sql.js/releases/latest 上找到最新发布的工件。

对于每个版本,您都会在发布资产中找到一个名为的文件。它将包含:sqljs.zip

  • sql-wasm.js:Sql.js 的 Web Assembly 版本。缩小并适合生产。使用这个。如果您使用此项,您还需要包含/发货。sql-wasm.wasm
  • sql-wasm-debug.js:Web 程序集,Sql.js. Larger 的调试版本,打开了断言。对本地开发有用。如果您使用这个,您将需要包含/发货。sql-wasm-debug.wasm
  • sql-asm.js:较旧的 asm.js Sql.js 版本。速度较慢且较大。出于兼容性原因提供。
  • sql-asm-memory-growth.js:默认情况下,Asm.js不允许内存增长,因为它速度较慢且会取消优化。如果您使用的是 sql-asm.js 并看到此错误 (),请使用此文件。Cannot enlarge memory arrays
  • sql-asm-debug.js:Sql.js的 Debug asm.js 版本。用于本地开发。
  • worker.*- 上述库的 Web Worker 版本。更有限的 API。参见 examples/GUI/gui.js 这是一个很好的例子。

有两个版本,一个是在网页中直接加载的版本,一个是electron等桌面端应用使用的版本

1.在网页中加载的版本(本教程的版本),有两种加载方式

  1. 可以使用npm包安装(推荐),使用构建工具webpackvite

    库下载地址:sql.js - npm (npmjs.com)

    npm i sql.js
    

    sql.js需要依赖sql-wasm.wasm文件,我们需要添加到自己的目录下面引用

    node_modules
        - sql.js
            - sql-wasm.wasm将这个文件放在自己的dist目录下面
    

    新建dist目录/

     dist
        - sql-wasm.wasm
    

    运行下面的代码,没有报错,且控制台打印对应数据

    import initSqlJs  from 'sql.js';
    const SQL = await initSqlJs({
    // 这里会加载dist/sql-wasm.wasm
    locateFile: file => `./dist/${file}`
    });
    ​
    // Create a database
    const db = new SQL.Database();
    ​
    let sqlstr = "CREATE TABLE hello (a int, b char); \
    INSERT INTO hello VALUES (0, 'hello'); \
    INSERT INTO hello VALUES (1, 'world');";
    db.run(sqlstr); // Run the query without returning anything
    ​
    // Prepare an sql statement
    const stmt = db.prepare("SELECT * FROM hello WHERE a=:aval AND b=:bval");
    ​
    // Bind values to the parameters and fetch the results of the query
    const result = stmt.getAsObject({':aval' : 1, ':bval' : 'world'});
    console.log(result); // Will print {a:1, b:'world'}
    ​
    
  2. 也可以直接在网页中加入(没有使用任何构建工具),需要在 web 静态服务器下访问本文件(推荐 vscode 插件 liveserver)

    库下载地址:sql.js - Libraries - cdnjs - The #1 free and open source CDN built to make life easier for developers

    1. 一种是直接在网页头部引入(不推荐)

      如果cdn出现问题,会导致不可用

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <link rel="icon" type="image/svg+xml" href="/vite.svg" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Vite App</title>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.11.0/sql-wasm.js" integrity="sha512-tz0jOZaOg9RtWWB6AdxSkINQwIs7S5obj1Dlml9KewZLPTblTWCux5eLtnexBb8kbLUo5crPmjsi8/vI17Vw0w==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
        </head>
        <body>
          <div id="app"></div>
          <script>
            config = {
            // 从云端加载https://sql.js.org/distsql-wasm.wasm
              locateFile: file => `https://sql.js.org/dist/${file}`
            };
            initSqlJs(config).then(function (SQL) {
              //Create the database
              const db = new SQL.Database();
              // Run a query without reading the results
              db.run('CREATE TABLE test (col1, col2);');
              // Insert two rows: (1,111) and (2,222)
              db.run('INSERT INTO test VALUES (?,?), (?,?)', [1, 111, 2, 222]);
      ​
              // Prepare a statement
              const stmt = db.prepare('SELECT * FROM test WHERE col1 BETWEEN $start AND $end');
              stmt.getAsObject({ $start: 1, $end: 1 }); // {col1:1, col2:111}
      ​
              // Bind new values
              stmt.bind({ $start: 1, $end: 2 });
              while (stmt.step()) {
                //
                const row = stmt.getAsObject();
                console.log('Here is a row: ' + JSON.stringify(row));
              }
            });
          </script>
        </body>
      </html>
      ​
      
    2. 一种是将文件下载在自己的文件目录中,然后引入(推荐)

      库下载地址:sql.js - Libraries - cdnjs - The #1 free and open source CDN built to make life easier for developers

      从下载地址下载两个文件,存在dist目录

      dist
          - sql-wasm.wasm
          - sql-wasm.js
      
      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <link rel="icon" type="image/svg+xml" href="/vite.svg" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Vite App</title>
          <script src="./dist/sql-wasm.js"></script>
        </head>
        <body>
          <div id="app"></div>
          <script>
            config = {
            // 这里请求自己目录下面的.dist/sql-wasm.wasm
              locateFile: file => `./dist/${file}`
            };
            initSqlJs(config).then(function (SQL) {
              //Create the database
              const db = new SQL.Database();
              // Run a query without reading the results
              db.run('CREATE TABLE test (col1, col2);');
              // Insert two rows: (1,111) and (2,222)
              db.run('INSERT INTO test VALUES (?,?), (?,?)', [1, 111, 2, 222]);
      ​
              // Prepare a statement
              const stmt = db.prepare('SELECT * FROM test WHERE col1 BETWEEN $start AND $end');
              stmt.getAsObject({ $start: 1, $end: 1 }); // {col1:1, col2:111}
      ​
              // Bind new values
              stmt.bind({ $start: 1, $end: 2 });
              while (stmt.step()) {
                //
                const row = stmt.getAsObject();
                console.log('Here is a row: ' + JSON.stringify(row));
              }
            });
          </script>
        </body>
      </html>
      ​
      

2.在node版本(electron等本机桌面应用程序使用)

库下载地址:sqlite3 - npm (npmjs.com)

npm install sqlite3

案例

持久化缓存

<!doctype html>
<html>
​
<head>
    <meta charset="utf8">
    <title>Persistent sqlite</title>
    <script src="../dist/sql-wasm.js"></script>
</head>
​
<body>
    <p>You have seen this page <span id="views">0</span> times.</p>
    <div>
        You have been here on the following dates: <ol id="dates"></ol>
    </div>
    <script>
        var baseUrl = '../dist/';
​
        function toBinArray(str) {
            var l = str.length,
                arr = new Uint8Array(l);
            for (var i = 0; i < l; i++) arr[i] = str.charCodeAt(i);
            return arr;
        }
​
        function toBinString(arr) {
            var uarr = new Uint8Array(arr);
            var strings = [], chunksize = 0xffff;
            // There is a maximum stack size. We cannot call String.fromCharCode with as many arguments as we want
            for (var i = 0; i * chunksize < uarr.length; i++) {
                strings.push(String.fromCharCode.apply(null, uarr.subarray(i * chunksize, (i + 1) * chunksize)));
            }
            return strings.join('');
        }
​
        // Normally Sql.js tries to load sql-wasm.wasm relative to the page, not relative to the javascript
        // doing the loading. So, we help it find the .wasm file with this function.
        var config = {
            locateFile: filename => `${baseUrl}/${filename}`
        }
        initSqlJs(config).then(function (SQL) {
            var dbstr = window.localStorage.getItem("viewcount.sqlite");
            if (dbstr) {
                var db = new SQL.Database(toBinArray(dbstr));
            } else {
                var db = new SQL.Database();
                db.run("CREATE TABLE views (date INTEGER PRIMARY KEY)");
            }
            db.run("INSERT INTO views(date) VALUES (?)", [Date.now()]);
​
            document.getElementById('views').textContent = db.exec("SELECT COUNT(*) FROM views")[0].values[0][0];
​
            var count = 0,
                dates = document.getElementById("dates");
​
            db.each("SELECT date FROM views ORDER BY date ASC",
                function callback(row) {
                    var li = document.createElement("li");
                    li.textContent = new Date(row.date);
                    dates.appendChild(li);
                }, function done() {
                    var dbstr = toBinString(db.export());
                    window.localStorage.setItem("viewcount.sqlite", dbstr);
                }
            );
        });
​
    </script>
</body>
​
</html>

交互案例

<!doctype html>
<html>
<!--Simple Read eval print loop for SQL-->
​
<head>
    <meta charset="utf8">
    <title>SQL REPL</title>
    <script src="../dist/sql-wasm.js"></script>
</head>
​
<body>
    <input type='text' id='input' placeholder="ENTER SOME SQL" size='50'
        value="CREATE TABLE test(val);INSERT INTO test VALUES (666); SELECT * FROM test">
    <button id='submit'>Execute</button>
    <pre id='result'></pre>
    <pre id='error'></pre>
    <script>
​
        //Open a blank database
        var db;
        initSqlJs({ locateFile: filename => `../dist/${filename}` }).then(function (SQL) {
            db = new SQL.Database();
        });
​
        document.getElementById('submit').onclick = function () {
            var sql = document.getElementById('input').value;
            var result = '', error = '';
            try { result = db.exec(sql); }
            catch (e) { error = e; }
            document.getElementById('result').innerHTML = JSON.stringify(result, null, '  ');
            document.getElementById('error').innerHTML = error;
        };
    </script>
</body>

代码解析

initSqlJs 函数

API 中的根对象是 initSqlJs 函数,它接受一个 SqlJsConfig 参数,并返回一个 SqlJs 对象

SqlJs 对象

initSqlJs返回主 sql.js 对象 SqlJs 模块,其中包含:

常用操作

详细api请移步官方文档sql.js

创建数据库/导入数据

// 创建一个新的数据库实例
const db = new SQL.Database();
// 创建并加载数据(见案例章节)
var db = new SQL.Database(toBinArray(dbstr));

查询

// 执行一个 INSERT 语句
db.run("INSERT INTO tasks (name, priority) VALUES ('Buy groceries', 'high')");
​
// 执行一个 SELECT 语句
const result = db.exec("SELECT * FROM tasks WHERE priority='high'");
​
// 输出结果
console.log(result);
​

导出

// 导出数据库
const databaseBlob = db.export();

可能遇到的问题

1. 配置 Vite 以包括 .db 文件

vite.config.js 中,您可以添加以下配置:

javascriptCopy Code
import { defineConfig } from 'vite';

export default defineConfig({
  assetsInclude: ['**/*.db'],
});

2. 确保文件路径正确

确保您在项目中引用 .db 文件的路径是正确的。例如:

const dbFilePath = './path/to/your.db'; // 确保路径正确

3. 处理 .db 文件

在代码中,确保您正确加载和处理 .db 文件。例如,使用 fetch 来获取文件内容:

javascriptCopy Code
const response = await fetch(dbFilePath);
// 转换成buffer
const data = await response.arrayBuffer();
const db = new SQL.Database(new Uint8Array(data)); // 从文件加载数据库

完结

sqlite确实好用,如无必要,勿增实体


http://www.kler.cn/news/367560.html

相关文章:

  • 构建最新的LLaMA-Factory镜像
  • 【知识科普】正则表达式深入解读
  • RISC-V笔记——显式同步
  • 【LeetCode:264. 丑数 II + 小根堆】
  • 传输层UDP
  • 在linux系统中查看具体文件大小命令
  • ffmpeg视频滤镜: 色温- colortemperature
  • Windows 11 绕过 TPM 方法总结,24H2 通用免 TPM 镜像下载 (Updated Oct 2024)
  • java项目之在线考试系统设计与实现(springboot)
  • 通过AWS Bedrock探索 Claude 的虚拟桌面魔力:让 AI 代替你动手完成任务!
  • 时间数据可视化基础实验(南丁格尔玫瑰图)——Python热狗大胃王比赛数据集
  • 蓝桥杯普及题
  • Android中导入讯飞大模型ai智能系统
  • nodejs写入日志文件
  • Linux: Shell编程中的应用之基于sh进行数据统计
  • 【C++ 真题】B2106 矩阵转置
  • 基于java SpringBoot和Vue校园求职招聘系统设计
  • 【牛客算法】某司面试算法题:设计LRU缓存结构
  • static 关键字的用法
  • 【Java】LinkedList实现类的使用
  • 苹果预告下周发布Mac新品:全系标配M4系列芯片
  • 前端处理API接口故障:多接口自动切换的实现方案
  • bluez hid host介绍,连接键盘/鼠标/手柄不是梦,安排
  • 日常实习与暑期实习详解
  • java使用正则表达式校验字符串pwd,是否符合包含大写小写数字特殊字符长度超过8位
  • Codeforces Round 981 (Div. 3) A - E 详细题解(C++)