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

Flutter开发笔记 —— sqflite插件数据库应用

前言

今天在观阅掘金大佬文章的时候,了解到了该 sqflite 插件,结合官网教程和自己实践,由此总结出该文,希望对大家的学习有帮助!

插件详情

Flutter的 SQLite 插件。支持 iOS、Android 和 MacOS。

  • 支持事务和batch模式
  • 打开时自动进行版本管理
  • 插入/查询/更新/删除查询的助手
  • iOS 和 Android 上的数据库操作在后台线程中执行

插件地址: https://pub.dev/packages/sqflite

本文使用插件版本为最新版本:2.3.0

基础介绍

数据表创建

  • openDatabase() 连接数据库
  • deleteDatabase() 删除数据库

openDataBase方法 可选参为db文件地址、版本号、相关回调

案例速览

late Database db;
final database = "book.db";
final table = "book";/** @author Marinda* @date 2023/12/13 15:53* @description 连接数据库*/
connection() async{//获取var databasePath = await getDatabasesPath();String path = p.join(databasePath,database);//删除数据库await deleteDatabase(path);print('当前地址:${path}');if(File(path).existsSync()){db = await openDatabase(path);}else{db = await openDatabase(path,version: 1,onCreate: (database,version) async{database.execute("CREATE TABLE `${table}` (id integer primary key autoincrement,name text not null,price REAL ,author TEXT NOT NULL,description TEXT)");});}
}

语句介绍

CURD方法介绍

  • 使用SQL语句的CURD前缀带raw (例如rawInsert)
  • 官方封装好的CURD语句不带raw(例如insert) ->全文使用该方法

语法速览

//前者
Future<int> rawInsert(String sql, [List<Object?>? arguments]);
//后者
Future<int> insert(String table, Map<String, Object?> values,{String? nullColumnHack, ConflictAlgorithm? conflictAlgorithm});

接下来看几个简单的CURD快速了解写法

insert(插入)

Future<int> insert() async{Map<String,dynamic> args = {"id": 1,"name": "张飞","description": "猛将"};//返回id table为表名return await db.insert(table,args);
}

delete(删除)

Future<int> delete(int id) async{return await db.delete(table,where: "id = ?",whereArgs: [id]);
}

update(修改)

Future<int> update() async{Map<String,dynamic> args = {"id": 1,"name": "吕布","description": "天下无双"};return await db.update(table, args,where: "id = ?",whereArgs: [args["id"]]);
}

select(查询)

/** @author Marinda* @date 2023/12/13 16:11* @description 通过id查询*/
Future<Map<String,dynamic>?> selectById(int id) async{var list = await db.query(table,where: "id = ?",whereArgs: [id]);if(list.isNotEmpty){return list.first;}return null;
}

现在我们对sqflite插件的基础使用有一个初步的了解了,接下来围绕一个书本表案例做实战

实战应用

  • 定义Book书表作为实体类
  • 定义DBBookProvider类处理数据库表

book.dart

/*** @author Marinda* @date 2023/12/13 15:42* @description 书籍信息*/
class Book {int? _id;String? _name;double? _price;String? _author;String? _description;Book({int? id,String? name,double? price,String? author,String? description}) {if (id != null) {this._id = id;}if (name != null) {this._name = name;}if (price != null) {this._price = price;}if (author != null) {this._author = author;}if (description != null) {this._description = description;}}int? get id => _id;set id(int? id) => _id = id;String? get name => _name;set name(String? name) => _name = name;double? get price => _price;set price(double? price) => _price = price;String? get author => _author;set author(String? author) => _author = author;String? get description => _description;set description(String? description) => _description = description;Book.fromJson(Map<String, dynamic> json) {_id = json['id'];_name = json['name'];_price = json['price'];_author = json['author'];_description = json['description'];}Map<String, dynamic> toJson() {final Map<String, dynamic> data = new Map<String, dynamic>();data['id'] = this._id;data['name'] = this._name;data['price'] = this._price;data['author'] = this._author;data['description'] = this._description;return data;}
}

