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

【2026最新】鸿蒙NEXT数据持久化实战:培训班管理系统数据存储全攻略

鸿蒙开发中数据总是丢失本地存储和网络请求搞不定本文用15分钟带你彻底搞懂Preferences、RDB、HTTP三大数据持久化方案附完整培训班管理系统实战代码和踩坑记录让你的鸿蒙App数据存储从此安全可靠一、学员信息本地存储1.1 Preferences轻量级存储Preferences适用于存储少量键值对数据如用户配置、登录状态等。// service/PreferencesHelper.ets import preferences from ohos.data.preferences; export class PreferencesHelper { private static instance: PreferencesHelper; private preferencesMap: Mapstring, preferences.Preferences new Map(); private constructor() {} static getInstance(): PreferencesHelper { if (!PreferencesHelper.instance) { PreferencesHelper.instance new PreferencesHelper(); } return PreferencesHelper.instance; } async getPreferences(context: Context, name: string): Promisepreferences.Preferences { if (this.preferencesMap.has(name)) { return this.preferencesMap.get(name)!; } const prefs await preferences.getPreferences(context, name); this.preferencesMap.set(name, prefs); return prefs; } async put(context: Context, name: string, key: string, value: preferences.ValueType): Promisevoid { const prefs await this.getPreferences(context, name); await prefs.put(key, value); await prefs.flush(); } async get(context: Context, name: string, key: string, defaultValue: preferences.ValueType): Promisepreferences.ValueType { const prefs await this.getPreferences(context, name); return await prefs.get(key, defaultValue); } async delete(context: Context, name: string, key: string): Promisevoid { const prefs await this.getPreferences(context, name); await prefs.delete(key); await prefs.flush(); } async clear(context: Context, name: string): Promisevoid { const prefs await this.getPreferences(context, name); await prefs.clear(); await prefs.flush(); } }1.2 用户配置存储// service/UserPreferences.ets import { PreferencesHelper } from ./PreferencesHelper; const PREFS_NAME user_prefs; export class UserPreferences { private static helper: PreferencesHelper PreferencesHelper.getInstance(); // 存储用户ID static async setUserId(context: Context, userId: string): Promisevoid { await this.helper.put(context, PREFS_NAME, user_id, userId); } // 获取用户ID static async getUserId(context: Context): Promisestring { return await this.helper.get(context, PREFS_NAME, user_id, ) as string; } // 存储登录状态 static async setLoginStatus(context: Context, isLoggedIn: boolean): Promisevoid { await this.helper.put(context, PREFS_NAME, is_logged_in, isLoggedIn); } // 获取登录状态 static async getLoginStatus(context: Context): Promiseboolean { return await this.helper.get(context, PREFS_NAME, is_logged_in, false) as boolean; } // 存储用户主题 static async setTheme(context: Context, theme: string): Promisevoid { await this.helper.put(context, PREFS_NAME, theme, theme); } // 获取用户主题 static async getTheme(context: Context): Promisestring { return await this.helper.get(context, PREFS_NAME, theme, light) as string; } // 存储语言设置 static async setLanguage(context: Context, language: string): Promisevoid { await this.helper.put(context, PREFS_NAME, language, language); } // 获取语言设置 static async getLanguage(context: Context): Promisestring { return await this.helper.get(context, PREFS_NAME, language, zh_CN) as string; } // 清除所有用户配置 static async clearAll(context: Context): Promisevoid { await this.helper.clear(context, PREFS_NAME); } }1.3 使用示例// pages/SettingsPage.ets import { UserPreferences } from ../service/UserPreferences; Entry Component struct SettingsPage { State theme: string light; State language: string zh_CN; State isLoggedIn: boolean false; async aboutToAppear() { this.theme await UserPreferences.getTheme(this.context); this.language await UserPreferences.getLanguage(this.context); this.isLoggedIn await UserPreferences.getLoginStatus(this.context); } build() { Column() { // 标题栏 TitleBar({ title: 设置, showBack: true }) List() { // 主题设置 ListItem() { this.SettingItem(主题模式, this.theme light ? 浅色 : 深色, () { this.toggleTheme(); }) } // 语言设置 ListItem() { this.SettingItem(语言, this.language zh_CN ? 简体中文 : English, () { this.toggleLanguage(); }) } // 清除数据 ListItem() { this.SettingItem(清除数据, , () { this.clearData(); }) } } .layoutWeight(1) } .width(100%) .height(100%) .backgroundColor(#F5F5F5) } Builder SettingItem(label: string, value: string, clickCallback: () void) { Row() { Text(label) .fontSize(16) .fontColor(#333333) Text(value) .fontSize(14) .fontColor(#999999) .layoutWeight(1) .textAlign(TextAlign.End) Image($r(app.media.ic_arrow_right)) .width(16) .height(16) .fillColor(#CCCCCC) } .width(100%) .height(56) .padding({ left: 16, right: 16 }) .backgroundColor(#FFFFFF) .onClick(clickCallback) } async toggleTheme() { this.theme this.theme light ? dark : light; await UserPreferences.setTheme(this.context, this.theme); } async toggleLanguage() { this.language this.language zh_CN ? en_US : zh_CN; await UserPreferences.setLanguage(this.context, this.language); } async clearData() { // 显示确认弹窗 AlertDialog.show({ title: 确认清除, message: 确定要清除所有本地数据吗, primaryButton: { value: 取消, action: () {} }, secondaryButton: { value: 确定, action: async () { await UserPreferences.clearAll(this.context); Utils.showToast(数据已清除); } } }); } }二、课程数据管理2.1 关系型数据库RDB使用RDB适用于存储结构化数据如学员信息、课程信息、报名记录等。// service/RdbHelper.ets import rdb from ohos.data.relationalStore; const DB_NAME training_management.db; const DB_VERSION 1; export class RdbHelper { private static instance: RdbHelper; private rdbStore: rdb.RdbStore | null null; private constructor() {} static getInstance(): RdbHelper { if (!RdbHelper.instance) { RdbHelper.instance new RdbHelper(); } return RdbHelper.instance; } async init(context: Context): Promisevoid { const config: rdb.StoreConfig { name: DB_NAME, securityLevel: rdb.SecurityLevel.S1 }; this.rdbStore await rdb.getRdbStore(context, config, DB_VERSION); await this.createTables(); } private async createTables(): Promisevoid { // 学员表 const createStudentTable CREATE TABLE IF NOT EXISTS student ( id TEXT PRIMARY KEY, name TEXT NOT NULL, phone TEXT, email TEXT, gender INTEGER DEFAULT 0, birthday TEXT, address TEXT, avatar TEXT, status INTEGER DEFAULT 0, create_time TEXT, update_time TEXT ) ; // 课程表 const createCourseTable CREATE TABLE IF NOT EXISTS course ( id TEXT PRIMARY KEY, name TEXT NOT NULL, description TEXT, teacher TEXT, price REAL, duration INTEGER, max_students INTEGER, current_students INTEGER DEFAULT 0, start_time TEXT, end_time TEXT, status INTEGER DEFAULT 0, create_time TEXT, update_time TEXT ) ; // 报名表 const createEnrollmentTable CREATE TABLE IF NOT EXISTS enrollment ( id TEXT PRIMARY KEY, student_id TEXT NOT NULL, course_id TEXT NOT NULL, enroll_time TEXT, status INTEGER DEFAULT 0, remark TEXT, create_time TEXT, update_time TEXT, FOREIGN KEY (student_id) REFERENCES student(id), FOREIGN KEY (course_id) REFERENCES course(id) ) ; await this.rdbStore?.executeSql(createStudentTable); await this.rdbStore?.executeSql(createCourseTable); await this.rdbStore?.executeSql(createEnrollmentTable); } getRdbStore(): rdb.RdbStore | null { return this.rdbStore; } }2.2 课程服务实现// service/CourseService.ets import { RdbHelper } from ./RdbHelper; import { Course } from ../model/Course; import rdb from ohos.data.relationalStore; export class CourseService { private rdbHelper: RdbHelper RdbHelper.getInstance(); // 插入课程 async insertCourse(course: Course): Promisevoid { const rdbStore this.rdbHelper.getRdbStore(); if (!rdbStore) return; const valueBucket: rdb.ValueBucket { id: course.id, name: course.name, description: course.description, teacher: course.teacher, price: course.price, duration: course.duration, max_students: course.maxStudents, current_students: course.currentStudents, start_time: course.startTime, end_time: course.endTime, status: course.status, create_time: course.createTime, update_time: course.updateTime }; await rdbStore.insert(course, valueBucket); } // 查询所有课程 async getAllCourses(): PromiseCourse[] { const rdbStore this.rdbHelper.getRdbStore(); if (!rdbStore) return []; const predicates new rdb.RdbPredicates(course); const resultSet await rdbStore.query(predicates, [ id, name, description, teacher, price, duration, max_students, current_students, start_time, end_time, status, create_time, update_time ]); const courses: Course[] []; while (resultSet.goToNextRow()) { const course: Course { id: resultSet.getString(resultSet.getColumnIndex(id)), name: resultSet.getString(resultSet.getColumnIndex(name)), description: resultSet.getString(resultSet.getColumnIndex(description)), teacher: resultSet.getString(resultSet.getColumnIndex(teacher)), price: resultSet.getDouble(resultSet.getColumnIndex(price)), duration: resultSet.getInt(resultSet.getColumnIndex(duration)), maxStudents: resultSet.getInt(resultSet.getColumnIndex(max_students)), currentStudents: resultSet.getInt(resultSet.getColumnIndex(current_students)), startTime: resultSet.getString(resultSet.getColumnIndex(start_time)), endTime: resultSet.getString(resultSet.getColumnIndex(end_time)), status: resultSet.getInt(resultSet.getColumnIndex(status)), createTime: resultSet.getString(resultSet.getColumnIndex(create_time)), updateTime: resultSet.getString(resultSet.getColumnIndex(update_time)) }; courses.push(course); } resultSet.close(); return courses; } // 根据ID查询课程 async getCourseById(courseId: string): PromiseCourse | null { const rdbStore this.rdbHelper.getRdbStore(); if (!rdbStore) return null; const predicates new rdb.RdbPredicates(course); predicates.equalTo(id, courseId); const resultSet await rdbStore.query(predicates, [ id, name, description, teacher, price, duration, max_students, current_students, start_time, end_time, status, create_time, update_time ]); if (resultSet.rowCount 0) { resultSet.close(); return null; } resultSet.goToNextRow(); const course: Course { id: resultSet.getString(resultSet.getColumnIndex(id)), name: resultSet.getString(resultSet.getColumnIndex(name)), description: resultSet.getString(resultSet.getColumnIndex(description)), teacher: resultSet.getString(resultSet.getColumnIndex(teacher)), price: resultSet.getDouble(resultSet.getColumnIndex(price)), duration: resultSet.getInt(resultSet.getColumnIndex(duration)), maxStudents: resultSet.getInt(resultSet.getColumnIndex(max_students)), currentStudents: resultSet.getInt(resultSet.getColumnIndex(current_students)), startTime: resultSet.getString(resultSet.getColumnIndex(start_time)), endTime: resultSet.getString(resultSet.getColumnIndex(end_time)), status: resultSet.getInt(resultSet.getColumnIndex(status)), createTime: resultSet.getString(resultSet.getColumnIndex(create_time)), updateTime: resultSet.getString(resultSet.getColumnIndex(update_time)) }; resultSet.close(); return course; } // 更新课程 async updateCourse(course: Course): Promisevoid { const rdbStore this.rdbHelper.getRdbStore(); if (!rdbStore) return; const valueBucket: rdb.ValueBucket { name: course.name, description: course.description, teacher: course.teacher, price: course.price, duration: course.duration, max_students: course.maxStudents, current_students: course.currentStudents, start_time: course.startTime, end_time: course.endTime, status: course.status, update_time: Utils.formatDate(new Date()) }; const predicates new rdb.RdbPredicates(course); predicates.equalTo(id, course.id); await rdbStore.update(valueBucket, predicates); } // 删除课程 async deleteCourse(courseId: string): Promisevoid { const rdbStore this.rdbHelper.getRdbStore(); if (!rdbStore) return; const predicates new rdb.RdbPredicates(course); predicates.equalTo(id, courseId); await rdbStore.delete(predicates); } // 搜索课程 async searchCourses(keyword: string): PromiseCourse[] { const rdbStore this.rdbHelper.getRdbStore(); if (!rdbStore) return []; const predicates new rdb.RdbPredicates(course); predicates.like(name, %${keyword}%); const resultSet await rdbStore.query(predicates, [ id, name, description, teacher, price, duration, max_students, current_students, start_time, end_time, status, create_time, update_time ]); const courses: Course[] []; while (resultSet.goToNextRow()) { const course: Course { id: resultSet.getString(resultSet.getColumnIndex(id)), name: resultSet.getString(resultSet.getColumnIndex(name)), description: resultSet.getString(resultSet.getColumnIndex(description)), teacher: resultSet.getString(resultSet.getColumnIndex(teacher)), price: resultSet.getDouble(resultSet.getColumnIndex(price)), duration: resultSet.getInt(resultSet.getColumnIndex(duration)), maxStudents: resultSet.getInt(resultSet.getColumnIndex(max_students)), currentStudents: resultSet.getInt(resultSet.getColumnIndex(current_students)), startTime: resultSet.getString(resultSet.getColumnIndex(start_time)), endTime: resultSet.getString(resultSet.getColumnIndex(end_time)), status: resultSet.getInt(resultSet.getColumnIndex(status)), createTime: resultSet.getString(resultSet.getColumnIndex(create_time)), updateTime: resultSet.getString(resultSet.getColumnIndex(update_time)) }; courses.push(course); } resultSet.close(); return courses; } // 获取课程统计 async getCourseStats(): Promise{ total: number; inProgress: number; ended: number } { const rdbStore this.rdbHelper.getRdbStore(); if (!rdbStore) return { total: 0, inProgress: 0, ended: 0 }; const totalResult await rdbStore.querySql(SELECT COUNT(*) as count FROM course); totalResult.goToNextRow(); const total totalResult.getInt(0); totalResult.close(); const inProgressResult await rdbStore.querySql(SELECT COUNT(*) as count FROM course WHERE status 1); inProgressResult.goToNextRow(); const inProgress inProgressResult.getInt(0); inProgressResult.close(); const endedResult await rdbStore.querySql(SELECT COUNT(*) as count FROM course WHERE status 2); endedResult.goToNextRow(); const ended endedResult.getInt(0); endedResult.close(); return { total, inProgress, ended }; } }三、网络请求与API对接3.1 HTTP请求封装// service/HttpHelper.ets import http from ohos.net.http; export class HttpHelper { private static baseUrl: string https://api.example.com; static async getT(path: string, params?: Recordstring, string): PromiseT { const url this.buildUrl(path, params); const httpRequest http.createHttp(); try { const response await httpRequest.request(url, { method: http.RequestMethod.GET, header: { Content-Type: application/json, Authorization: Bearer ${await this.getToken()} } }); if (response.responseCode 200) { return JSON.parse(response.result as string) as T; } else { throw new Error(HTTP Error: ${response.responseCode}); } } finally { httpRequest.destroy(); } } static async postT(path: string, data: Recordstring, any): PromiseT { const url this.buildUrl(path); const httpRequest http.createHttp(); try { const response await httpRequest.request(url, { method: http.RequestMethod.POST, header: { Content-Type: application/json, Authorization: Bearer ${await this.getToken()} }, extraData: JSON.stringify(data) }); if (response.responseCode 200) { return JSON.parse(response.result as string) as T; } else { throw new Error(HTTP Error: ${response.responseCode}); } } finally { httpRequest.destroy(); } } static async putT(path: string, data: Recordstring, any): PromiseT { const url this.buildUrl(path); const httpRequest http.createHttp(); try { const response await httpRequest.request(url, { method: http.RequestMethod.PUT, header: { Content-Type: application/json, Authorization: Bearer ${await this.getToken()} }, extraData: JSON.stringify(data) }); if (response.responseCode 200) { return JSON.parse(response.result as string) as T; } else { throw new Error(HTTP Error: ${response.responseCode}); } } finally { httpRequest.destroy(); } } static async deleteT(path: string): PromiseT { const url this.buildUrl(path); const httpRequest http.createHttp(); try { const response await httpRequest.request(url, { method: http.RequestMethod.DELETE, header: { Content-Type: application/json, Authorization: Bearer ${await this.getToken()} } }); if (response.responseCode 200) { return JSON.parse(response.result as string) as T; } else { throw new Error(HTTP Error: ${response.responseCode}); } } finally { httpRequest.destroy(); } } private static buildUrl(path: string, params?: Recordstring, string): string { let url ${this.baseUrl}${path}; if (params) { const queryString Object.entries(params) .map(([key, value]) ${encodeURIComponent(key)}${encodeURIComponent(value)}) .join(); url ?${queryString}; } return url; } private static async getToken(): Promisestring { // 从本地存储获取token return await UserPreferences.getToken(); } }3.2 API服务封装// service/ApiService.ets import { HttpHelper } from ./HttpHelper; export interface ApiResponseT { code: number; message: string; data: T; } export class ApiService { // 获取课程列表 static async getCourses(): PromiseCourse[] { const response await HttpHelper.getApiResponseCourse[](/courses); return response.data; } // 获取课程详情 static async getCourseDetail(courseId: string): PromiseCourse { const response await HttpHelper.getApiResponseCourse(/courses/${courseId}); return response.data; } // 创建课程 static async createCourse(course: Course): PromiseCourse { const response await HttpHelper.postApiResponseCourse(/courses, course); return response.data; } // 更新课程 static async updateCourse(courseId: string, course: Course): PromiseCourse { const response await HttpHelper.putApiResponseCourse(/courses/${courseId}, course); return response.data; } // 删除课程 static async deleteCourse(courseId: string): Promisevoid { await HttpHelper.deleteApiResponsevoid(/courses/${courseId}); } // 获取学员列表 static async getStudents(): PromiseStudent[] { const response await HttpHelper.getApiResponseStudent[](/students); return response.data; } // 创建报名 static async createEnrollment(enrollment: Enrollment): PromiseEnrollment { const response await HttpHelper.postApiResponseEnrollment(/enrollments, enrollment); return response.data; } }四、数据缓存策略4.1 缓存管理器// service/CacheManager.ets export class CacheManager { private static cache: Mapstring, { data: any; timestamp: number } new Map(); private static CACHE_DURATION 5 * 60 * 1000; // 5分钟缓存 static set(key: string, data: any): void { this.cache.set(key, { data: data, timestamp: Date.now() }); } static getT(key: string): T | null { const cached this.cache.get(key); if (!cached) return null; const isExpired Date.now() - cached.timestamp this.CACHE_DURATION; if (isExpired) { this.cache.delete(key); return null; } return cached.data as T; } static has(key: string): boolean { const cached this.cache.get(key); if (!cached) return false; const isExpired Date.now() - cached.timestamp this.CACHE_DURATION; if (isExpired) { this.cache.delete(key); return false; } return true; } static delete(key: string): void { this.cache.delete(key); } static clear(): void { this.cache.clear(); } }4.2 带缓存的数据服务// service/CachedCourseService.ets import { CacheManager } from ./CacheManager; export class CachedCourseService { private static CACHE_KEY_ALL_COURSES all_courses; private static courseService: CourseService new CourseService(); static async getAllCourses(): PromiseCourse[] { // 先从缓存获取 const cached CacheManager.getCourse[](this.CACHE_KEY_ALL_COURSES); if (cached) { return cached; } // 缓存未命中从数据库获取 const courses await this.courseService.getAllCourses(); // 存入缓存 CacheManager.set(this.CACHE_KEY_ALL_COURSES, courses); return courses; } static async getCourseById(courseId: string): PromiseCourse | null { const cacheKey course_${courseId}; // 先从缓存获取 const cached CacheManager.getCourse(cacheKey); if (cached) { return cached; } // 缓存未命中从数据库获取 const course await this.courseService.getCourseById(courseId); if (course) { CacheManager.set(cacheKey, course); } return course; } static async insertCourse(course: Course): Promisevoid { await this.courseService.insertCourse(course); // 清除相关缓存 CacheManager.delete(this.CACHE_KEY_ALL_COURSES); } static async updateCourse(course: Course): Promisevoid { await this.courseService.updateCourse(course); // 清除相关缓存 CacheManager.delete(this.CACHE_KEY_ALL_COURSES); CacheManager.delete(course_${course.id}); } static async deleteCourse(courseId: string): Promisevoid { await this.courseService.deleteCourse(courseId); // 清除相关缓存 CacheManager.delete(this.CACHE_KEY_ALL_COURSES); CacheManager.delete(course_${courseId}); } }五、离线功能实现5.1 离线数据同步// service/OfflineSyncService.ets export class OfflineSyncService { private static pendingOperations: Array{ type: create | update | delete; table: string; data: any; timestamp: number; } []; // 添加待同步操作 static addPendingOperation( type: create | update | delete, table: string, data: any ): void { this.pendingOperations.push({ type, table, data, timestamp: Date.now() }); // 保存到本地存储 this.savePendingOperations(); } // 同步待处理操作 static async syncPendingOperations(): Promisevoid { const operations [...this.pendingOperations]; for (const operation of operations) { try { await this.executeOperation(operation); // 成功后移除 this.pendingOperations this.pendingOperations.filter( op op.timestamp ! operation.timestamp ); } catch (error) { console.error(同步操作失败:, error); break; } } // 保存更新后的待处理操作 this.savePendingOperations(); } private static async executeOperation(operation: any): Promisevoid { switch (operation.type) { case create: await this.executeCreate(operation.table, operation.data); break; case update: await this.executeUpdate(operation.table, operation.data); break; case delete: await this.executeDelete(operation.table, operation.data); break; } } private static async executeCreate(table: string, data: any): Promisevoid { switch (table) { case courses: await ApiService.createCourse(data); break; case students: await ApiService.createStudent(data); break; case enrollments: await ApiService.createEnrollment(data); break; } } private static async executeUpdate(table: string, data: any): Promisevoid { switch (table) { case courses: await ApiService.updateCourse(data.id, data); break; case students: await ApiService.updateStudent(data.id, data); break; } } private static async executeDelete(table: string, data: any): Promisevoid { switch (table) { case courses: await ApiService.deleteCourse(data.id); break; case students: await ApiService.deleteStudent(data.id); break; } } private static savePendingOperations(): void { // 保存到Preferences const operationsJson JSON.stringify(this.pendingOperations); // 实际实现中需要调用Preferences保存 } static loadPendingOperations(): void { // 从Preferences加载 // 实际实现中需要调用Preferences读取 this.pendingOperations []; } static getPendingOperationsCount(): number { return this.pendingOperations.length; } }5.2 网络状态监听// service/NetworkMonitor.ets import { connection } from kit.NetworkKit; export class NetworkMonitor { private static isOnline: boolean true; private static listeners: Array(isOnline: boolean) void []; static async init(): Promisevoid { // 获取初始网络状态 try { const netConn connection.createNetConnection(); const netCapabilities await netConn.getNetCapabilities(); this.isOnline netCapabilities.linkUp netCapabilities.linkAddresses.length 0; } catch (error) { console.error(获取网络状态失败:, error); } // 监听网络变化 connection.on(netAvailable, () { this.isOnline true; this.notifyListeners(); }); connection.on(netUnavailable, () { this.isOnline false; this.notifyListeners(); }); } static getIsOnline(): boolean { return this.isOnline; } static addListener(listener: (isOnline: boolean) void): void { this.listeners.push(listener); } static removeListener(listener: (isOnline: boolean) void): void { this.listeners this.listeners.filter(l l ! listener); } private static notifyListeners(): void { this.listeners.forEach(listener { listener(this.isOnline); }); } }六、踩坑记录6.1 Preferences数据丢失问题应用更新后Preferences数据丢失。原因应用签名变更导致Preferences文件被清除。解决方案// 使用RDB存储重要数据Preferences仅存储临时配置 // 或者在应用更新时迁移数据6.2 RDB并发访问问题问题多线程同时访问RDB导致异常。原因RDB不支持并发写入。解决方案// 使用队列串行化数据库操作 private operationQueue: Array() Promisevoid []; private isProcessing: boolean false; async enqueueOperation(operation: () Promisevoid): Promisevoid { this.operationQueue.push(operation); if (!this.isProcessing) { await this.processQueue(); } } private async processQueue(): Promisevoid { this.isProcessing true; while (this.operationQueue.length 0) { const operation this.operationQueue.shift(); if (operation) { await operation(); } } this.isProcessing false; }6.3 HTTP请求超时问题网络不稳定时请求超时。原因未设置合理的超时时间。解决方案// 设置请求超时 const response await httpRequest.request(url, { method: http.RequestMethod.GET, connectTimeout: 10000, // 10秒连接超时 readTimeout: 30000, // 30秒读取超时 header: { Content-Type: application/json } });七、总结与预告本文要点回顾Preferences轻量级键值对存储适用于配置数据RDB关系型数据库适用于结构化数据HTTP请求网络API封装支持RESTful接口数据缓存内存缓存策略提升访问性能离线功能离线数据同步保证数据一致性下期预告下期我们将深入讲解性能优化篇包括学员列表性能优化图片加载与缓存优化启动速度优化内存管理与泄漏检测互动引导如果本文对你有帮助请点赞、收藏、关注有任何问题欢迎在评论区留言我会及时回复。系列文章导航第1篇项目架构篇第2篇UI界面篇第3篇状态管理篇第4篇数据持久化篇本文第5篇性能优化篇

