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

Flutter开发进阶之并发操作数据库

Flutter开发进阶之并发操作数据库

尽管 Flutter 本身不包含任何数据库功能,但可以使用各种第三方库和插件来在 Flutter 应用程序中实现数据库功能;
以下将使用sqflite作为例子,sqflite允许在 Flutter 应用程序中执行 SQL 查询,创建和管理数据库表,以及执行其他常见的数据库操作。
Flutter开发
在将sqflite添加到Flutter项目的依赖中后,就可以使用代码创建数据库和表了。

import 'package:sqflite/sqflite.dart';  Future<Database> getDatabase() async {  final dir = (await getDatabasesPath()).resolve('my_database.db');  return await openDatabase(dir.path, version: 1, onCreate: _onCreate);  
}  Future _onCreate(Database db, int version) async {  await db.execute('''  CREATE TABLE user (  id INTEGER PRIMARY KEY AUTOINCREMENT,  name TEXT,  age INTEGER  )  ''');  
}

然后我们可以做一些插入、查询、更新和删除数据库中数据的操作。

import 'package:sqflite/sqflite.dart';  Future<void> insertData() async {  final db = await getDatabase();  await db.execute(  'INSERT INTO user (name, age) VALUES (?, ?)',  ['John', 25],  );  
}  Future<List<Map<String, dynamic>>> queryData() async {  final db = await getDatabase();  return await db.query('user');  
}  Future<int> updateData() async {  final db = await getDatabase();  return await db.update(  'user',  {'age': 26},  where: 'name = ?',  whereArgs: ['John'],  );  
}  Future<int> deleteData() async {  final db = await getDatabase();  return await db.delete('user', where: 'name = ?', whereArgs: ['John']);  
}

在实际应用中并不会这么简单,特别是当我们有需求在多个位置去操作数据库的时候,这时候可能会有线程安全的问题;
比如说在一个作用域内,有多台设备需要在我所在的这台设备操作数据库;
首先我所在的设备作为主机要监听子机的UDP广播,然后将通过我验证的子机向其发送我开放的TCP的地址和端口。

  const String multicastGroup = '224.0.0.1'; // 定义多播组地址  const int port = 5000; // 定义端口号  const int bufferSize = 1024; // 定义缓冲区大小  final ByteData buffer = ByteData(bufferSize);  DatagramSocket socket = DatagramSocket();  socket.bind(port);  socket.joinMulticastGroup(multicastGroupIP);  socket.listen(buffer.length);  socket.onDatagramReceived = (Datagram datagram) async {  final String receivedData = datagram.data.toString();  // 处理接收到的数据...  };  

然后合法的子机会收到我的信息,就可以通过TCP向主机发送命令;
这时就需要主机时刻监听TCP并对其响应。

  const int port = 5000; // 定义端口号  final ServerSocket serverSocket = ServerSocket(port);  serverSocket.onAccept = (ServerSocket socket) async {  final Stream stream = socket.accept();  stream.transform(utf8.decoder).listen((String data) {  // 处理接收到的数据...  });  };  

假设对其响应的本身是对数据库进行操作,而主机内部也同时对数据库有了操作,这时候就要注意数据库的线程安全了;
首先可以通过对数据库的操作加锁来保证,比如sqflite提供了事务(Transaction),在事务中执行数据库操作可以确保操作的原子性,即要么全部成功,要么全部失败;
通过使用事务,我们可以实现对数据库操作的加锁,确保同一时间只有一个线程可以访问数据库中的特定资源。

