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实例。

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

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

相关文章

基于深度学习的多类别电表读数识别方案详解

基于深度学习的多类别电表读数识别方案详解 多类别电表读数识别方案详解项目背景项目难点最终项目方案系列项目全集&#xff1a; 安装说明环境要求 数据集简介数据标注模型选型明确目标&#xff0c;开始下一步的操作 检测模型训练模型评估与推理番外篇&#xff1a;基于目标检测…

vue3移动端适配

将vue3项目中的 px 单位&#xff0c;自动转换为rem 单位 可以看到这里会根据页面缩小放大变化 需要安装两个插件&#xff0c;看步骤 amfe-flexible --- 默认指向2.2.1版本 npm i -S amfe-flexiblepostcss-pxtorem --- 默认指向6.0.0版本 --save-dev 参数会把依赖包的版本信…

机器学习---lightGBM

1. lightGBM演进过程 AdaBoost是⼀种提升树的方法&#xff0c;和三个臭皮匠&#xff0c;赛过诸葛亮的道理⼀样。 AdaBoost两个问题&#xff1a; (1) 如何改变训练数据的权重或概率分布提高前⼀轮被弱分类器错误分类的样本的权重&#xff0c;降低前⼀ 轮被分对的权重 (2) 如何…

vue3、vue2文件导入事件

一、vue3写法 1、html部分 <el-buttontype"info"plainicon"Upload"click"handleImport"v-hasPermi"[system:user:import]">导入</el-button><!-- 导入对话框 --><el-dialog :title"upload.title" v-…

mysql进阶-索引基础

目录 1. 概念-索引是什么&#xff1f; 2. 索引的数据结构(索引模型) 2.1 二分查找&#xff1a; 2.2 二叉查找树&#xff08;BST Binary Search Tree&#xff09;&#xff1a; 2.3 平衡二叉树(AVL Tree Balanced binary search trees) 2.4 多路平衡查找树(B Tree Balanced…

推荐一款通过ssh连接linux服务的开源工具WindTerm

文章目录 前言WindTerm介绍WindTerm使用主密码和锁屏总结 前言 工作一入门便是游戏服务器开发&#xff0c;所以常常有连接Linux服务器的需求&#xff0c;之前用的最多的是Xshell&#xff0c;最近这个软件个人版只能免费使用一个月了&#xff0c;超过时间会提示更新无法正常使用…

C++学习笔记——输入、输出和文件

目录 一、标准输入输出 2.1下面是它们的基本用法 解释 二、格式化输入输出 2.2下面是一个示例 解释 三、文件读写 3.3下面是一个文件读写的示例 解释 四、异常处理和错误检测 4.1下面是一个示例 解释 五、一个实例代码 5.1如何读取 CSV 文件&#xff0c;并计算每…

【数据结构】交换排序

插入排序链接。 这篇文章讲解交换排序的两种排序&#xff1a;冒泡排序与快速排序。 目录 冒泡排序&#xff1a;完整代码&#xff1a; 快速排序&#xff1a;单趟排序&#xff1a;hoare&#xff1a;挖坑&#xff1a;前后指针&#xff1a; 完整代码&#xff08;3种方式&#xff0…

3 - AOP

1. 快速入门 1.1 基本说明 AOP(aspect oriented programming) &#xff0c;面向切面编程 切面类中声明通知方法&#xff1a; 前置通知&#xff1a;Before返回通知&#xff1a;AfterReturning异常通知&#xff1a;AfterThrowing后置通知&#xff1a;After环绕通知&#xff1…

2、Redis持久化、主从与哨兵:构建强大而稳定的数据生态

Redis作为一款高性能的内存数据库&#xff0c;其在持久化、主从复制和哨兵系统方面的支持使其在大规模应用和高可用性场景中脱颖而出。本文将深入探讨Redis的持久化机制、主从复制以及哨兵系统&#xff0c;为构建强大而稳定的数据生态揭示关键技术。 持久化&#xff1a;数据的…

二进制与十六进制,二进制与八进制之间的相互转换技巧

目录 1.二进制转换为八进制 2.八进制转换为二进制 3.二进制转换为十六进制 4.十六进制转换为二进制 1.二进制转换为八进制 转换为8进制 第一步&#xff1a;以小数点为分界线&#xff0c;整数部分自右向左&#xff0c;小数部分自左向右每3位取成1位&#xff1a; 整数部分…

【python入门】day28:记录用户登录日志

演示 代码 #-*- coding:utf-8 -*- print(记录用户登录日志----------------------------) import time def show_info():print(输入提示数字,执行相应操作:0退出,1查看登录日志) def write_logininfo(username):#----------记录日志with open(log.txt,a,encodingutf-8)as file…

如何高效阅读Linux的man page

有时候需要在man page中查某个命令的用法&#xff0c;我们一般会使用man command的方式来查询&#xff0c;例如man vmstat.但是对于一些bash内置的命令&#xff0c;如alias,如果使用man alias会打开General Commands Manual ,如下图 可以看到&#xff0c;内置命令很多&#xff…

COBOL语言 :一种主要专注于解决业务问题的编程语言

译文&#xff1a; 什么是COBOL? COBOL是一种主要专注于解决业务问题的编程语言。COBOL的完整形式是面向业务的通用语言。它主要用于公司和政府的商业、金融和行政系统。这种语言也被用来解决许多数据处理问题。 它是由CODASYL(数据系统语言会议)开发的。它被用作大型机中的一…

基于 InternLM 和 LangChain 搭建你的知识库

如何打造垂域大模型是一个重要落地方向。 如何打造个人专属的大模型应用也是重要的问题。 RAG 外挂一个知识库 优势&#xff1a;成本低&#xff0c;实时更新 劣势&#xff1a;能力受基座模型影响大&#xff0c;RAG每次需要将检索文档和问题提交给大模型&#xff0c;极大占用上下…

工程项目管理系统源码与Spring Cloud:实现高效系统管理与二次开发

随着企业规模的不断扩大和业务的快速发展&#xff0c;传统的工程项目管理方式已经无法满足现代企业的需求。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;企业需要借助先进的数字化技术进行转型。本文将介绍一款采用Spring CloudSpring BootMybat…

C++力扣题目701--二叉搜索树中的插入操作

给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值都不同。 注意&#xff0c;可能存在多种有效的插入方式&a…

苏州倍丰智能新型雾化粉末技术量产成功!金属3D打印全产业链更进一步

苏州倍丰智能深耕金属3D打印技术领域&#xff0c;以金属3D打印全产业链为目标&#xff0c;围绕金属3D打印设备&#xff0c;涵盖包括金属粉末前后处理设备、金属粉末原材料制备、先进工艺研发等多个领域&#xff0c;完成了一整条自上而下的金属3D打印全产业链。 近日&#xff0c…

大数据Doris(五十四):SQL函数之日期函数(二)

文章目录 SQL函数之日期函数(二) 一、DAYOFMONTH(DATETIME date) 二、dayofweek(DATETIME date)

HarmonyOS 通过 animateTo讲解尺寸动画效果

上文 HarmonyOS讲解并演示 animateTo 动画效果 我们已经做出了基本的动画效果 也对 animateTo 的使用比较熟悉了 第一个参数是 配置动画参数的json 第二个参数 则是改变我们元素属性值的事件 但属性值 远远不止位置属性 本文 我们来说 通过尺寸变化 完成动画效果 如果你有看过…