Tauri 开发实践 — Tauri 集成本地数据库

简介: 本文介绍了在 Tauri 框架中集成本地数据库的几种方案,包括直接绑定 SQLite、使用第三方数据库库和使用 tauri-plugin-sql-api 插件。最终选择了 tauri-plugin-sql-api,因为它集成简单、支持多种数据库类型,并且与 Tauri 框架深度整合,提升了开发效率和安全性。文章详细介绍了如何安装和使用该插件,以及如何编写核心代码实现数据库操作。

本文首发微信公众号:前端徐徐。

前言

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

方案比较

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

  1. SQLite 通过直接绑定
  2. 使用第三方数据库库
  3. 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。

我们推荐以下三种通用的安装方法:

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

安装核心插件

在你的 Cargo.toml 文件中添加以下内容:

src-tauri/Cargo.toml

toml
复制代码
[dependencies.tauri-plugin-sql]
git = "https://github.com/tauri-apps/plugins-workspace"
branch = "v1"
features = ["sqlite"] # 或者 "postgres", 或 "mysql"

安装 JavaScript 依赖

你可以使用你喜欢的 JavaScript 包管理器来安装:

注意:由于大多数 JavaScript 包管理器无法从 git 单仓库安装包,我们提供了每个插件的只读镜像。这使得安装选项 2 更加方便使用。

pnpm add https://github.com/tauri-apps/tauri-plugin-sql#v1
# 或
npm add https://github.com/tauri-apps/tauri-plugin-sql#v1
# 或
yarn add https://github.com/tauri-apps/tauri-plugin-sql#v1

编写核心代码

DatabaseService

构建db核心类,初始化DB,这里只是做的key-value的表

import Database from "tauri-plugin-sql-api";
import {ENV_MODE} from "@/utils/const"
class DatabaseService {
  private db!: Database;
  private dbReady: Promise<void>;
  constructor() {
    this.dbReady = this.initDatabase();
  }
  private async initDatabase() {
    try {
      this.db = await Database.load(ENV_MODE !== 'development' ? "sqlite:xtools.db" : "sqlite:xtools_test.db");
      await this.db.execute(`
        CREATE TABLE IF NOT EXISTS key_value (
          key TEXT PRIMARY KEY,
          value TEXT
        )
      `);
    } catch (error) {
      console.error("Error initializing database:", error);
      throw error; 
    }
  }
  public async getDbInstance(): Promise<Database> {
    await this.dbReady;
    return this.db;
  }
}
export default new DatabaseService();

KeyValueStore

keyValue的增删改查,方便外部使用

import DatabaseService from './dbService';
class KeyValueStore {
  private dbPromise = DatabaseService.getDbInstance();
  
  public async set(key: string, value: string): Promise<void> {
    const db = await this.dbPromise;
    try {
      await db.execute('REPLACE INTO key_value (key, value) VALUES (?, ?)', [key, value]);
    } catch (error) {
      console.error(`Error setting value for key "${key}":`, error);
      throw error; 
    }
  }
  public async get(key: string): Promise<string | null> {
    const db = await this.dbPromise;
    try {
      const result = await db.select<{ value: string }[]>('SELECT value FROM key_value WHERE key = ?', [key]);
      return result.length > 0 ? result[0].value : null;
    } catch (error) {
      console.error(`Error getting value for key "${key}":`, error);
      throw error;
    }
  }
  public async delete(key: string): Promise<void> {
    const db = await this.dbPromise;
    try {
      await db.execute('DELETE FROM key_value WHERE key = ?', [key]);
    } catch (error) {
      console.error(`Error deleting key "${key}":`, error);
      throw error;
    }
  }
  public async getAll(): Promise<{ key: string; value: string }[]> {
    const db = await this.dbPromise;
    try {
      const result = await db.select<{ key: string; value: string }[]>('SELECT key, value FROM key_value');
      return result;
    } catch (error) {
      console.error("Error getting all key-value pairs:", error);
      throw error;
    }
  }
}
export default KeyValueStore;

外部使用

这里判断了一下环境,如何是TAURI环境我们就用本地数据库,否则就用localStorage,兼容浏览器环境。

