【Tauri2】035——sql和sqlx

前言

这篇就来看看插件sql

SQL | Taurihttps://tauri.app/plugin/sql/

正文

准备

添加依赖

tauri-plugin-sql = {version = "2.2.0",features = ["sqlite"]}

features可以是mysql、sqlite、postsql

进去features看看

sqlite = ["sqlx/sqlite","sqlx/runtime-tokio",
]

可以发现本质使用的是sqlx

sqlx - Rusthttps://docs.rs/sqlx/latest/sqlx/注册插件

        .plugin(tauri_plugin_sql::Builder::default().build())

并不像其他插件一样,有init方法,因为需要一些配置,比如连接数据库。

配置

要想配置数据库,如果数据库里面有东西,比如表,需要用到如下函数add_migrations

    pub fn add_migrations(mut self,db_url: &str, migrations: Vec<Migration>) -> Self 

需要传入db_urlmigrations

比如db_url可以设置sqlite:start.db

migrations是个Vec,元素类型是Migration

Migration的定义如下

#[derive(Debug)]
pub struct Migration {pub version: i64,pub description: &'static str,pub sql: &'static str,pub kind: MigrationKind,
}

 MigrationKind是指定迁移的类型

#[derive(Debug)]
pub enum MigrationKind {Up,Down,
}

项目结构如下 

在migration.rs中

