flutter开发实战-本地SQLite数据存储
flutter开发实战-本地SQLite数据库存储
正在编写一个需要持久化且查询大量本地设备数据的 app,可考虑采用数据库。相比于其他本地持久化方案来说,数据库能够提供更为迅速的插入、更新、查询功能。这里需要用到sqflite package 来使用 SQLite 数据库
预览图
一、引入sqflite
在工程的pubspec.yaml中引入插件
# sqflitesqflite: ^2.2.8+4
二、使用sqflite
使用 sqflite 实现插入,读取,更新,删除数据。
- 打开数据库
Future<void> openDB(BuildContext context) async {// Open the database and store the reference.database = await openDatabase(// Set the path to the database. Note: Using the `join` function from the// `path` package is best practice to ensure the path is correctly// constructed for each platform.join(await getDatabasesPath(), 'doggie_database.db'),// When the database is first created, create a table to store dogs.onCreate: (db, version) {// Run the CREATE TABLE statement on the database.return db.execute('CREATE TABLE dogs(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)',);},version: 1,);}
- 插入一条记录
Future<void> insertDB(BuildContext context) async {dogId++;// Create a Dog and add it to the dogs tablevar fido = Dog(id: dogId,name: 'Fido',age: 35,);// Get a reference to the database.final db = await database;// Insert the Dog into the correct table. You might also specify the// `conflictAlgorithm` to use in case the same dog is inserted twice.//// In this case, replace any previous data.await db?.insert('dogs',fido.toMap(),conflictAlgorithm: ConflictAlgorithm.replace,);}
- 更新一条记录
Future<void> updateDog(Dog dog) async {// Get a reference to the database.final db = await database;// Update the given Dog.await db?.update('dogs',dog.toMap(),// Ensure that the Dog has a matching id.where: 'id = ?',// Pass the Dog's id as a whereArg to prevent SQL injection.whereArgs: [dog.id],);}
- 删除一条记录
Future<void> deleteDog(int id) async {// Get a reference to the database.final db = await database;// Remove the Dog from the database.await db?.delete('dogs',// Use a `where` clause to delete a specific dog.where: 'id = ?',// Pass the Dog's id as a whereArg to prevent SQL injection.whereArgs: [id],);}
- 获取存储记录
// A method that retrieves all the dogs from the dogs table.Future<List<Dog>> dogs() async {// Get a reference to the database.final db = await database;// Query the table for all the dogs.final List<Map<String, Object?>>? dogMaps = await db?.query('dogs');if (dogMaps != null && dogMaps.isNotEmpty) {// Convert the list of each dog's fields into a list of `Dog` objects.List<Dog> dogs = [];for(var dogMap in dogMaps) {// Dog dog = Dog(id: dogMap['id']??0, name: name, age: age)var id = dogMap['id'] as int;var name = dogMap['name'] as String;var age = dogMap['age'] as int;Dog dog = Dog(id: id, name: name, age: age);dogs.add(dog);}return dogs;}return [];}
完整代码如下
import 'package:flutter/material.dart';
import 'dart:async';import 'package:flutter/widgets.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';class SqliteDemoPage extends StatefulWidget {const SqliteDemoPage({super.key});@overrideState<SqliteDemoPage> createState() => _SqliteDemoPageState();
}class _SqliteDemoPageState extends State<SqliteDemoPage> {Database? database;int dogId = 0;Future<void> openDB(BuildContext context) async {// Open the database and store the reference.database = await openDatabase(// Set the path to the database. Note: Using the `join` function from the// `path` package is best practice to ensure the path is correctly// constructed for each platform.join(await getDatabasesPath(), 'doggie_database.db'),// When the database is first created, create a table to store dogs.onCreate: (db, version) {// Run the CREATE TABLE statement on the database.return db.execute('CREATE TABLE dogs(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)',);},version: 1,);}// A method that retrieves all the dogs from the dogs table.Future<List<Dog>> dogs() async {// Get a reference to the database.final db = await database;// Query the table for all the dogs.final List<Map<String, Object?>>? dogMaps = await db?.query('dogs');if (dogMaps != null && dogMaps.isNotEmpty) {// Convert the list of each dog's fields into a list of `Dog` objects.List<Dog> dogs = [];for(var dogMap in dogMaps) {// Dog dog = Dog(id: dogMap['id']??0, name: name, age: age)var id = dogMap['id'] as int;var name = dogMap['name'] as String;var age = dogMap['age'] as int;Dog dog = Dog(id: id, name: name, age: age);dogs.add(dog);}return dogs;}return [];}Future<void> updateDog(Dog dog) async {// Get a reference to the database.final db = await database;// Update the given Dog.await db?.update('dogs',dog.toMap(),// Ensure that the Dog has a matching id.where: 'id = ?',// Pass the Dog's id as a whereArg to prevent SQL injection.whereArgs: [dog.id],);}Future<void> deleteDog(int id) async {// Get a reference to the database.final db = await database;// Remove the Dog from the database.await db?.delete('dogs',// Use a `where` clause to delete a specific dog.where: 'id = ?',// Pass the Dog's id as a whereArg to prevent SQL injection.whereArgs: [id],);}Future<void> insertDB(BuildContext context) async {dogId++;// Create a Dog and add it to the dogs tablevar fido = Dog(id: dogId,name: 'Fido',age: 35,);// Get a reference to the database.final db = await database;// Insert the Dog into the correct table. You might also specify the// `conflictAlgorithm` to use in case the same dog is inserted twice.//// In this case, replace any previous data.await db?.insert('dogs',fido.toMap(),conflictAlgorithm: ConflictAlgorithm.replace,);}Future<void> getListFromDB(BuildContext context) async {List<Dog> list = await dogs();for(var dog in list) {print("dog info:${dog.toString()}");}}void updateDB(BuildContext context) {var dog = Dog(id: dogId,name: 'AFarah',age: 11,);updateDog(dog);}Future<void> deleteDB(BuildContext context) async {await deleteDog(dogId);dogId--;}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('SqliteDemo'),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,crossAxisAlignment: CrossAxisAlignment.center,children: [const SizedBox(height: 20,),TextButton(onPressed: () {openDB(context);},child: Container(height: 36,width: 200,color: Colors.lightGreen,alignment: Alignment.center,child: const Text('openDatabase',style: TextStyle(fontSize: 12, color: Colors.white),),),),const SizedBox(height: 20,),TextButton(onPressed: () {insertDB(context);},child: Container(height: 36,width: 200,color: Colors.lightGreen,alignment: Alignment.center,child: const Text('插入一条dog记录',style: TextStyle(fontSize: 12, color: Colors.white),),),),const SizedBox(height: 20,),TextButton(onPressed: () {getListFromDB(context);},child: Container(height: 36,width: 200,color: Colors.lightGreen,alignment: Alignment.center,child: const Text('获取记录列表',style: TextStyle(fontSize: 12, color: Colors.white),),),),const SizedBox(height: 20,),TextButton(onPressed: () {updateDB(context);},child: Container(height: 36,width: 200,color: Colors.lightGreen,alignment: Alignment.center,child: const Text('更新一条记录',style: TextStyle(fontSize: 12, color: Colors.white),),),),const SizedBox(height: 20,),TextButton(onPressed: () {deleteDB(context);},child: Container(height: 36,width: 200,color: Colors.lightGreen,alignment: Alignment.center,child: const Text('删除一条记录',style: TextStyle(fontSize: 12, color: Colors.white),),),),],),),);}
}class Dog {final int id;final String name;final int age;const Dog({required this.id,required this.name,required this.age,});// Convert a Dog into a Map. The keys must correspond to the names of the// columns in the database.Map<String, Object?> toMap() {return {'id': id,'name': name,'age': age,};}// Implement toString to make it easier to see information about// each dog when using the print statement.@overrideString toString() {return 'Dog{id: $id, name: $name, age: $age}';}
}
三、小结
flutter开发实战-本地SQLite数据库存储
学习记录,每天不停进步。
相关文章:

flutter开发实战-本地SQLite数据存储
flutter开发实战-本地SQLite数据库存储 正在编写一个需要持久化且查询大量本地设备数据的 app,可考虑采用数据库。相比于其他本地持久化方案来说,数据库能够提供更为迅速的插入、更新、查询功能。这里需要用到sqflite package 来使用 SQLite 数据库 预…...
【路由組件】
完成Vue Router 安装后,就可以使用路由了,路由的基本使用步骤,首先定义路由组件,以便使用Vue Router控制路由组件展示与 切换,接着定义路由链接和路由视图,以便告知路由组件渲染到哪个位置,然后…...
【C++风云录】数字逻辑设计优化:电子设计自动化与集成电路
集成电路设计:打开知识的大门 前言 本文将详细介绍关于数字芯片设计,电子设计格式解析,集成电路设计工具,硬件描述语言分析,电路验证以及电路优化六个主题的深入研究与实践。每一部分都包含了主题的概述,…...

Flask Response 对象
文章目录 创建 Response 对象设置响应内容设置响应状态码设置响应头完整的示例拓展设置响应的 cookie重定向响应发送文件作为响应 总结 Flask 是一个 Python Web 框架,用于快速开发 Web 应用程序。在 Flask 中,我们使用 Response 对象来构建 HTTP 响应。…...

算法001:移动零
力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/move-zeroes/ 使用 双指针 来解题: 此处的双指针,…...

基于springboot+vue+Mysql的网上书城管理系统
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...
python实现绘制烟花代码
在Python中,我们可以使用多个库来绘制烟花效果,例如turtle库用于简单的绘图,或者更复杂的库如pygame或matplotlib结合动画。但是,由于turtle库是Python自带的,我们可以使用它来绘制一个简单的烟花效果。 下面是一个使…...
Python小白的机器学习入门指南
Python小白的机器学习入门指南 大家好!今天我们来聊一聊如何使用Python进行机器学习。本文将为大家介绍一些基本的Python命令,并结合一个简单的数据集进行实例讲解,希望能帮助你快速入门机器学习。 数据集介绍 我们将使用一个简单的鸢尾花数…...
学校上课,是耽误我学习了。。
>>上一篇(文科生在三本院校,读计算机专业) 2015年9月,我入学了。 我期待的大学生活是多姿多彩的,我会参加各种社团,参与各种有意思的活动。 但我是个社恐,有过尝试,但还是难…...

OpenFeign高级用法:缓存、QueryMap、MatrixVariable、CollectionFormat优雅地远程调用
码到三十五 : 个人主页 微服务架构中,服务之间的通信变得尤为关键。OpenFeign,一个声明式的Web服务客户端,使得REST API的调用变得更加简单和优雅。OpenFeign集成了Ribbon和Hystrix,具有负载均衡和容错的能力ÿ…...

python基础之函数
目录 1.函数相关术语 2.函数类型分类 3.栈 4.位置参数和关键字参数 5.默认参数 6.局部变量和全局变量 7.返回多个值 8.怀孕函数 9.匿名函数 10.可传递任意个数实参的函数 11.函数地址与函数接口 12.内置函数修改与函数包装 1.函数相关术语 函数的基本概念有函数头…...

深入理解C#中的IO操作 - FileStream流详解与示例
文章目录 一、FileStream类的介绍二、文件读取和写入2.1 文件读取(FileStream.Read)2.2 文件写入(FileStream.Write) 三、文件复制、移动和目录操作3.1 文件复制(FileStream.Copy)3.2 文件移动(…...
信息泄露--注意点点
目录 明确目标: 信息泄露: 版本软件 敏感文件 配置错误 url基于文件: url基于路由: 状态码: http头信息泄露 报错信息泄露 页面信息泄露 robots.txt敏感信息泄露 .get文件泄露 --判断: 搜索引擎收录泄露 BP: 爆破: 明确目标: 失能 读取 写入 执行 信息泄…...

位运算符
自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 位运算符是把数字看作二进制数来进行计算的,因此,需要先将要执行运算的数据转换为二进制,然后才能进行执行运算。…...

云上聚智——移动云云服务器进行后端的搭建及部署
什么是移动云 移动云是指将移动设备和云计算技术相结合,为移动应用提供强大的计算和存储能力的服务模式。传统的移动应用通常在本地设备上进行计算和存储,而移动云将这些任务转移到云端进行处理。通过移动云,移动设备可以利用云端的高性能计算…...

C语言程序的编译
目录 一、预处理(预编译) 二、编译 三、汇编 四,链接 在前面讲到了宏的定义,那么宏在编译时候是如何发生替换的?接下来做一下详细的介绍C语言程序的编译过程主要包括以下几个步骤:预处理、编译、汇编和…...

滴滴三面 | Go后端研发
狠狠的被鞭打了快两个小时… 注意我写的题解不一定是对的,如果你认为有其他答案欢迎评论区留言 bg:23届 211本 社招 1. 自我介绍 2. 讲一个项目的点,因为用到了中间件平台的数据同步,于是开始鞭打数据同步。。 3. 如果同步的时候…...

深度学习之基于Yolov3的行人重识别
欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 行人重识别(Person Re-Identification,简称ReID)是计算机视觉领域…...
防火墙最新技术汇总
防火墙技术持续发展,以应对日益复杂的网络安全威胁。以下是防火墙领域的一些最新技术汇总: 下一代防火墙(NGFW):NGFW结合了传统防火墙的分组过滤和状态检测功能,还集成了深度包检测(DPI…...

PikaUnsafe upfileupload
1.client check 客户端检测,前端js检测,禁用js和修改后缀名即可。 php格式不能上传,我们修改后缀上传。 蚁剑成功连接。 2.MIME type 这个就是 content-type 规定上传类型,上面的方法也能成功,也可以修改 conten-ty…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...