HTML5 本地数据库及应用

HTML5本地数据库及应用

目录


WebSQL

WebSQL 是 HTML5 规范中提出的一种基于 SQL 的客户端数据库存储技术,允许在浏览器端创建和操作关系型数据库。尽管 WebSQL 曾被纳入 HTML5 草案,但由于种种原因(如标准化进程停滞、缺乏跨浏览器支持等),它并未成为正式的 W3C 标准,且已被主流浏览器厂商弃用。目前,推荐使用 IndexedDB 作为浏览器端的数据库解决方案.

数据库创建与打开

使用 window.openDatabase() 函数创建或打开一个 WebSQL 数据库:

js 复制代码
let db = null;
try {
  db = openDatabase('myDatabase', '1.0', 'My Database Description', 2 * 1024 * 1024); // 最后一个参数是数据库大小限制,单位为字节
} catch (err) {
  console.error('Error creating/opening database:', err);
}

执行SQL

WebSQL 提供 transaction() 方法来开启一个事务,并在其回调函数中执行 SQL 查询。查询通过 executeSql() 方法执行,该方法接受 SQL 语句和参数数组(如果有),以及两个回调函数:一个用于处理查询结果,另一个用于处理执行错误。

js 复制代码
db.transaction(function(tx) {
  tx.executeSql('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)', [], function(tx, result) {
    console.log('Table "users" created or already exists.');
  }, function(tx, error) {
    console.error('Error creating table:', error);
  });
});

插入、查询、更新、删除数据

js 复制代码
// 插入数据
db.transaction(function(tx) {
  tx.executeSql('INSERT INTO users (name, email) VALUES (?, ?)', ['John Doe', 'john.doe@example.com'], function(tx, result) {
    console.log('User inserted successfully:', result.insertId);
  }, function(tx, error) {
    console.error('Error inserting user:', error);
  });
});

// 查询数据
db.transaction(function(tx) {
  tx.executeSql('SELECT * FROM users WHERE name = ?', ['John Doe'], function(tx, result) {
    for (let i = 0; i < result.rows.length; i++) {
      const row = result.rows.item(i);
      console.log('User:', row.id, row.name, row.email);
    }
  }, function(tx, error) {
    console.error('Error querying users:', error);
  });
});

// 更新数据
db.transaction(function(tx) {
  tx.executeSql('UPDATE users SET email = ? WHERE id = ?', ['new.email@example.com', 1], function(tx, result) {
    console.log('User updated successfully:', result.rowsAffected);
  }, function(tx, error) {
    console.error('Error updating user:', error);
  });
});

// 删除数据
db.transaction(function(tx) {
  tx.executeSql('DELETE FROM users WHERE id = ?', [1], function(tx, result) {
    console.log('User deleted successfully:', result.rowsAffected);
  }, function(tx, error) {
    console.error('Error deleting user:', error);
  });
});

事务处理

WebSQL 中的所有操作都必须在一个事务(Transaction)中进行。事务确保一组操作要么全部成功,要么全部失败(回滚)。上面的例子中,每个操作都已经封装在 transaction() 方法提供的回调函数中。

限制与弃用

尽管 WebSQL 为浏览器端的离线存储提供了关系型数据库的便利,但由于以下原因,它并未成为广泛接受的标准:

  • 标准化停滞:WebSQL 的标准化工作在 W3C 停滞不前,导致其未能成为正式的 HTML5 标准。
  • 跨浏览器支持问题:只有 Safari、Chrome 和 Opera 浏览器曾提供对 WebSQL 的支持。Firefox、IE/Edge 从未实现该技术。
  • 替代技术出现:IndexedDB,一种更灵活、更适合现代 web 应用的键值对存储机制,逐渐成为浏览器端数据库的首选方案。

IndexDB

IndexedDB用于在浏览器端存储大量结构化数据。与传统的 cookie、localStorage、sessionStorage 等基于字符串键值对的存储方式不同,IndexedDB 允许存储复杂的对象(包括二进制数据),并提供了索引、查询和事务处理等功能,使其更适合于构建复杂的离线应用和丰富的 web 客户端体验。

打开数据库

使用 indexedDB.open() 方法打开或创建数据库。该方法接受数据库名称和版本号作为参数,并返回一个 IDBRequest 对象。在 onsuccess 事件处理器中,可以访问到 IDBDatabase 对象,用于后续的数据库操作。

js 复制代码
let db;
const request = indexedDB.open('myDatabase', 1);

request.onerror = function(event) {
  console.error('Error opening IndexedDB:', event.target.error);
};

request.onsuccess = function(event) {
  db = event.target.result;
  console.log('Database opened successfully.');
};

request.onupgradeneeded = function(event) {
  // 如果数据库版本升级或首次创建,需要在此处创建或修改对象商店(Object Store)
  const db = event.target.result;
  const objectStore = db.createObjectStore('users', { keyPath: 'id' });
  objectStore.createIndex('nameIndex', 'name', { unique: false });
};

