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

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&#xff0c;可考虑采用数据库。相比于其他本地持久化方案来说&#xff0c;数据库能够提供更为迅速的插入、更新、查询功能。这里需要用到sqflite package 来使用 SQLite 数据库 预…...

【路由組件】

完成Vue Router 安装后&#xff0c;就可以使用路由了&#xff0c;路由的基本使用步骤&#xff0c;首先定义路由组件&#xff0c;以便使用Vue Router控制路由组件展示与 切换&#xff0c;接着定义路由链接和路由视图&#xff0c;以便告知路由组件渲染到哪个位置&#xff0c;然后…...

【C++风云录】数字逻辑设计优化:电子设计自动化与集成电路

集成电路设计&#xff1a;打开知识的大门 前言 本文将详细介绍关于数字芯片设计&#xff0c;电子设计格式解析&#xff0c;集成电路设计工具&#xff0c;硬件描述语言分析&#xff0c;电路验证以及电路优化六个主题的深入研究与实践。每一部分都包含了主题的概述&#xff0c;…...

Flask Response 对象

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

算法001:移动零

力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/move-zeroes/ 使用 双指针 来解题&#xff1a; 此处的双指针&#xff0c;…...

基于springboot+vue+Mysql的网上书城管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…...

python实现绘制烟花代码

在Python中&#xff0c;我们可以使用多个库来绘制烟花效果&#xff0c;例如turtle库用于简单的绘图&#xff0c;或者更复杂的库如pygame或matplotlib结合动画。但是&#xff0c;由于turtle库是Python自带的&#xff0c;我们可以使用它来绘制一个简单的烟花效果。 下面是一个使…...

Python小白的机器学习入门指南

Python小白的机器学习入门指南 大家好&#xff01;今天我们来聊一聊如何使用Python进行机器学习。本文将为大家介绍一些基本的Python命令&#xff0c;并结合一个简单的数据集进行实例讲解&#xff0c;希望能帮助你快速入门机器学习。 数据集介绍 我们将使用一个简单的鸢尾花数…...

学校上课,是耽误我学习了。。

>>上一篇&#xff08;文科生在三本院校&#xff0c;读计算机专业&#xff09; 2015年9月&#xff0c;我入学了。 我期待的大学生活是多姿多彩的&#xff0c;我会参加各种社团&#xff0c;参与各种有意思的活动。 但我是个社恐&#xff0c;有过尝试&#xff0c;但还是难…...

OpenFeign高级用法:缓存、QueryMap、MatrixVariable、CollectionFormat优雅地远程调用

码到三十五 &#xff1a; 个人主页 微服务架构中&#xff0c;服务之间的通信变得尤为关键。OpenFeign&#xff0c;一个声明式的Web服务客户端&#xff0c;使得REST API的调用变得更加简单和优雅。OpenFeign集成了Ribbon和Hystrix&#xff0c;具有负载均衡和容错的能力&#xff…...

python基础之函数

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

深入理解C#中的IO操作 - FileStream流详解与示例

文章目录 一、FileStream类的介绍二、文件读取和写入2.1 文件读取&#xff08;FileStream.Read&#xff09;2.2 文件写入&#xff08;FileStream.Write&#xff09; 三、文件复制、移动和目录操作3.1 文件复制&#xff08;FileStream.Copy&#xff09;3.2 文件移动&#xff08;…...

信息泄露--注意点点

目录 明确目标: 信息泄露: 版本软件 敏感文件 配置错误 url基于文件: url基于路由: 状态码: http头信息泄露 报错信息泄露 页面信息泄露 robots.txt敏感信息泄露 .get文件泄露 --判断: 搜索引擎收录泄露 BP: 爆破: 明确目标: 失能 读取 写入 执行 信息泄…...

位运算符

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

云上聚智——移动云云服务器进行后端的搭建及部署

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

C语言程序的编译

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

滴滴三面 | Go后端研发

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

深度学习之基于Yolov3的行人重识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 行人重识别&#xff08;Person Re-Identification&#xff0c;简称ReID&#xff09;是计算机视觉领域…...

防火墙最新技术汇总

防火墙技术持续发展&#xff0c;以应对日益复杂的网络安全威胁。以下是防火墙领域的一些最新技术汇总&#xff1a; 下一代防火墙&#xff08;NGFW&#xff09;&#xff1a;NGFW结合了传统防火墙的分组过滤和状态检测功能&#xff0c;还集成了深度包检测&#xff08;DPI&#xf…...

PikaUnsafe upfileupload

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

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

Vue 模板语句的数据来源

&#x1f9e9; Vue 模板语句的数据来源&#xff1a;全方位解析 Vue 模板&#xff08;<template> 部分&#xff09;中的表达式、指令绑定&#xff08;如 v-bind, v-on&#xff09;和插值&#xff08;{{ }}&#xff09;都在一个特定的作用域内求值。这个作用域由当前 组件…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...

【51单片机】4. 模块化编程与LCD1602Debug

1. 什么是模块化编程 传统编程会将所有函数放在main.c中&#xff0c;如果使用的模块多&#xff0c;一个文件内会有很多代码&#xff0c;不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里&#xff0c;在.h文件里提供外部可调用函数声明&#xff0c;其他.c文…...

如何把工业通信协议转换成http websocket

1.现状 工业通信协议多数工作在边缘设备上&#xff0c;比如&#xff1a;PLC、IOT盒子等。上层业务系统需要根据不同的工业协议做对应开发&#xff0c;当设备上用的是modbus从站时&#xff0c;采集设备数据需要开发modbus主站&#xff1b;当设备上用的是西门子PN协议时&#xf…...