Tauri应用开发实践指南(5)—Tauri 集成本地数据库

打印 上一主题 下一主题

主题 846|帖子 846|积分 2538

本文首发于微信公众号:前端徐徐。欢迎关注,获取更多前端技能分享。

  前言

Tauri 是一个构建跨平台桌面应用程序的框架,利用 Web 技术构建前端,并利用 Rust 构建后端。它以其小巧的体积和高性能受到开发者的欢迎。在开发过程中,我们经常需要数据本地持久化, 所以会需要与本地数据库进行交互 。
方案比较

在 Tauri 中集成本地数据库有多种方案,常见的包罗:

  • SQLite 通过直接绑定
  • 利用第三方数据库库
  • Tauri 插件:tauri-plugin-sql-api
1. SQLite 通过直接绑定

优点:


  • 直接控制:可以完全掌控数据库的利用和配置。
  • 轻量级:SQLite 非常得当桌面应用,文件存储简单。
缺点:


  • 复杂性:需要手动处置惩罚全部数据库连接、查询和事务。
  • 安全性:需要自行管理数据库文件的访问权限。
2. 利用第三方数据库库

优点:


  • 功能丰富:第三方库通常提供丰富的功能和更好的文档支持。
  • 社区支持:许多库有活跃的社区,能够快速获取资助。
缺点:


  • 依靠管理:需要处置惩罚额外的依靠管理和库更新。
  • 体积增长:引入额外的库可能会增长应用的体积。
3. Tauri 插件:tauri-plugin-sql-api

优点:


  • 集成方便:专为 Tauri 设计的插件,易于集成。
  • 多数据库支持:支持 SQLite、MySQL 和 PostgreSQL。
  • 安全性:通过 Tauri 的安全模子,确保数据库利用的安全性。
缺点:


  • 功能限定:相比直接利用数据库库,插件可能有一些功能限定。
综合思量,我们选择 tauri-plugin-sql-api 作为集成本地数据库的方案。它的集成简单、支持多种数据库类型,而且与 Tauri 框架深度整合,能够有用地提升开发效率和安全性。
利用 tauri-plugin-sql-api 集成本地数据库

此插件要求 Rust 版本至少为 1.65。
我们保举以下三种通用的安装方法:

  • 利用 crates.io 和 npm(最简单,但需要信任我们的发布流程是否正常)
  • 从 GitHub 上直接拉取源代码,利用 git 标签/修订哈希(最安全)
  • 在你的 Tauri 项目中利用 git 子模块安装这个仓库,然后利用文件协议来引入源代码(最安全,但利用起来不方便)
安装核心插件

在你的 Cargo.toml 文件中添加以下内容:
src-tauri/Cargo.toml
  1. toml
  2. 复制代码
  3. [dependencies.tauri-plugin-sql]
  4. git = "https://github.com/tauri-apps/plugins-workspace"
  5. branch = "v1"
  6. features = ["sqlite"] # 或者 "postgres", 或 "mysql"
复制代码
安装 JavaScript 依靠

你可以利用你喜欢的 JavaScript 包管理器来安装:
注意:由于大多数 JavaScript 包管理器无法从 git 单仓库安装包,我们提供了每个插件的只读镜像。这使得安装选项 2 更加方便利用。
  1. pnpm add https://github.com/tauri-apps/tauri-plugin-sql#v1
  2. # 或
  3. npm add https://github.com/tauri-apps/tauri-plugin-sql#v1
  4. # 或
  5. yarn add https://github.com/tauri-apps/tauri-plugin-sql#v1
复制代码
编写核心代码

DatabaseService