相关文章:

【2026最新】鸿蒙NEXT数据持久化实战:培训班管理系统数据存储全攻略

鸿蒙开发中数据总是丢失?本地存储和网络请求搞不定?本文用15分钟带你彻底搞懂Preferences、RDB、HTTP三大数据持久化方案,附完整培训班管理系统实战代码和踩坑记录,让你的鸿蒙App数据存储从此安全可靠!一、学员信息本地…...

降AI率软件越便宜越好吗?实测5个主流降AI工具,首选嘎嘎降!

一、前言:2026 年毕业必须通过 aigc 检测 2026 年各高校对学术论文的 AIGC 疑似度的审查全面变严, 均发布了具体 AIGC 检测报告和数值要求,211 和 985 高校规定本科论文 AI 率要低于 20%, 硕士要求 AI 率不高于 15%。普通高校一般要求 AI 率控制在 30% 以内。AIGC 检测率超标的…...

基于Feather RP2040与CircuitPython的CNC旋钮宏键盘DIY指南

1. 项目概述:打造你的专属生产力旋钮如果你经常使用像Cura、Fusion 360或者Adobe系列这类专业软件,一定对频繁切换工具、调整参数时在键盘和鼠标间来回切换的繁琐深有体会。传统的键盘快捷键虽然快,但组合键太多容易忘记,而且缺乏…...

