鸿蒙PC Electron框架实战:数据管理与持久化方案
·
欢迎加入开源鸿蒙PC社区:https://harmonypc.csdn.net/
atomgit仓库地址: https://atomgit.com/feng8403000/cms



一、引言
1.1 数据管理的重要性
在桌面应用中,数据管理是核心功能之一。一个可靠的数据管理系统需要:
- 数据持久化:确保数据在应用关闭后不丢失
- 数据完整性:保证数据的准确性和一致性
- 数据安全性:保护敏感数据不被泄露
- 数据可访问性:提供高效的数据查询和操作接口
1.2 Electron中的数据存储方案
在Electron应用中,常用的数据存储方案包括:
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| LocalStorage | 轻量级配置数据 | 简单易用,无需额外依赖 | 容量有限(约5MB),仅支持字符串 |
| IndexedDB | 结构化数据存储 | 支持复杂查询,容量大 | API复杂,异步操作 |
| SQLite | 关系型数据存储 | 强大的查询能力,事务支持 | 需要native依赖,部署复杂 |
| 文件系统 | 大量数据或二进制文件 | 灵活,容量不受限 | 需要手动管理文件结构 |
1.3 本章概述
本章将详细介绍如何在鸿蒙PC Electron应用中设计和实现一个完整的数据管理系统,包括:
- 数据模型设计
- 存储方案选择
- 数据操作API
- 数据同步策略
- 性能优化方案
二、数据模型设计
2.1 核心数据模型
// 文章模型
class Article {
constructor(data) {
this.id = data.id || `art-${Date.now()}`;
this.title = data.title || '';
this.excerpt = data.excerpt || '';
this.content = data.content || '';
this.categoryId = data.categoryId || null;
this.tagIds = data.tagIds || [];
this.status = data.status || 'draft'; // draft, published, archived
this.createdAt = data.createdAt || new Date().toISOString();
this.updatedAt = data.updatedAt || new Date().toISOString();
this.readCount = data.readCount || 0;
this.likeCount = data.likeCount || 0;
this.author = data.author || 'Anonymous';
this.metadata = data.metadata || {};
}
validate() {
const errors = [];
if (!this.title.trim()) {
errors.push('文章标题不能为空');
}
if (!this.content.trim()) {
errors.push('文章内容不能为空');
}
if (!['draft', 'published', 'archived'].includes(this.status)) {
errors.push('无效的文章状态');
}
return errors;
}
toJSON() {
return {
id: this.id,
title: this.title,
excerpt: this.excerpt,
content: this.content,
categoryId: this.categoryId,
tagIds: this.tagIds,
status: this.status,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
readCount: this.readCount,
likeCount: this.likeCount,
author: this.author,
metadata: this.metadata
};
}
static fromJSON(json) {
return new Article(json);
}
}
// 分类模型
class Category {
constructor(data) {
this.id = data.id || `cat-${Date.now()}`;
this.name = data.name || '';
this.description = data.description || '';
this.icon = data.icon || 'folder';
this.parentId = data.parentId || null;
this.order = data.order || 0;
this.createdAt = data.createdAt || new Date().toISOString();
this.updatedAt = data.updatedAt || new Date().toISOString();
}
validate() {
const errors = [];
if (!this.name.trim()) {
errors.push('分类名称不能为空');
}
return errors;
}
toJSON() {
return {
id: this.id,
name: this.name,
description: this.description,
icon: this.icon,
parentId: this.parentId,
order: this.order,
createdAt: this.createdAt,
updatedAt: this.updatedAt
};
}
static fromJSON(json) {
return new Category(json);
}
}
// 标签模型
class Tag {
constructor(data) {
this.id = data.id || `tag-${Date.now()}`;
this.name = data.name || '';
this.color = data.color || '#4caf50';
this.description = data.description || '';
this.createdAt = data.createdAt || new Date().toISOString();
}
validate() {
const errors = [];
if (!this.name.trim()) {
errors.push('标签名称不能为空');
}
// 验证颜色格式
if (!/^#[0-9A-Fa-f]{6}$/.test(this.color)) {
errors.push('无效的颜色格式');
}
return errors;
}
toJSON() {
return {
id: this.id,
name: this.name,
color: this.color,
description: this.description,
createdAt: this.createdAt
};
}
static fromJSON(json) {
return new Tag(json);
}
}
// 用户设置模型
class UserSettings {
constructor(data) {
this.theme = data.theme || 'tech';
this.language = data.language || 'zh-CN';
this.editorFontSize = data.editorFontSize || 14;
this.autoSaveInterval = data.autoSaveInterval || 30;
this.showPreview = data.showPreview || true;
this.notificationsEnabled = data.notificationsEnabled || true;
this.createdAt = data.createdAt || new Date().toISOString();
this.updatedAt = data.updatedAt || new Date().toISOString();
}
toJSON() {
return {
theme: this.theme,
language: this.language,
editorFontSize: this.editorFontSize,
autoSaveInterval: this.autoSaveInterval,
showPreview: this.showPreview,
notificationsEnabled: this.notificationsEnabled,
createdAt: this.createdAt,
updatedAt: this.updatedAt
};
}
static fromJSON(json) {
return new UserSettings(json);
}
}
2.2 数据关系设计
┌─────────────────────────────────────────────────────────────────┐
│ 数据关系图 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Article (文章) │
│ ├─ id (主键) │
│ ├─ categoryId → Category.id (外键) │
│ ├─ tagIds[] → Tag.id (多对多) │
│ └─ 其他字段... │
│ │
│ Category (分类) │
│ ├─ id (主键) │
│ ├─ parentId → Category.id (自引用,支持层级) │
│ └─ 其他字段... │
│ │
│ Tag (标签) │
│ ├─ id (主键) │
│ └─ 其他字段... │
│ │
│ UserSettings (用户设置) │
│ └─ 无外键关联 │
│ │
└─────────────────────────────────────────────────────────────────┘
三、存储方案实现
3.1 LocalStorage适配器
class LocalStorageAdapter {
constructor(prefix = 'article-manager') {
this.prefix = prefix;
}
getKey(key) {
return `${this.prefix}:${key}`;
}
getItem(key) {
try {
const item = localStorage.getItem(this.getKey(key));
return item ? JSON.parse(item) : null;
} catch (error) {
console.error(`读取 ${key} 失败:`, error);
return null;
}
}
setItem(key, value) {
try {
localStorage.setItem(this.getKey(key), JSON.stringify(value));
return true;
} catch (error) {
console.error(`写入 ${key} 失败:`, error);
return false;
}
}
removeItem(key) {
try {
localStorage.removeItem(this.getKey(key));
return true;
} catch (error) {
console.error(`删除 ${key} 失败:`, error);
return false;
}
}
clear() {
try {
const keys = Object.keys(localStorage).filter(key =>
key.startsWith(`${this.prefix}:`)
);
keys.forEach(key => localStorage.removeItem(key));
return true;
} catch (error) {
console.error('清空存储失败:', error);
return false;
}
}
getAllKeys() {
try {
return Object.keys(localStorage).filter(key =>
key.startsWith(`${this.prefix}:`)
);
} catch (error) {
console.error('获取所有键失败:', error);
return [];
}
}
}
3.2 数据存储管理器
class DataStorageManager {
constructor() {
this.adapter = new LocalStorageAdapter();
this.cache = new Map();
this.autoSaveInterval = null;
this.pendingChanges = new Set();
this.initAutoSave();
}
initAutoSave() {
this.autoSaveInterval = setInterval(() => {
this.flushPendingChanges();
}, 30000); // 每30秒自动保存
}
stopAutoSave() {
if (this.autoSaveInterval) {
clearInterval(this.autoSaveInterval);
}
}
// 文章操作
saveArticle(article) {
const key = `articles:${article.id}`;
this.adapter.setItem(key, article.toJSON());
this.cache.set(key, article);
this.pendingChanges.add(key);
return article;
}
getArticle(id) {
const key = `articles:${id}`;
// 先从缓存获取
if (this.cache.has(key)) {
return this.cache.get(key);
}
// 从存储获取
const data = this.adapter.getItem(key);
if (data) {
const article = Article.fromJSON(data);
this.cache.set(key, article);
return article;
}
return null;
}
getAllArticles() {
const keys = this.adapter.getAllKeys().filter(k => k.startsWith('article-manager:articles:'));
const articles = [];
keys.forEach(key => {
const data = this.adapter.getItem(key.replace('article-manager:', ''));
if (data) {
articles.push(Article.fromJSON(data));
}
});
return articles.sort((a, b) =>
new Date(b.createdAt) - new Date(a.createdAt)
);
}
deleteArticle(id) {
const key = `articles:${id}`;
this.adapter.removeItem(key);
this.cache.delete(key);
this.pendingChanges.delete(key);
}
// 分类操作
saveCategory(category) {
const key = `categories:${category.id}`;
this.adapter.setItem(key, category.toJSON());
this.cache.set(key, category);
this.pendingChanges.add(key);
return category;
}
getCategory(id) {
const key = `categories:${id}`;
if (this.cache.has(key)) {
return this.cache.get(key);
}
const data = this.adapter.getItem(key);
if (data) {
const category = Category.fromJSON(data);
this.cache.set(key, category);
return category;
}
return null;
}
getAllCategories() {
const keys = this.adapter.getAllKeys().filter(k => k.startsWith('article-manager:categories:'));
const categories = [];
keys.forEach(key => {
const data = this.adapter.getItem(key.replace('article-manager:', ''));
if (data) {
categories.push(Category.fromJSON(data));
}
});
return categories.sort((a, b) => a.order - b.order);
}
deleteCategory(id) {
const key = `categories:${id}`;
this.adapter.removeItem(key);
this.cache.delete(key);
this.pendingChanges.delete(key);
// 删除关联的文章或更新文章的categoryId
const articles = this.getAllArticles();
articles.forEach(article => {
if (article.categoryId === id) {
article.categoryId = null;
this.saveArticle(article);
}
});
}
// 标签操作
saveTag(tag) {
const key = `tags:${tag.id}`;
this.adapter.setItem(key, tag.toJSON());
this.cache.set(key, tag);
this.pendingChanges.add(key);
return tag;
}
getTag(id) {
const key = `tags:${id}`;
if (this.cache.has(key)) {
return this.cache.get(key);
}
const data = this.adapter.getItem(key);
if (data) {
const tag = Tag.fromJSON(data);
this.cache.set(key, tag);
return tag;
}
return null;
}
getAllTags() {
const keys = this.adapter.getAllKeys().filter(k => k.startsWith('article-manager:tags:'));
const tags = [];
keys.forEach(key => {
const data = this.adapter.getItem(key.replace('article-manager:', ''));
if (data) {
tags.push(Tag.fromJSON(data));
}
});
return tags.sort((a, b) => a.name.localeCompare(b.name));
}
deleteTag(id) {
const key = `tags:${id}`;
this.adapter.removeItem(key);
this.cache.delete(key);
this.pendingChanges.delete(key);
// 从所有文章中移除该标签
const articles = this.getAllArticles();
articles.forEach(article => {
const index = article.tagIds.indexOf(id);
if (index !== -1) {
article.tagIds.splice(index, 1);
this.saveArticle(article);
}
});
}
// 用户设置操作
saveUserSettings(settings) {
const key = 'user-settings';
this.adapter.setItem(key, settings.toJSON());
this.cache.set(key, settings);
this.pendingChanges.add(key);
return settings;
}
getUserSettings() {
const key = 'user-settings';
if (this.cache.has(key)) {
return this.cache.get(key);
}
const data = this.adapter.getItem(key);
if (data) {
const settings = UserSettings.fromJSON(data);
this.cache.set(key, settings);
return settings;
}
// 返回默认设置
return new UserSettings({});
}
// 统计信息
getStats() {
const articles = this.getAllArticles();
const categories = this.getAllCategories();
const tags = this.getAllTags();
const published = articles.filter(a => a.status === 'published').length;
const drafts = articles.filter(a => a.status === 'draft').length;
const totalReads = articles.reduce((sum, a) => sum + a.readCount, 0);
const totalLikes = articles.reduce((sum, a) => sum + a.likeCount, 0);
return {
totalArticles: articles.length,
published,
drafts,
totalReads,
totalLikes,
totalCategories: categories.length,
totalTags: tags.length
};
}
// 刷新缓存
refreshCache() {
this.cache.clear();
}
// 刷新特定类型的缓存
refreshCacheByType(type) {
this.cache.forEach((value, key) => {
if (key.startsWith(`${type}:`)) {
this.cache.delete(key);
}
});
}
// 手动触发保存
flushPendingChanges() {
if (this.pendingChanges.size === 0) return;
console.log(`正在保存 ${this.pendingChanges.size} 个更改...`);
this.pendingChanges.forEach(key => {
const item = this.cache.get(key);
if (item) {
this.adapter.setItem(key, item.toJSON ? item.toJSON() : item);
}
});
this.pendingChanges.clear();
console.log('保存完成');
}
// 导出数据
exportData() {
const data = {
articles: this.getAllArticles().map(a => a.toJSON()),
categories: this.getAllCategories().map(c => c.toJSON()),
tags: this.getAllTags().map(t => t.toJSON()),
userSettings: this.getUserSettings().toJSON(),
exportTime: new Date().toISOString(),
version: '1.0.0'
};
return JSON.stringify(data, null, 2);
}
// 导入数据
importData(jsonString) {
try {
const data = JSON.parse(jsonString);
// 清空现有数据
this.adapter.clear();
this.cache.clear();
this.pendingChanges.clear();
// 导入分类
if (data.categories) {
data.categories.forEach(catData => {
const category = Category.fromJSON(catData);
this.saveCategory(category);
});
}
// 导入标签
if (data.tags) {
data.tags.forEach(tagData => {
const tag = Tag.fromJSON(tagData);
this.saveTag(tag);
});
}
// 导入文章
if (data.articles) {
data.articles.forEach(artData => {
const article = Article.fromJSON(artData);
this.saveArticle(article);
});
}
// 导入用户设置
if (data.userSettings) {
const settings = UserSettings.fromJSON(data.userSettings);
this.saveUserSettings(settings);
}
this.flushPendingChanges();
return { success: true, message: '数据导入成功' };
} catch (error) {
console.error('数据导入失败:', error);
return { success: false, message: `导入失败: ${error.message}` };
}
}
}
四、数据操作API
4.1 统一数据访问层
class DataAccessLayer {
constructor() {
this.storage = new DataStorageManager();
this.observers = new Map();
}
// 文章API
async createArticle(data) {
const article = new Article(data);
const errors = article.validate();
if (errors.length > 0) {
throw new Error(errors.join('; '));
}
return this.storage.saveArticle(article);
}
async updateArticle(id, data) {
const article = this.storage.getArticle(id);
if (!article) {
throw new Error('文章不存在');
}
// 更新字段
Object.assign(article, data);
article.updatedAt = new Date().toISOString();
const errors = article.validate();
if (errors.length > 0) {
throw new Error(errors.join('; '));
}
return this.storage.saveArticle(article);
}
async getArticle(id) {
const article = this.storage.getArticle(id);
if (!article) {
throw new Error('文章不存在');
}
return article;
}
async getAllArticles(filters = {}) {
let articles = this.storage.getAllArticles();
// 状态过滤
if (filters.status) {
articles = articles.filter(a => a.status === filters.status);
}
// 分类过滤
if (filters.categoryId) {
articles = articles.filter(a => a.categoryId === filters.categoryId);
}
// 标签过滤
if (filters.tagId) {
articles = articles.filter(a => a.tagIds.includes(filters.tagId));
}
// 搜索过滤
if (filters.search) {
const searchLower = filters.search.toLowerCase();
articles = articles.filter(a =>
a.title.toLowerCase().includes(searchLower) ||
a.excerpt.toLowerCase().includes(searchLower) ||
a.content.toLowerCase().includes(searchLower)
);
}
// 排序
if (filters.sortBy) {
articles.sort((a, b) => {
if (filters.sortOrder === 'desc') {
return new Date(b[filters.sortBy]) - new Date(a[filters.sortBy]);
}
return new Date(a[filters.sortBy]) - new Date(b[filters.sortBy]);
});
}
// 分页
if (filters.page && filters.pageSize) {
const start = (filters.page - 1) * filters.pageSize;
const end = start + filters.pageSize;
articles = articles.slice(start, end);
}
return articles;
}
async deleteArticle(id) {
const article = this.storage.getArticle(id);
if (!article) {
throw new Error('文章不存在');
}
this.storage.deleteArticle(id);
this.notifyObservers('articleDeleted', { id });
}
// 分类API
async createCategory(data) {
const category = new Category(data);
const errors = category.validate();
if (errors.length > 0) {
throw new Error(errors.join('; '));
}
const saved = this.storage.saveCategory(category);
this.notifyObservers('categoryCreated', saved);
return saved;
}
async updateCategory(id, data) {
const category = this.storage.getCategory(id);
if (!category) {
throw new Error('分类不存在');
}
Object.assign(category, data);
category.updatedAt = new Date().toISOString();
const errors = category.validate();
if (errors.length > 0) {
throw new Error(errors.join('; '));
}
const saved = this.storage.saveCategory(category);
this.notifyObservers('categoryUpdated', saved);
return saved;
}
async getCategory(id) {
const category = this.storage.getCategory(id);
if (!category) {
throw new Error('分类不存在');
}
return category;
}
async getAllCategories() {
return this.storage.getAllCategories();
}
async deleteCategory(id) {
const category = this.storage.getCategory(id);
if (!category) {
throw new Error('分类不存在');
}
this.storage.deleteCategory(id);
this.notifyObservers('categoryDeleted', { id });
}
// 标签API
async createTag(data) {
const tag = new Tag(data);
const errors = tag.validate();
if (errors.length > 0) {
throw new Error(errors.join('; '));
}
const saved = this.storage.saveTag(tag);
this.notifyObservers('tagCreated', saved);
return saved;
}
async updateTag(id, data) {
const tag = this.storage.getTag(id);
if (!tag) {
throw new Error('标签不存在');
}
Object.assign(tag, data);
const errors = tag.validate();
if (errors.length > 0) {
throw new Error(errors.join('; '));
}
const saved = this.storage.saveTag(tag);
this.notifyObservers('tagUpdated', saved);
return saved;
}
async getTag(id) {
const tag = this.storage.getTag(id);
if (!tag) {
throw new Error('标签不存在');
}
return tag;
}
async getAllTags() {
return this.storage.getAllTags();
}
async deleteTag(id) {
const tag = this.storage.getTag(id);
if (!tag) {
throw new Error('标签不存在');
}
this.storage.deleteTag(id);
this.notifyObservers('tagDeleted', { id });
}
// 用户设置API
async getUserSettings() {
return this.storage.getUserSettings();
}
async updateUserSettings(data) {
const settings = this.storage.getUserSettings();
Object.assign(settings, data);
settings.updatedAt = new Date().toISOString();
const saved = this.storage.saveUserSettings(settings);
this.notifyObservers('settingsUpdated', saved);
return saved;
}
// 统计API
async getStats() {
return this.storage.getStats();
}
// 导出/导入API
async exportData() {
return this.storage.exportData();
}
async importData(jsonString) {
const result = this.storage.importData(jsonString);
if (result.success) {
this.notifyObservers('dataImported', {});
}
return result;
}
// 观察者模式
subscribe(eventType, callback) {
if (!this.observers.has(eventType)) {
this.observers.set(eventType, []);
}
this.observers.get(eventType).push(callback);
}
unsubscribe(eventType, callback) {
const callbacks = this.observers.get(eventType);
if (callbacks) {
const index = callbacks.indexOf(callback);
if (index !== -1) {
callbacks.splice(index, 1);
}
}
}
notifyObservers(eventType, data) {
const callbacks = this.observers.get(eventType);
if (callbacks) {
callbacks.forEach(callback => {
try {
callback(data);
} catch (error) {
console.error(`观察者回调失败:`, error);
}
});
}
}
}
五、数据同步策略
5.1 本地缓存策略
class CacheStrategy {
constructor() {
this.cache = new Map();
this.maxAge = 300000; // 5分钟过期
this.maxSize = 100; // 最大缓存数量
}
get(key) {
const item = this.cache.get(key);
if (!item) {
return null;
}
// 检查是否过期
if (Date.now() - item.timestamp > this.maxAge) {
this.cache.delete(key);
return null;
}
return item.value;
}
set(key, value) {
// 如果缓存已满,删除最旧的条目
if (this.cache.size >= this.maxSize) {
let oldestKey = null;
let oldestTime = Date.now();
this.cache.forEach((item, k) => {
if (item.timestamp < oldestTime) {
oldestTime = item.timestamp;
oldestKey = k;
}
});
if (oldestKey) {
this.cache.delete(oldestKey);
}
}
this.cache.set(key, {
value,
timestamp: Date.now()
});
}
delete(key) {
this.cache.delete(key);
}
clear() {
this.cache.clear();
}
has(key) {
return this.cache.has(key);
}
getSize() {
return this.cache.size;
}
// 缓存预热
preload(keys, fetchFunction) {
keys.forEach(key => {
if (!this.has(key)) {
const value = fetchFunction(key);
if (value) {
this.set(key, value);
}
}
});
}
}
5.2 离线数据同步
class OfflineSyncManager {
constructor() {
this.queue = [];
this.isSyncing = false;
this.syncInterval = null;
this.lastSyncTime = null;
}
addOperation(operation) {
this.queue.push({
...operation,
timestamp: Date.now(),
id: `op-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
});
// 如果队列超过一定数量,触发同步
if (this.queue.length >= 10) {
this.triggerSync();
}
}
async triggerSync() {
if (this.isSyncing) {
return;
}
this.isSyncing = true;
try {
const operationsToSync = [...this.queue];
this.queue = [];
for (const operation of operationsToSync) {
await this.executeOperation(operation);
}
this.lastSyncTime = Date.now();
console.log('同步完成');
} catch (error) {
console.error('同步失败:', error);
// 将失败的操作放回队列
this.queue = [...operationsToSync, ...this.queue];
} finally {
this.isSyncing = false;
}
}
async executeOperation(operation) {
switch (operation.type) {
case 'create':
await this.createItem(operation);
break;
case 'update':
await this.updateItem(operation);
break;
case 'delete':
await this.deleteItem(operation);
break;
default:
console.warn(`未知操作类型: ${operation.type}`);
}
}
async createItem(operation) {
// 实际的创建逻辑
console.log(`创建 ${operation.collection}:`, operation.data);
}
async updateItem(operation) {
// 实际的更新逻辑
console.log(`更新 ${operation.collection} ${operation.id}:`, operation.data);
}
async deleteItem(operation) {
// 实际的删除逻辑
console.log(`删除 ${operation.collection} ${operation.id}`);
}
startAutoSync(interval = 60000) {
this.syncInterval = setInterval(() => {
if (this.queue.length > 0 && !this.isSyncing) {
this.triggerSync();
}
}, interval);
}
stopAutoSync() {
if (this.syncInterval) {
clearInterval(this.syncInterval);
}
}
getQueueLength() {
return this.queue.length;
}
getLastSyncTime() {
return this.lastSyncTime;
}
clearQueue() {
this.queue = [];
}
}
六、性能优化方案
6.1 批量操作优化
class BatchOperationManager {
constructor() {
this.batches = new Map();
this.batchTimeout = 500; // 500ms内的操作合并
}
scheduleOperation(collection, operation) {
if (!this.batches.has(collection)) {
this.batches.set(collection, []);
}
this.batches.get(collection).push(operation);
// 设置延迟执行
this.scheduleBatchExecution(collection);
}
scheduleBatchExecution(collection) {
const key = `batch-${collection}`;
// 如果已经有定时器,不重复设置
if (this.timers && this.timers[key]) {
return;
}
setTimeout(() => {
this.executeBatch(collection);
if (this.timers) {
delete this.timers[key];
}
}, this.batchTimeout);
}
async executeBatch(collection) {
const operations = this.batches.get(collection) || [];
if (operations.length === 0) {
return;
}
try {
// 按操作类型分组
const grouped = operations.reduce((acc, op) => {
if (!acc[op.type]) {
acc[op.type] = [];
}
acc[op.type].push(op);
return acc;
}, {});
// 批量执行
for (const [type, ops] of Object.entries(grouped)) {
await this.executeBatchByType(collection, type, ops);
}
console.log(`批量执行完成: ${collection} - ${operations.length} 个操作`);
} catch (error) {
console.error(`批量执行失败: ${collection}`, error);
} finally {
this.batches.set(collection, []);
}
}
async executeBatchByType(collection, type, operations) {
switch (type) {
case 'create':
await this.batchCreate(collection, operations);
break;
case 'update':
await this.batchUpdate(collection, operations);
break;
case 'delete':
await this.batchDelete(collection, operations);
break;
}
}
async batchCreate(collection, operations) {
for (const op of operations) {
// 创建操作
}
}
async batchUpdate(collection, operations) {
for (const op of operations) {
// 更新操作
}
}
async batchDelete(collection, operations) {
for (const op of operations) {
// 删除操作
}
}
}
6.2 索引优化
class DataIndexer {
constructor() {
this.indexes = new Map();
}
createIndex(collection, field) {
const indexKey = `${collection}:${field}`;
if (!this.indexes.has(indexKey)) {
this.indexes.set(indexKey, new Map());
}
return this.indexes.get(indexKey);
}
updateIndex(collection, field, id, value) {
const index = this.createIndex(collection, field);
// 如果值是数组,为每个元素创建索引
if (Array.isArray(value)) {
value.forEach(v => {
if (!index.has(v)) {
index.set(v, new Set());
}
index.get(v).add(id);
});
} else {
if (!index.has(value)) {
index.set(value, new Set());
}
index.get(value).add(id);
}
}
queryByIndex(collection, field, value) {
const index = this.indexes.get(`${collection}:${field}`);
if (!index) {
return [];
}
const ids = index.get(value);
return ids ? Array.from(ids) : [];
}
removeFromIndex(collection, field, id, oldValue) {
const index = this.indexes.get(`${collection}:${field}`);
if (!index) {
return;
}
if (Array.isArray(oldValue)) {
oldValue.forEach(v => {
const ids = index.get(v);
if (ids) {
ids.delete(id);
}
});
} else {
const ids = index.get(oldValue);
if (ids) {
ids.delete(id);
}
}
}
clearIndex(collection, field) {
const indexKey = `${collection}:${field}`;
this.indexes.delete(indexKey);
}
rebuildIndex(collection, field, items) {
this.clearIndex(collection, field);
items.forEach(item => {
this.updateIndex(collection, field, item.id, item[field]);
});
}
getIndexStats() {
const stats = {};
this.indexes.forEach((index, key) => {
stats[key] = {
entries: index.size,
totalIds: Array.from(index.values()).reduce((sum, ids) => sum + ids.size, 0)
};
});
return stats;
}
}
七、总结与展望
7.1 功能回顾
本章详细介绍了数据管理与持久化方案的设计与实现,包括:
- 数据模型设计:文章、分类、标签、用户设置的完整模型
- 存储方案:LocalStorage适配器和数据存储管理器
- 数据API:统一的数据访问层,支持CRUD操作和查询过滤
- 同步策略:缓存策略和离线同步机制
- 性能优化:批量操作和索引优化
7.2 技术亮点
- 模块化设计:数据层与业务逻辑分离
- 观察者模式:支持数据变更通知
- 缓存机制:提高数据访问效率
- 批量操作:减少存储操作次数
- 索引优化:加速查询操作
7.3 未来扩展
未来可以考虑添加以下功能:
- 云端同步:支持与云端服务同步数据
- 版本控制:支持数据版本管理和回滚
- 数据加密:保护敏感数据
- 全文搜索:支持文章内容的全文检索
- 数据迁移:支持不同存储方案之间的数据迁移
更多推荐
所有评论(0)