构建db核心类,初始化DB,这里只是做的key-value的表
  1. import Database from "tauri-plugin-sql-api";
  2. import {ENV_MODE} from "@/utils/const"
  3. class DatabaseService {
  4.   private db!: Database;
  5.   private dbReady: Promise<void>;
  6.   constructor() {
  7.     this.dbReady = this.initDatabase();
  8.   }
  9.   private async initDatabase() {
  10.     try {
  11.       this.db = await Database.load(ENV_MODE !== 'development' ? "sqlite:xtools.db" : "sqlite:xtools_test.db");
  12.       await this.db.execute(`
  13.         CREATE TABLE IF NOT EXISTS key_value (
  14.           key TEXT PRIMARY KEY,
  15.           value TEXT
  16.         )
  17.       `);
  18.     } catch (error) {
  19.       console.error("Error initializing database:", error);
  20.       throw error;
  21.     }
  22.   }
  23.   public async getDbInstance(): Promise<Database> {
  24.     await this.dbReady;
  25.     return this.db;
  26.   }
  27. }
  28. export default new DatabaseService();
复制代码
KeyValueStore

keyValue的增编削查,方便外部利用
  1. import DatabaseService from './dbService';
  2. class KeyValueStore {
  3.   private dbPromise = DatabaseService.getDbInstance();
  4.   
  5.   public async set(key: string, value: string): Promise<void> {
  6.     const db = await this.dbPromise;
  7.     try {
  8.       await db.execute('REPLACE INTO key_value (key, value) VALUES (?, ?)', [key, value]);
  9.     } catch (error) {
  10.       console.error(`Error setting value for key "${key}":`, error);
  11.       throw error;
  12.     }
  13.   }
  14.   public async get(key: string): Promise<string | null> {
  15.     const db = await this.dbPromise;
  16.     try {
  17.       const result = await db.select<{ value: string }[]>('SELECT value FROM key_value WHERE key = ?', [key]);
  18.       return result.length > 0 ? result[0].value : null;
  19.     } catch (error) {
  20.       console.error(`Error getting value for key "${key}":`, error);
  21.       throw error;
  22.     }
  23.   }
  24.   public async delete(key: string): Promise<void> {
  25.     const db = await this.dbPromise;
  26.     try {
  27.       await db.execute('DELETE FROM key_value WHERE key = ?', [key]);
  28.     } catch (error) {
  29.       console.error(`Error deleting key "${key}":`, error);
  30.       throw error;
  31.     }
  32.   }
  33.   public async getAll(): Promise<{ key: string; value: string }[]> {
  34.     const db = await this.dbPromise;
  35.     try {
  36.       const result = await db.select<{ key: string; value: string }[]>('SELECT key, value FROM key_value');
  37.       return result;
  38.     } catch (error) {
  39.       console.error("Error getting all key-value pairs:", error);
  40.       throw error;
  41.     }
  42.   }
  43. }
  44. export default KeyValueStore;
复制代码
外部利用

这里判断了一下环境,如何是TAURI环境我们就用本地数据库,否则就用localStorage,兼容欣赏器环境。
  1. import { KeyValueStore } from '@/db';
  2. import {IS_TAURI} from '@/utils/const'
  3. export const getStore = async (key:string) => {
  4.     if (IS_TAURI) {
  5.         const store = new KeyValueStore();
  6.         const val =   await store.get(key);
  7.         return val
  8.     } else {
  9.         return localStorage.getItem(key)
  10.     }
  11. }
  12. export const setStore = async (key:string,value:string) => {
  13.     if (IS_TAURI) {
  14.         const store = new KeyValueStore();
  15.         await store.set(key,value);
  16.     } else {
  17.         localStorage.setItem(key,value)
  18.     }
  19. }
复制代码
总结

通过以上步骤,我们在 Tauri 应用中乐成集成了 tauri-plugin-sql-api 插件,实现了与本地 SQLite 数据库的交互。tauri-plugin-sql-api 插件不仅支持 SQLite,还支持其他类型的数据库,如 MySQL 和 PostgreSQL,开发者可以根据需求进行选择。通过 Tauri 的这种插件化设计,使得开发者能够轻松地将强大的 Rust 后端功能集成到当代前端框架中,从而构建高性能的跨平台桌面应用程序。
源码

https://github.com/Xutaotaotao/XTools/tree/feature-tauri-v1/src/db

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

傲渊山岳

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表