从技巧到工程:构建可维护的Prompt设计体系与实战指南

1. 项目概述:Prompt Engineering 的实战价值最近在 GitHub 上看到一个名为 “imJunaidAfzal/Prompt-Engineering” 的项目,这让我想起了过去一年里,和团队一起从零开始摸索大语言模型应用落地的经历。Prompt Engineering,中文常译…...

ECHO:不止是播放器——一款完整的桌面音乐产品

下载地址:canghaiapp.com 软件介绍:不止是播放器 ECHO 将自己定位为一款“完整的桌面音乐产品”。从技术架构上看,它确实与此相符: 核心技术选型:项目基于 Electron React 技术栈构建。Electron 赋予了它调用原生系…...

BeagleBone Black设备树覆盖层实战:从原理到自定义SPI/UART配置

1. 项目概述:为什么BeagleBone Black开发者必须掌握设备树?如果你正在使用BeagleBone Black(BBB)进行嵌入式开发,并且已经不止一次地困惑于为什么某个外设(比如UART、SPI或者某个GPIO)无法按预期…...

FanControl终极指南:如何突破NVIDIA显卡风扇30%限制实现0 RPM静音控制

FanControl终极指南:如何突破NVIDIA显卡风扇30%限制实现0 RPM静音控制 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/Git…...