import { KeyValueStore } from '@/db';
import {IS_TAURI} from '@/utils/const'
export const getStore = async (key:string) => {
    if (IS_TAURI) {
        const store = new KeyValueStore();
        const val =   await store.get(key);
        return val
    } else {
        return localStorage.getItem(key)
    }
}
export const setStore = async (key:string,value:string) => {
    if (IS_TAURI) {
        const store = new KeyValueStore();
        await store.set(key,value);
    } else {
        localStorage.setItem(key,value)
    }
}

总结

通过以上步骤,我们在 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

相关文章
|
1天前
|
SQL 关系型数据库 MySQL
Go语言项目高效对接SQL数据库:实践技巧与方法
在Go语言项目中,与SQL数据库进行对接是一项基础且重要的任务
17 10
|
5天前
|
SQL 关系型数据库 数据库
SQL数据库:核心原理与应用实践
随着信息技术的飞速发展,数据库管理系统已成为各类组织和企业中不可或缺的核心组件。在众多数据库管理系统中,SQL(结构化查询语言)数据库以其强大的数据管理能力和灵活性,广泛应用于各类业务场景。本文将深入探讨SQL数据库的基本原理、核心特性以及实际应用。一、SQL数据库概述SQL数据库是一种关系型数据库
16 5
|
4天前
|
SQL 开发框架 .NET
ASP连接SQL数据库:从基础到实践
随着互联网技术的快速发展,数据库与应用程序之间的连接成为了软件开发中的一项关键技术。ASP(ActiveServerPages)是一种在服务器端执行的脚本环境,它能够生成动态的网页内容。而SQL数据库则是一种关系型数据库管理系统,广泛应用于各类网站和应用程序的数据存储和管理。本文将详细介绍如何使用A
19 3
|
7天前
|
关系型数据库 数据挖掘 数据库
解析数据库联结:应用与实践中的 INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN 与 CROSS JOIN
解析数据库联结:应用与实践中的 INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN 与 CROSS JOIN
16 1
|
8天前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
12 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
14小时前
|
SQL 存储 关系型数据库
添加数据到数据库的SQL语句详解与实践技巧
在数据库管理中,添加数据是一个基本操作,它涉及到向表中插入新的记录
|
29天前
|
消息中间件 缓存 监控
优化微服务架构中的数据库访问:策略与实践
随着微服务架构的普及,如何高效管理和优化数据库访问成为了关键挑战。本文探讨了在微服务环境中优化数据库访问的策略,包括数据库分片、缓存机制、异步处理等技术手段。通过深入分析实际案例和最佳实践,本文旨在为开发者提供实际可行的解决方案,以提升系统性能和可扩展性。
|
1月前
|
JavaScript 前端开发 数据库
数据库测试场景实践总结
本文介绍了数据库超时和应用锁表SSDB测试场景的验证方法,通过锁定数据表模拟写入失败情况,并利用SSDB进行重试。测试需开发人员配合验证功能。同时,提供了SSDB服务器登录、查询队列数量及重启服务等常用命令。适用于验证和解决数据库写入问题。
24 7
|
1月前
|
存储 负载均衡 数据库
探索后端技术:从服务器架构到数据库优化的实践之旅
在当今数字化时代,后端技术作为支撑网站和应用运行的核心,扮演着至关重要的角色。本文将带领读者深入后端技术的两大关键领域——服务器架构和数据库优化,通过实践案例揭示其背后的原理与技巧。无论是对于初学者还是经验丰富的开发者,这篇文章都将提供宝贵的见解和实用的知识,帮助读者在后端开发的道路上更进一步。
|
2月前
|
Java Spring 开发者
Java Web开发新潮流:Vaadin与Spring Boot强强联手,打造高效便捷的应用体验!
【8月更文挑战第31天】《Vaadin与Spring Boot集成:最佳实践指南》介绍了如何结合Vaadin和Spring Boot的优势进行高效Java Web开发。文章首先概述了集成的基本步骤,包括引入依赖和配置自动功能,然后通过示例展示了如何创建和使用Vaadin组件。相较于传统框架,这种集成方式简化了配置、提升了开发效率并便于部署。尽管可能存在性能和学习曲线方面的挑战,但合理的框架组合能显著提升应用开发的质量和速度。
41 0