Future<void> insertData() async {  final db = await getDatabase();  await db.transaction((txn) async {  // 在事务中执行数据库操作  await txn.execute('INSERT INTO user (name, age) VALUES (?, ?)', ('John', 25));  // 提交事务  await txn.commit();  });  
}  

或者直接使用synchronized创建锁。

import 'package:synchronized/synchronized.dart';

还可以通过数据库连接池来限制最大连接数量。

import 'package:sqflite/sqflite.dart';  class DatabaseHelper {  static final DatabaseHelper _instance = DatabaseHelper._internal();  static Database? _db;  factory DatabaseHelper() {  return _instance;  }  Future<Database> get db async {  if (_db != null) return _db;  _db = await _openDatabase();  return _db;  }  Future<void> close() async {  if (_db != null) {  await _db!.close();  _db = null;  }  }  Future<Database> _openDatabase() async {  final pool = await SqliteConnectionPool.forDatabase('path/to/database.db');  pool.maxSize = 10; // 设置最大连接数为10  return pool.openDatabase();  }  
}

这样同时还避免了直接使用Database实例。

相关文章:

Flutter开发进阶之并发操作数据库

Flutter开发进阶之并发操作数据库 尽管 Flutter 本身不包含任何数据库功能&#xff0c;但可以使用各种第三方库和插件来在 Flutter 应用程序中实现数据库功能&#xff1b; 以下将使用sqflite作为例子&#xff0c;sqflite允许在 Flutter 应用程序中执行 SQL 查询&#xff0c;创…...

docker应用:搭建uptime-kuma监控站点

简介&#xff1a;Uptime Kuma是一个易于使用的自托管监控工具&#xff0c;它的界面干净简洁&#xff0c;部署和使用都非常方便。 历史攻略&#xff1a; docker&#xff1a;可视化工具portainer docker-compose&#xff1a;搭建自动化运维平台Spug 开源地址&#xff1a; ht…...

在illustrator中按大小尺寸选择物体 <脚本 018>

在Illustrator中我们可以依据对象的属性 如&#xff1a;填充颜色、描边颜色或描边宽度来选择相同属性的对象&#xff0c;但是Illustrator中没有根据不同大小尺寸来选择对象的功能&#xff0c;下面介绍的就是根据大小尺寸选择对象的脚本。 1、下面是当前画板中的所有对象&#…...

leetcode - 934. Shortest Bridge

Description You are given an n x n binary matrix grid where 1 represents land and 0 represents water. An island is a 4-directionally connected group of 1’s not connected to any other 1’s. There are exactly two islands in grid. You may change 0’s to 1…...

k8s的存储卷、数据卷

容器内的目录和宿主机目录进行挂载。 容器在系统上的生命周期是短暂的。 k8s用控制器创建的pod。delete相当于重启。容器的状态也会恢复到初始状态。一旦恢复到初始状态&#xff0c;所有的后天编辑的文件都会消失 容器和节点之间创建一个可以持久化保存容器内文件的存储卷。…...

流星全自动网页生成系统重构版源码

流星全自动网页生成系统重构版源码分享&#xff0c;所有模板经过精心审核与修改&#xff0c;完美兼容小屏手机大屏手机&#xff0c;以及各种平板端、电脑端和360浏览器、谷歌浏览器、火狐浏览器等等各大浏览器显示。 为用户使用方便考虑&#xff0c;全自动网页制作系统无需繁琐…...

vscode打开c_cpp_properties.json文件的一种方式

步骤一 点击win32 步骤二 点击json 自动生成了...

发起人自选-钉钉审批

场景描述 配置一个审批流程&#xff0c;在某些审批节点&#xff0c;不能确定谁具体来审批&#xff0c;所以需要手工选择一个人或者多个人保证流程能得以顺利通过。有些审批流程的做法是&#xff0c;上一个节点来选择指定的人&#xff0c;而钉钉的做法是发起人来指定。 钉钉设…...

电脑DIY-显卡

显卡 英伟达&#xff08;NVIDIA&#xff09;RTX系列 英伟达&#xff08;NVIDIA&#xff09; 英伟达&#xff08;NVIDIA&#xff09;是一家知名的图形处理器制造商&#xff0c;其显卡产品系列众多。以下是英伟达显卡的主要系列&#xff1a; 系列面向客户说明产品GeForce系列个…...

vue3+vite+ts+pinia新建项目(略详细版)

1、新建项目 npm create vite@latest 2、安装依赖 yarn add vue-router yarn add -D @types/node vite-plugin-pages sass sass-loader 3、配置别名 //vite.config.ts import { defineConfig } from vite import path from node:path export default defineConfig({ plu…...

深入理解 Flink(五)Flink Standalone 集群启动源码剖析

前言 Flink 集群的逻辑概念&#xff1a; JobManager(StandaloneSessionClusterEntrypoint) TaskManager(TaskManagerRunner) Flink 集群的物理概念&#xff1a; ResourceManager(管理集群所有资源&#xff0c;管理集群所有从节点) TaskExecutor(管理从节点资源&#xff0c;接…...

SpringCloud Aliba-Nacos-从入门到学废【2】

&#x1f95a;今日鸡汤&#x1f95a; 比起不做而后悔&#xff0c;不如做了再后悔。 ——空白《游戏人生》 目录 &#x1f9c8;1.Nacos集群架构说明 &#x1f9c2;2.三种部署模式 &#x1f37f;3.切换到mysql 1.在nacos-server-2.0.3\nacos\conf里找到nacos-mysql.sql 2.查…...

web前端算法简介之字典与哈希表

回顾 栈、队列 &#xff1a; 进、出 栈&#xff08;Stack&#xff09;&#xff1a; 栈的操作主要包括&#xff1a; 队列&#xff08;Queue&#xff09;&#xff1a; 队列的操作主要包括&#xff1a; 链表、数组 &#xff1a; 多个元素存储组成的 简述链表&#xff1a;数组&…...

【uview2.0】Keyboard 键盘 与 CodeInput 验证码输入 结合使用 uview

https://www.uviewui.com/components/codeInput.html &#xff08;CodeInput 验证码输入&#xff09; https://www.uviewui.com/components/keyboard.html &#xff08;Keyboard 键盘&#xff09; <u-keyboard mode"number" :dotDisabled"true" :show&q…...

解决chromebook kabylake安装linux没有声音问题

chromebook kabylake安装arch没有声音&#xff0c;好长时间没有解决&#xff0c;一直用的蓝牙耳机。 今天搜搜帖子解决了&#xff0c; 分享供参考 git clone https://github.com/eupnea-project/chromebook-linux-audiocd chromebook-linux-audio ./setup-audio提示 I Underst…...

Spring Boot - Application Events 的发布顺序_ApplicationContextInitializedEvent

文章目录 Pre概述Code源码分析 Pre Spring Boot - Application Events 的发布顺序_ApplicationEnvironmentPreparedEvent Spring Boot - Application Events 的发布顺序_ApplicationEnvironmentPreparedEvent 概述 Spring Boot 的广播机制是基于观察者模式实现的&#xff0c…...

由jar包冲突导致的logback日志不输出

最近接手一个厂商移交的项目&#xff0c;发现后管子系统不打印日志。 项目使用的logback 本地断点调试发现logback-classic jar冲突导致 打出的war中没有 相关的jar 解决方法&#xff1a; 去除pom 文件中多余的 logback-classic 应用&#xff0c;只保留最新版本的。 重新打…...

app开发——安卓native开发思路记录

我们知道app开发目前有三种方式&#xff0c;第一种是webapp&#xff0c;第二种是hybird app&#xff0c;第三种是native app。 而native-app就是安卓原生app&#xff0c;这里记录一下安卓原生开发的基本思路。 首先&#xff0c;安卓原生开发虽然在当今时代不是那么常见了&…...

黑马程序员JavaWeb开发|案例:tlias智能学习辅助系统(1)准备工作、部门管理

一、准备工作 1.明确需求 根据产品经理绘制的页面原型&#xff0c;对部门和员工进行相应的增删改查操作。 2.环境搭建 将使用相同配置的不同项目作为Module放入同一Project&#xff0c;以提高相同配置的复用性。 准备数据库表&#xff08;dept, emp&#xff09; 资料中包含…...

C# .NET SQL sugar中 IsAny进行根据条件判断数据是否存在 IsAny的使用

SQL sugar 中控制器直接判断数据是否存在 首先确保你的Service层继承的表名 控制器中使用IsAny进行根据条件判断数据是否存在...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

基于鸿蒙(HarmonyOS5)的打车小程序

1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...

Python训练营-Day26-函数专题1:函数定义与参数

题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一个名为 calculate_circle_area 的函数&#xff0c;该函数接收圆的半径 radius 作为参数&#xff0c;并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求&#xff1a;函数接收一个位置参数 radi…...