企业级应用如何通过 Taotoken 统一管理多个团队的模型调用

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 企业级应用如何通过 Taotoken 统一管理多个团队的模型调用 在中大型企业的技术实践中,多个项目组或产品线同时接入和使…...

赛车电气系统设计的现代化转型与实践

1. 赛车电气系统设计的现状与挑战当人们谈论赛车技术时,脑海中浮现的往往是碳纤维车身、空气动力学套件或是大马力发动机。但在这光鲜亮丽的表象背后,电气系统才是现代赛车的"神经系统"。有趣的是,这个关键领域的设计方法却呈现出两…...

Topit:macOS窗口置顶的终极解决方案,开源高效的多任务开发利器

Topit:macOS窗口置顶的终极解决方案,开源高效的多任务开发利器 【免费下载链接】Topit Pin any window to the top of your screen / 在Mac上将你的任何窗口强制置顶 项目地址: https://gitcode.com/gh_mirrors/to/Topit Topit是一款专为macOS系统…...

复杂系统交付中的风险治理与经济模型转型

1. 复杂系统交付中的风险本质与治理转型在航空航天、国防军工等复杂系统开发领域,项目失败率长期居高不下。根据IBM对全球500个大型系统的调研,73%的项目存在严重进度延迟,平均超支达到原始预算的189%。这种系统性失效的根源在于传统工程治理…...