use tauri_plugin_sql::{Migration,MigrationKind};
pub fn get_migration()->Vec<Migration>{vec![// Define your migrations hereMigration {version: 1,description: "Create book table",sql: r"CREATE TABLE book (id INTEGER PRIMARY KEY,author TEXT,title TEXT,published_date date);",kind: MigrationKind::Up,}] 
}

 创建了一张表

注册

       .plugin(tauri_plugin_sql::Builder::default().add_migrations("sqlite:start.db",get_migration()).build())

 想要在后端使用

怎么在后端使用,这确实是个问题,笔者发现好像没有在后端使用的东西,全都是前端调用

比如说

    pub(crate) async fn connect<R: Runtime>(conn_url: &str,_app: &AppHandle<R>,) -> Result<Self, crate::Error> 

按道理来说,connect应该可以使用,但是这是私有的,只在crate内部公开,

笔者也没找到怎么使用,

看看内部的通信函数

#[command]
pub(crate) async fn load<R: Runtime>(app: AppHandle<R>,db_instances: State<'_, DbInstances>,migrations: State<'_, Migrations>,db: String,
) -> Result<String, crate::Error> {let pool = DbPool::connect(&db, &app).await?;if let Some(migrations) = migrations.0.lock().await.remove(&db) {let migrator = Migrator::new(migrations).await?;pool.migrate(&migrator).await?;}db_instances.0.write().await.insert(db.clone(), pool);Ok(db)
}
impl DbPool {pub(crate) async fn connectpub(crate) async fn migratepub(crate) async fn close(&self) pub(crate) async fn execute}

可以看出使用了DbInstances和Migrations,两个State

要先连接 DbPool::connect,但是这个connect没公开,其他方法也没有公开

看来这个插件就是写在前端的。后端无法使用。

要么使用sqlx,要么修改源码。额,都很麻烦。

笔者不在后端使用这个插件。直接使用sqlx

sqlx

暂时丢掉插件,简单使用一下这个crate

创建一个数据库和book表


添加依赖

sqlx = { version = "0.8.5", features = ["sqlite", "runtime-tokio"] }

 

在connect.rs中,定义DbInstances ,然后将其注册成State

use sqlx::sqlite::SqlitePoolOptions;
use sqlx::Sqlite;
use sqlx::Pool;
use tauri::{command, AppHandle, State};
async fn connect()-> Pool<Sqlite> {SqlitePoolOptions::new().connect("sqlite:start.db").await.unwrap()}
pub struct DbInstances {pub db: Pool<Sqlite>
}
impl DbInstances {pub async fn new() -> Self {Self {db: connect().await}}
}

通信函数 

use sqlx::Executor;
use crate::sql::connect::DbInstances;
use tauri::{command, AppHandle, State};
use tauri::Result;#[command]
pub async fn insert_one(state: State<'_, DbInstances>)->Result<()> {let db=state.db.clone();db.execute(r"INSERT INTO book (id, author, title, published_date) VALUES (2, 'gg', 'good', '2024-04-20');").await.unwrap();Ok(())}

注册State通信函数之后。

执行后

成功。简单地使用了一下sqlx

前端使用插件sql

既然这个插件是为前端服务的,就在前端简单使用一下。

添加依赖

pnpm add @tauri-apps/plugin-sql

后端注册完成后,简单的代码如下 

import Database,{QueryResult}  from '@tauri-apps/plugin-sql';
export async function useSql(){const db = await Database.load('sqlite:start.db');let a=await db.execute("INSERT INTO book (id, author, title, published_date) VALUES (22, 'gg', 'good', '2024-04-20');");console.log(a)let b=await db.select("select * from book")console.log(b)db.close()
}

所有的通信函数都在这里。 

使用load方法和execuct方法,需要配置权限

    "sql:default","sql:allow-execute"

 通信函数load

#[command]
pub(crate) async fn load<R: Runtime>(app: AppHandle<R>,db_instances: State<'_, DbInstances>,migrations: State<'_, Migrations>,db: String,
) -> Result<String, crate::Error> {let pool = DbPool::connect(&db, &app).await?;if let Some(migrations) = migrations.0.lock().await.remove(&db) {let migrator = Migrator::new(migrations).await?;pool.migrate(&migrator).await?;}db_instances.0.write().await.insert(db.clone(), pool);Ok(db)
}

先连接,看看DbPool::connect方法

 match conn_url.split_once(':').ok_or_else(|| crate::Error::InvalidDbUrl(conn_url.to_string()))?.0{#[cfg(feature = "sqlite")]"sqlite" => {let app_path = _app.path().app_config_dir().expect("No App config path was found!");create_dir_all(&app_path).expect("Couldn't create app config dir");let conn_url = &path_mapper(app_path, conn_url);if !Sqlite::database_exists(conn_url).await.unwrap_or(false) {Sqlite::create_database(conn_url).await?;}Ok(Self::Sqlite(Pool::connect(conn_url).await?))}
fn path_mapper(mut app_path: std::path::PathBuf, connection_string: &str) -> String {app_path.push(connection_string.split_once(':').expect("Couldn't parse the connection string for DB!").1,);

对于sqlite:start.db可以发现位置其实是在app_config_dir+start.db

笔者是Window系统,位置如下

写相当路径会相对 app_config_dir。

可以写绝对路径,比如

const db = await Database.load('sqlite:D:/start/start.db');

当然,需要有表,结果如下

从官网的案例中可以发现

const result = await db.execute(
"UPDATE todos SET title = $1, status = $2 WHERE id = $3",
[todos.title, todos.status, todos.id],
);

 可以在sql语句中使用占位符。基本操作。

预加载

可以在配置文件中提前配置。不重要

  "plugins": {"sql": {"preload": ["sqlite:start.db"]}},

总结

这个插件实际上感觉就是对sqlx的封装。也不是很完全的封装,也没有对sql语句的封装。

等用于为前端提供了数据库连接和执行的接口。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/77698.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全链路自动化AIGC内容工厂:构建企业级智能内容生产系统

一、工业化AIGC系统架构 1.1 生产流程设计 [需求输入] → [创意生成] → [多模态生产] → [质量审核] → [多平台分发] ↑ ↓ ↑ [用户反馈] ← [效果分析] ← [数据埋点] ← [内容投放] 1.2 技术指标要求 指标 标准值 实现方案 单日产能 1,000,000 分布式推理集群 内容合规率…

是否想要一个桌面哆啦A梦的宠物

是否想拥有一个在指定时间喊你的桌面宠物呢&#xff08;手动狗头&#xff09; 如果你有更好的想法&#xff0c;欢迎提出你的想法。 是否考虑过跟开发者一对一&#xff0c;提出你的建议&#xff08;狗头&#xff09;。 https://wwxc.lanzouo.com/idKnJ2uvq11c 密码:bbkm

Unity AI-使用Ollama本地大语言模型运行框架运行本地Deepseek等模型实现聊天对话(二)

一、使用介绍 官方网页&#xff1a;Ollama官方网址 中文文档参考&#xff1a;Ollama中文文档 相关教程&#xff1a;Ollama教程 使用版本&#xff1a;Unity 2022.3.53f1c1、Ollama 0.6.2 示例模型&#xff1a;llama3.2 二、运行示例 三、使用步骤 1、创建Canvas面板 具体…

从 BERT 到 GPT:Encoder 的 “全局视野” 如何喂饱 Decoder 的 “逐词纠结”

当 Encoder 学会 “左顾右盼”&#xff1a;Decoder 如何凭 “单向记忆” 生成丝滑文本&#xff1f; 目录 当 Encoder 学会 “左顾右盼”&#xff1a;Decoder 如何凭 “单向记忆” 生成丝滑文本&#xff1f;引言一、Encoder vs Decoder&#xff1a;核心功能与基础架构对比1.1 本…

数据结构入门:详解顺序表的实现与操作

目录 1.线性表 2.顺序表 2.1概念与结构 2.2分类 2.2.1静态顺序表 2.2.2动态顺序表 3.动态顺序表的实现 3.1.SeqList.h 3.2.SeqList.c 3.2.1初始化 3.2.2销毁 3.2.3打印 3.2.4顺序表扩容 3.2.5尾部插入及尾部删除 3.2.6头部插入及头部删除 3.2.7特定位置插入…

LeetCode热题100--53.最大子数组和--中等

1. 题目 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组是数组中的一个连续部分。 示例 1&#xff1a; 输入&#xff1a;nums [-2,1,-3,4,-1,2,1,-5,4] 输出&…

python:练习:2

1.题目&#xff1a;统计一篇英文文章中每个单词出现的次数&#xff0c;并按照出现次数排序输出。 示例输入&#xff1a; text "Python is an interpreted, high-level, general-purpose programming language. Created by Guido van Rossum and first released in 1991…

AI Agent 孵化器?开源框架CAMEL

简介 CAMEL&#xff08;Communicative Agents for Mind Exploration of Large Scale Language Model Society&#xff09;是一个开源框架&#xff0c;大语言模型多智能体框架的先驱者。旨在通过角色扮演和自主协作&#xff0c;探索大语言模型&#xff08;LLM&#xff09;在多智…

关于插值和拟合(数学建模实验课)

文章目录 1.总体评价2.具体的课堂题目 1.总体评价 学校可以开设这个数学建模实验课程&#xff0c;我本来是非常的激动地&#xff0c;但是这个最后的上课方式却让我高兴不起哦来&#xff0c;因为老师讲的这个内容非常的简单&#xff0c;而且一个上午的数学实验&#xff0c;基本…

LayerSkip: Enabling Early Exit Inference and Self-Speculative Decoding

TL;DR 2024 年 Meta FAIR 提出了 LayerSkip&#xff0c;这是一种端到端的解决方案&#xff0c;用于加速大语言模型&#xff08;LLMs&#xff09;的推理过程 Paper name LayerSkip: Enabling Early Exit Inference and Self-Speculative Decoding Paper Reading Note Paper…

解决ktransformers v0.3 docker镜像中 operator torchvision::nms does not exist 问题

问题背景 更新ktransformers docker镜像到v0.3版本后&#xff08;之前为v0.2.4post1&#xff09;&#xff0c;使用更新前启动命令无法正确启动服务&#xff0c;提示以下错误&#xff1a; Traceback (most recent call last):File "/workspace/ktransformers/ktransforme…

如何系统学习音视频

学习音视频技术涉及多个领域&#xff0c;包括音频处理、视频处理、编码解码、流媒体传输等。 第一阶段&#xff1a;基础知识准备 目标&#xff1a;掌握音视频学习所需的计算机科学和数学基础。 计算机基础 学习计算机网络基础&#xff08;TCP/IP、UDP、HTTP、RTSP等协议&#…

TiDB 可观测性最佳实践

TiDB 介绍 TiDB&#xff0c;由 PingCAP 公司自主研发的开源分布式关系型数据库&#xff0c;是一款创新的 HTAP 数据库产品&#xff0c;它融合了在线事务处理&#xff08;OLTP&#xff09;和在线分析处理&#xff08;OLAP&#xff09;的能力&#xff0c;支持水平扩容和缩容&…

使用FreeRTOS解决单片机串口异步打印

单片机串口异步打印 文章目录 单片机串口异步打印前言设计思路准备队列创建完整代码 总结 前言 &#x1f30a;在单片机开发中串口的异步打印异步打印允许单片机在执行其他任务的同时进行打印操作&#xff0c;无需等待打印完成后再继续执行后续代码&#xff0c;避免了在多处调用…

代码颜色模式python

1. CMYK&#xff08;印刷场景&#xff09; 例子&#xff1a;某出版社设计书籍封面时&#xff0c;使用 Adobe Illustrator 绘制图案。 红色封面的 CMYK 值可能为&#xff1a;C0, M100, Y100, K0&#xff08;通过洋红和黄色油墨混合呈现红色&#xff09;。印刷前需将设计文件转…

HarmonyOS NEXT 诗词元服务项目开发上架全流程实战(二、元服务与应用APP签名打包步骤详解)

在HarmonyOS应用开发过程中&#xff0c;发布应用到应用市场是一个重要的环节。没经历过的童鞋&#xff0c;首次对HarmonyOS的应用签名打包上架可能感觉繁琐。需要各种秘钥证书生成和申请&#xff0c;混在一起分不清。其实搞清楚后也就那会事&#xff0c;各个文件都有它存在的作…

【BotSharp框架示例 ——实现聊天机器人,并通过 DeepSeek V3实现 function calling】

BotSharp框架示例 ——实现聊天机器人&#xff0c;并通过 DeepSeek V3实现 function calling 一、一点点感悟二、创建项目1、创建项目2、添加引用3、MyWeatherPlugin项目代码编写4、WeatherApiDefaultService项目代码编写5、WebAPI MyWeatherAPI 的项目代码编写6、data文件夹中…

百度CarLife实现手机车机无缝互联

百度CarLife是百度推出的智能车联网解决方案&#xff0c;通过手机与车机互联技术&#xff0c;为用户提供安全便捷的车载互联网服务体验。 CarLife 实现手机与车机屏幕的无缝互联&#xff0c;让应用内容同步至车载系统&#xff0c;减少驾驶过程中操作手机的频率&#xff0c;提升…

基于STM32的虚线绘制函数改造

改造前&#xff1a; uint16_t DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { // GUI_DrawLine( x1, y1, x2, y2); // return 1;int16_t deltaX, deltaY;int16_t error, stepErrorLT, stepErrorGE;int16_t stepX, stepY;int16_t steep;int16_t…

Java高频面试之并发编程-10

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天来报道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面试官&#xff1a;ThreadLocalMap 怎么解决 Hash 冲突的&#xff1f; ThreadLocalMap 是 ThreadLocal 的核心实现&#xff0c;它采用 开放…