创建/修改对象

对象商店是 IndexedDB中存放数据的基本单元,类似于关系型数据库中的表。在 onupgradeneeded事件处理器中,可以使用createObjectStore()方法创建新的对象商店,或者通过deleteObjectStore()方法删除已有的对象商店。同时,可以为对象商店创建索引,以便进行高效查询。

插入数据

插入数据需先获取事务(Transaction),然后在事务上下文中使用 put() 或 add() 方法将数据写入对象商店。put()会覆盖已有键值的数据,而 add() 在键值已存在时会抛出错误。

js 复制代码
const transaction = db.transaction(['users'], 'readwrite');
const objectStore = transaction.objectStore('users');

const newUser = {
  id: 1,
  name: 'John Doe',
  email: 'john.doe@example.com'
};

objectStore.add(newUser).onsuccess = function(event) {
  console.log('User added successfully:', newUser);
};

transaction.oncomplete = function() {
  console.log('Transaction completed.');
};

transaction.onerror = function(event) {
  console.error('Transaction error:', event.target.error);
};

查询数据

查询数据同样需要获取事务和对象商店,然后使用 get()、getAll()、openCursor() 等方法进行查询。

js 复制代码
const transaction = db.transaction(['users'], 'readonly');
const objectStore = transaction.objectStore('users');

// 查询单个用户
const request = objectStore.get(1);
request.onsuccess = function(event) {
  const user = event.target.result;
  if (user) {
    console.log('Found user:', user);
  } else {
    console.log('User not found.');
  }
};

// 查询所有用户
const getAllRequest = objectStore.getAll();
getAllRequest.onsuccess = function(event) {
  const allUsers = event.target.result;
  console.log('All users:', allUsers);
};

// 使用游标遍历所有用户
const cursorRequest = objectStore.openCursor();
cursorRequest.onsuccess = function(event) {
  const cursor = event.target.result;
  if (cursor) {
    console.log('User:', cursor.value);
    cursor.continue();
  } else {
    console.log('End of cursor.');
  }
};

更新和删除数据

更新数据使用 put() 方法,删除数据使用 delete() 方法。与插入数据类似,这些操作应在事务上下文中进行。

js 复制代码
const transaction = db.transaction(['users'], 'readwrite');
const objectStore = transaction.objectStore('users');

// 更新用户
const updatedUser = {
  id: 1,
  name: 'John Smith',
  email: 'john.smith@example.com'
};
objectStore.put(updatedUser).onsuccess = function(event) {
  console.log('User updated successfully:', updatedUser);
};

// 删除用户
objectStore.delete(1).onsuccess = function(event) {
  console.log('User deleted successfully.');
};

// 事务处理同插入数据示例

索引优化查询

创建索引后,可以在查询时指定使用索引来加速查找。例如,使用 index() 方法获取索引对象,然后调用索引对象的查询方法。

js 复制代码
const transaction = db.transaction(['users'], 'readonly');
const objectStore = transaction.objectStore('users');
const nameIndex = objectStore.index('nameIndex');

// 查询所有名为 'John Doe' 的用户
const request = nameIndex.getAll('John Doe');
request.onsuccess = function(event) {
  const usersWithNameJohnDoe = event.target.result;
  console.log('Users named John Doe:', usersWithNameJohnDoe);
};
相关推荐
wno7044 小时前
postgresSQL压缩版安装与基本命令
数据库·postgresql
聚美智数6 小时前
智能结构化识别-图片结构解析-图像结构化解析-照片结构化解析
android·java·数据库
瀚高PG实验室6 小时前
瀚高数据库常用系统表查询入门指南(附常用SQL)
数据库·sql·postgresql·瀚高数据库
ben9518chen7 小时前
mysql数据库基本操作
数据库·mysql
2603_965148117 小时前
电商选品调研:通过关键词搜索API获取市场热销商品,结合商品详情API分析竞品卖点与定价
开发语言·数据库·人工智能·python·信息可视化
lpfasd1237 小时前
node-sass 停止维护!老项目迁移 Dart Sass 完整教程
前端·rust·sass
土豆.exe7 小时前
nf_tables 的 verdict 被读了两次:一个十年未闭合的位域错配
java·数据库·网络安全·缓存
缓慢更新8 小时前
表单引擎的存储建模:宽表与文档库的取舍
运维·服务器·网络·数据库·低代码·oracle·适配器模式
Web3&Basketball9 小时前
实测Gemini4Argon:ERQA 87%登顶长程任务榜
数据库·python·大模型·多模态·gemini·长上下文·推理优化
Data analyse4569 小时前
rnweb 回放数据量太大怎么办?分片存储与断点续传的实现思路
前端·网络·算法·数据分析