db_book_provider.dart

/*** @author Marinda* @date 2023/12/13 15:43* @description 书籍数据库适配器*/class DBBookProvider{late Database db;final database = "book.db";final table = "book";static DBBookProvider? _instance;static DBBookProvider instance = getInstance();DBBookProvider._();factory DBBookProvider(){return instance;}static getInstance(){if(_instance == null){_instance = DBBookProvider._();}return _instance ?? DBBookProvider._();}/** @author Marinda* @date 2023/12/13 15:53* @description 连接数据库*/connection() async{var databasePath = await getDatabasesPath();String path = p.join(databasePath,database);// await deleteDatabase(path);print('当前地址:${path}');if(File(path).existsSync()){db = await openDatabase(path);}else{db = await openDatabase(path,version: 1,onCreate: (database,version) async{database.execute("CREATE TABLE `${table}` (id integer primary key autoincrement,name text not null,price REAL ,author TEXT NOT NULL,description TEXT)");});}}/** @author Marinda* @date 2023/12/13 16:01* @description 关闭数据库*/close() async{await db.close();}/** @author Marinda* @date 2023/12/13 16:02* @description 插入*/Future<Book> insert(Book book) async{int id = await db.insert(table,book.toJson());book.id = id;return book;}/** @author Marinda* @date 2023/12/13 16:08* @description 删除id*/Future<int> delete(int id) async{return await db.delete(table,where: "id = ?",whereArgs: [id]);}/** @author Marinda* @date 2023/12/13 16:11* @description 通过id查询*/Future<Book?> selectById(int id) async{var list = await db.query(table,where: "id = ?",whereArgs: [id]);if(list.isNotEmpty){return Book.fromJson(list.first);}return null;}/** @author Marinda* @date 2023/12/13 16:13* @description 获取所有书籍列表*/Future<List<Book>> queryList() async{svar result = await db.query(table);return result.map((e) => Book.fromJson(e)).toList();}/** @author Marinda* @date 2023/12/13 16:15* @description 修改书籍信息*/Future<int> update(Book book) async{return await db.update(table, book.toJson(),where: "id = ?",whereArgs: [book.id]);}}

实例化调用


initDatabase() async{DBBookProvider dbBookProvider = DBBookProvider.instance;//连接await dbBookProvider.connection();Book book = Book(name: "斗破苍穹",author: "天蚕土豆",price: 88.00,description: "一本不错的小说");//插入Book element = await dbBookProvider.insert(book);print('element : ${element.toJson()}');//删除for(var id in result){await dbBookProvider.delete(id);}Book newBook = Book.fromJson(book.toJson());newBook.id = 1;newBook.author = "天蚕土豆";//修改await dbBookProvider.update(newBook);//查询全部var list = await dbBookProvider.queryList();print("当前列表: ${list.map((e) => e.toJson()).toList()}");
}

事务&batch

单独拉出来讲讲的原因是我在应用中踩了个坑

事务和batch是什么这个大家如果不了解的话自行百度一下,下文带大家简单看看案例

/** @author Marinda* @date 2023/12/13 16:17* @description 批量插入全部书籍列表*/
insertAll(List<Book> bookList) async{List resultList = [];await db.transaction((txn) async{Batch batch = txn.batch();for(var book in bookList){batch.insert(table,book.toJson());}//返回全部结果并且不跳过错误!resultList = await batch.commit(noResult: false,continueOnError: false);print('resultList: ${resultList}');});await close();return resultList;
}

注:在该案例中配合事务 batch.commit方法中如果continueOnError为false时 出现异常则会中止,导致前面插入回推。

注:在该insertAll()方法 或其他涉及事务的方法,都要执行完毕后主动调用close() 断开本次连接。否则会导致 Error Domain=FMDatabase Code=5 “database is locked”

如果已经出现 Error Domain=FMDatabase Code=5 “database is locked” 错误,请删除该数据库文件,重新生成。

结束语

感谢你的观看,希望对大家学习有帮助,有不对的地方欢迎指正!

相关文章:

Flutter开发笔记 —— sqflite插件数据库应用

前言 今天在观阅掘金大佬文章的时候&#xff0c;了解到了该 sqflite 插件&#xff0c;结合官网教程和自己实践&#xff0c;由此总结出该文&#xff0c;希望对大家的学习有帮助&#xff01; 插件详情 Flutter的 SQLite 插件。支持 iOS、Android 和 MacOS。 支持事务和batch模式…...

OxLint 发布了,Eslint 何去何从?

由于最近的rust在前端领域的崛起&#xff0c;基于rust的前端生态链遭到rust底层重构&#xff0c;最近又爆出OxLint&#xff0c;是一款基于Rust的linter工具Oxlint在国外前端圈引起热烈讨论&#xff0c;很多大佬给出了高度评价&#xff1b;你或许不知道OxLint&#xff0c;相比ES…...

第一次使用ThreadPoolExecutor处理业务

通过对业务逻辑的分析&#xff0c;进行编码&#xff0c;先把第一条sql查出来的数据进行分组&#xff0c;然后分别使用不同的线程去查询数据返回&#xff0c;并添加到原来的数据中。 总感觉哪里写的不对&#xff0c;但是同事们都没用过这个&#xff0c;请大家指教一下&#xff…...

Sharding-Jdbc(6):Sharding-Jdbc日志分析

1 修改配置 将配置文件中的开启分片日志从false改为true Sharding-JDBC中的路由结果是通过分片字段和分片方法来确定的,如果查询条件中有 id 字段的情况还好&#xff0c;查询将会落到某个具体的分片&#xff1b;如果查询没有分片的字段&#xff0c;会向所有的db或者是表都会查…...

centos安装了curl却报 -bash: curl: command not found

前因 我服务器上想用curl下载docker-compress&#xff0c;发现没有curl命令&#xff0c;就去下载安装&#xff0c;安装完成之后&#xff0c;报-bash: curl: command not found 解决方法 [rootcentos ~]# rpm -e --nodeps curl warning: file /usr/bin/curl: remove failed: …...

Re58:读论文 REALM: Retrieval-Augmented Language Model Pre-Training

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文名称&#xff1a;REALM: Retrieval-Augmented Language Model Pre-Training 模型名称&#xff1a;Retrieval-Augmented Language Model pre-training (REALM) 本文是2020年ICML论文&#xff0c;作者来自…...

java的json解析

import com.alibaba.fastjson.*; public class JsonParser { public static void main(String[] args) { String jsonStr "{\"name\":\"John\", \"age\":30}"; // JSON字符串示例 // 将JSON字符串转换为JSONObject对象 JSONObje…...

Spring事务失效的几种情况

Spring事务失效的几种情况 1、未被Spring管理的类中的方法 这种情况是指&#xff1a;没有在类上添加Service、Repository、Component等注解将类交由Spring管理&#xff0c;然后该类中还有加上了Transactional注解 例如&#xff1a; Service //如果没有添加Service这个注解…...

filter的用法与使用场景:筛选数据

//this.allCollectorList:后台给定的所有可供选择数据 //this.collectorData:目前已经存在选中列表中的数据//目前已经存在选中列表中的数据id getSelIdList() {let eIdList = []this.collectorData.forEach(row => {eIdList.push(row.id)})return eIdList },//在中的数据…...

ClickHouse(18)ClickHouse集成ODBC表引擎详细解析

文章目录 创建表用法示例资料分享参考文章 ODBC集成表引擎使得ClickHouse可以通过ODBC方式连接到外部数据库. 为了安全地实现 ODBC 连接&#xff0c;ClickHouse 使用了一个独立程序 clickhouse-odbc-bridge. 如果ODBC驱动程序是直接从 clickhouse-server中加载的&#xff0c;那…...

网络攻击(一)--安全渗透简介

1. 安全渗透概述 目标 了解渗透测试的基本概念了解渗透测试从业人员的注意事项 1.1. 写在前面的话 在了解渗透测试之前&#xff0c;我们先看看&#xff0c;信息安全相关的法律是怎么样的 中华人民共和国网络安全法 《中华人民共和国网络安全法》由全国人民代表大会常务委员会…...

视频号小店资金需要多少?

我是电商珠珠 视频号团队于22年7月发展了自己的电商平台-视频号小店&#xff0c;相比于抖音电商来讲&#xff0c;可以有效的将公域流量转化为私域&#xff0c;对于商家来说&#xff0c;是一件利好的事情。 可以有效的提高客户的黏性&#xff0c;增加店铺回头客。 有很多想要…...

机器学习项目精选 第一期:超完整数据科学资料合集

大噶吼&#xff0c;不说废话&#xff0c;分享一波我最近看过并觉得非常硬核的资源&#xff0c;包括Python、机器学习、深度学习、大模型等等。 1、超完整数据科学资料合集 地址&#xff1a;https://github.com/krishnaik06/The-Grand-Complete-Data-Science-Materials Pytho…...

档案数字化管理可以提供什么服务?

档案数字化管理提供了便捷、高效和安全的档案管理服务&#xff0c;帮助组织更好地管理和利用自己的档案资源。 具体来说&#xff0c;专久智能档案数字化管理可以提供以下服务&#xff1a; 1. 档案扫描和数字化&#xff1a;将纸质档案通过扫描仪转换为数字格式&#xff0c;包括文…...

第一周:AI产品经理跳槽准备工作

一、筛选意向行业 因素1:行业发展情况 1. 行业发展情况和政策 待补充 2. AI人才市场情况 报告下载:待补充 2023年2⽉,ChatGPT爆⽕在脉脉引发各界搜索和热议,当⽉,“AIGC”、“⼈⼯智能”、“ChatGPT”、“⼤模型”等相关词汇搜索指数达到459.31,同⽐增⻓超5.4倍,内…...

基于核心素养高中物理“深度学习”策略及其教学研究课题论证设计方案

目录 一、课题的提出及意义 二、课题的核心概念及其界定...

通过 Java 17、Spring Boot 3.2 构建 Web API 应用程序

本心、输入输出、结果 文章目录 通过 Java 17、Spring Boot 3.2 构建 Web API 应用程序前言Spring Boot 3.2 更新了哪些内容Java 17 新特性构建步骤花有重开日,人无再少年实践是检验真理的唯一标准通过 Java 17、Spring Boot 3.2 构建 Web API 应用程序 编辑:简简单单 Online…...

go原生http开发简易blog(一)项目简介与搭建

文章目录 一、项目简介二、项目搭建前置知识三、首页- - -前端文件与后端结构体定义四、配置文件加载五、构造假数据- - -显示首页内容 代码地址&#xff1a;https://gitee.com/lymgoforIT/goblog 一、项目简介 使用Go原生http开发一个简易的博客系统&#xff0c;包含一下功能…...

[足式机器人]Part4 南科大高等机器人控制课 Ch09 Dynamics of Open Chains

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;CLEAR_LAB 笔者带更新-运动学 课程主讲教师&#xff1a; Prof. Wei Zhang 南科大高等机器人控制课 Ch09 Dynamics of Open Chains 1. Introduction1.1 From Single Rigid Body to Open Chains1.2 Preview of Open-Chain …...

概率论复习

第一章&#xff1a;随机概率及其概率 A和B相容就是 AB 空集 全概率公式与贝叶斯公式&#xff1a; 伯努利求概率&#xff1a; 第二章&#xff1a;一维随机变量及其分布&#xff1a; 离散型随机变量求分布律&#xff1a; 利用常规离散性分布求概率&#xff1a; 连续性随机变量…...

构建多链资产追踪器:Node.js与React实现链上资产聚合与估值

1. 项目概述&#xff1a;一个链上资产追踪器的诞生最近在整理自己的数字资产时&#xff0c;发现了一个挺普遍但有点烦人的问题&#xff1a;当你在不同的区块链网络&#xff08;比如以太坊、BSC、Polygon&#xff09;上持有多种代币&#xff08;Token&#xff09;和NFT时&#x…...

Chrome扩展开发实战:打造浏览器侧边栏ChatGPT助手

1. 项目概述&#xff1a;一个让ChatGPT常驻浏览器侧边栏的利器如果你和我一样&#xff0c;每天的工作和学习都离不开浏览器&#xff0c;并且频繁地与ChatGPT对话来获取灵感、润色文案或者调试代码&#xff0c;那么你肯定对在无数个标签页之间来回切换感到厌烦。每次都要打开一个…...

西门子PLC通信必备:手把手教你用SCL编写Modbus RTU CRC校验功能块

西门子PLC通信实战&#xff1a;SCL实现Modbus RTU CRC校验的工程化解决方案 在工业自动化领域&#xff0c;可靠的数据通信如同设备的神经系统。当两台PLC需要通过RS485接口交换温度传感器读数时&#xff0c;Modbus RTU协议因其简洁高效成为首选。但许多工程师在调试阶段都会遇到…...

从零构建现代化Web控制面板:安全架构与实时监控实践

1. 项目概述&#xff1a;一个为开发者设计的现代化控制面板最近在GitHub上看到一个挺有意思的项目&#xff0c;叫clawpanel&#xff0c;作者是kweephyo-pmt。光看名字&#xff0c;你可能会联想到“爪子”和“面板”&#xff0c;感觉像是个带点攻击性或工具属性的管理界面。实际…...

【HarmonyOS 6.1 全场景实战】《灵犀厨房》之【营养分析引擎】计算个性化卡路里建议:给《灵犀厨房》装上“营养大脑”

【营养分析引擎】计算个性化卡路里建议&#xff1a;给《灵犀厨房》装上“营养大脑” 摘要&#xff1a;从“爱吃什么”到“该吃什么”&#xff0c;是《灵犀厨房》进化的关键一步。上一篇我们刚打通了 Health Kit 数据&#xff0c;今天&#xff0c;我们就要基于 Mifflin-St Jeor …...

Wand-Enhancer终极指南:免费解锁WeMod专业功能的完整解决方案

Wand-Enhancer终极指南&#xff1a;免费解锁WeMod专业功能的完整解决方案 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer 还在为WeMod专业版的高昂订阅费…...

品牌声音技能化:从模糊概念到可执行AI内容策略

1. 项目概述&#xff1a;品牌声音的“技能化”构建最近在和一些做品牌营销、内容运营的朋友聊天&#xff0c;发现一个挺普遍的现象&#xff1a;大家手里都有一堆品牌手册、VI规范&#xff0c;但一到具体执行&#xff0c;比如写一篇公众号推文、拍一条短视频&#xff0c;或者回复…...

MCP服务器开发指南:为AI助手构建安全可控的外部工具扩展

1. 项目概述&#xff1a;一个为AI助手赋能的MCP服务器最近在折腾AI应用开发的朋友&#xff0c;可能都绕不开一个词&#xff1a;MCP。全称是Model Context Protocol&#xff0c;你可以把它理解成一套标准化的“插件协议”。它让像Claude、Cursor这类AI助手&#xff0c;能够安全、…...

别再手动调色了!用Matlab bar3函数一键生成论文级渐变三维柱状图(附完整代码)

别再手动调色了&#xff01;用Matlab bar3函数一键生成论文级渐变三维柱状图&#xff08;附完整代码&#xff09; 科研图表的美观程度直接影响论文的第一印象&#xff0c;而三维柱状图在展示多维度数据时尤为常见。传统手动调整每个柱体的颜色、透明度、光照效果不仅耗时&#…...

Navis:开源项目标准化开发环境与工具链配置框架实践

1. 项目概述&#xff1a;一个为开发者打造的“导航星图”如果你和我一样&#xff0c;常年混迹在开源项目的海洋里&#xff0c;那么你一定对这种感觉不陌生&#xff1a;面对一个全新的、功能强大的开源工具&#xff0c;兴奋地克隆了仓库&#xff0c;然后……就卡在了第一步。REA…...