Linux驱动开发:原子操作实现LED设备互斥访问

1. 项目概述:用原子操作给LED驱动加把“锁”在嵌入式Linux开发里,驱动开发是绕不开的一环。很多时候,一个硬件设备,比如一个简单的LED灯,可能会被多个用户空间的应用程序同时访问。想象一下,一个APP想开灯&…...

3分钟掌握FanControl:Windows风扇控制终极指南

3分钟掌握FanControl:Windows风扇控制终极指南 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa/FanCon…...

Linux系统下Vue开发环境搭建:从Node.js到Vite的完整指南

1. 项目概述:为什么要在Linux上搭建Vue环境?对于前端开发者而言,Vue.js 早已不是陌生的名字。它凭借其渐进式的设计理念、灵活的组件化系统和相对平缓的学习曲线,成为了构建现代Web应用的主流框架之一。然而,很多开发者…...

ctfileGet:城通网盘直连地址解析工具的技术原理与实用指南

ctfileGet:城通网盘直连地址解析工具的技术原理与实用指南 【免费下载链接】ctfileGet 获取城通网盘一次性直连地址 项目地址: https://gitcode.com/gh_mirrors/ct/ctfileGet ctfileGet是一个基于Web的开源工具,专门用于解析城通网盘分享链接并获…...

基于RK3568核心板的智能家居控制器:从硬件选型到软件架构实战

1. 项目概述:当智能家居控制器遇上国产高性能核心板最近在做一个智能家居中控的案子,客户对性能、成本和本地化能力要求都比较高。选型阶段,我们团队把市面上主流的几款ARM核心板都摸了一遍,从传统的树莓派CM4到全志、瑞芯微的方案…...

AI智能体工具搜索系统:从MCP协议到语义检索的工程实践

1. 项目概述:从“工具搜索”到“智能体工具箱”的进化 最近在折腾AI智能体(Agent)开发的朋友,估计都绕不开一个核心问题:如何让智能体高效、准确地调用外部工具?无论是让它帮你查天气、发邮件,还…...

基于LLM与RAG构建智能问答系统:架构、实现与优化指南

1. 项目概述:当RAG遇上LLM,构建你的智能知识问答引擎最近在GitHub上看到一个挺有意思的项目,叫“Jenqyang/LLM-Powered-RAG-System”。光看名字,圈内人大概就能猜到个七七八八:这是一个基于大语言模型(LLM&…...

免费开源字体编辑器终极指南:5个核心模块带你从零到专业设计

免费开源字体编辑器终极指南:5个核心模块带你从零到专业设计 【免费下载链接】fontforge Free (libre) font editor for Windows, Mac OS X and GNULinux 项目地址: https://gitcode.com/gh_mirrors/fo/fontforge 想要免费编辑字体却找不到合适的工具&#x…...

Node.js性能预测工具nodestradamus:从监控到预警的实践指南

1. 项目概述与核心价值最近在折腾一些服务器监控和性能预测的活儿,偶然间在GitHub上发现了一个叫nodestradamus的项目,作者是ChristosGrigoras。这个名字挺有意思,结合了“Node.js”和“诺查丹玛斯”(那位著名的预言家&#xff09…...

芯片/半导体/CPO光模块 深度分析报告

芯片/半导体/CPO光模块 深度分析报告报告生成时间:2026年5月16日 分析标的:芯片半导体板块 CPO光模块产业链 龙头标的:中际旭创(300308)、天孚通信(300394)、新易盛(300502)、寒武纪(688256)、海光信息(688041) 数据来源:公开市场…...

神经网络建筑负荷预测与供暖优化【附程序】

✨ 长期致力于BP神经网络、负荷预测、空气源热泵、优化控制研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,点击《获取方式》 (1)基于BP神经网络的公共建筑热负荷预测模型&…...

雷达目标检测与成像算法实时实现【附代码】

✨ 长期致力于阵列雷达、多输入多输出、现场可编程门阵列、目标检测定位、高分辨成像研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,点击《获取方式》 (1)相控阵和差波束目…...

CFETR重载机械臂精确运动控制验证【附仿真】

✨ 长期致力于中国聚变工程实验堆、遥操作、多功能重载机械臂、路径规划、精确控制、数据融合控制研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,点击《获取方式》 (1)刚柔…...

学生综合素质评价系统设计实现【附程序】

✨ 长期致力于综合素质评价、AHP层次分析、BP神经网络、遗传算法研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,点击《获取方式》 (1)三层指标体系构建与AHP动态权重分配&…...

VIBESRAILS:基于Rails的音视频智能分析后端框架实践指南

1. 项目概述与核心价值最近在折腾一个挺有意思的开源项目,叫 VIBESRAILS,来自 GitHub 上的 VictoHughes 仓库。乍一看这个名字,可能有点摸不着头脑,但如果你对音视频处理、实时通信或者多媒体分析有点兴趣,那这个项目绝…...

VTube Studio完整指南:从零开始打造你的虚拟主播形象

VTube Studio完整指南:从零开始打造你的虚拟主播形象 【免费下载链接】VTubeStudio VTube Studio API Development Page 项目地址: https://gitcode.com/gh_mirrors/vt/VTubeStudio 想要成为一名虚拟主播,却担心技术门槛太高?VTube St…...

如何用FanControl快速解决电脑风扇噪音问题:完整免费指南

如何用FanControl快速解决电脑风扇噪音问题:完整免费指南 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending…...

解密Jsxer:如何高效反编译Adobe JSXBIN二进制脚本

解密Jsxer:如何高效反编译Adobe JSXBIN二进制脚本 【免费下载链接】jsxer A fast and accurate JSXBIN decompiler. 项目地址: https://gitcode.com/gh_mirrors/js/jsxer Jsxer是一个快速准确的JSXBIN反编译器,专门用于将Adobe ExtendScript的二进…...

HS2-HF Patch:3步安装HoneySelect2终极增强补丁完整指南

HS2-HF Patch:3步安装HoneySelect2终极增强补丁完整指南 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch HS2-HF Patch是HoneySelect2玩家的游戏增强…...