当前位置: 首页 > 编程笔记 >

Flutter持久化存储之数据库存储(sqflite)详解

端木令
2023-03-14
本文向大家介绍Flutter持久化存储之数据库存储(sqflite)详解,包括了Flutter持久化存储之数据库存储(sqflite)详解的使用技巧和注意事项,需要的朋友参考一下

前言

数据库存储是我们常用的存储方式之一,对大批量数据有增、删、改、查操作需求时,我们就会想到使用数据库,Flutter中提供了一个sqflite插件供我们用于大量数据执行CRUD操作。本篇我们就来一起学习sqflite的使用。

sqflite是一款轻量级的关系型数据库,类似SQLite。

在Flutter平台我们使用sqflite库来同时支持Android 和iOS。

sqflite使用

引入插件

在pubspec.yaml文件中添加path_provider插件,最新版本为1.0.0,如下:

dependencies:
 flutter:
 sdk: flutter
 #sqflite插件
 sqflite: 1.0.0

然后命令行执行flutter packages get即可将插件下载到本地。

数据库操作方法介绍

1. 插入操作

插入数据操作有两个方法:

Future<int> rawInsert(String sql, [List<dynamic> arguments]);

Future<int> insert(String table, Map<String, dynamic> values,
 {String nullColumnHack, ConflictAlgorithm conflictAlgorithm});

rawInsert方法第一个参数为一条插入sql语句,可以使用?作为占位符,通过第二个参数填充数据。

insert方法第一个参数为操作的表名,第二个参数map中是想要添加的字段名和对应字段值。

2. 查询操作

查询操作同样实现了两个方法:

Future<List<Map<String, dynamic>>> query(String table,
 {bool distinct,
 List<String> columns,
 String where,
 List<dynamic> whereArgs,
 String groupBy,
 String having,
 String orderBy,
 int limit,
 int offset});
 
Future<List<Map<String, dynamic>>> rawQuery(String sql,
 [List<dynamic> arguments]);

query方法第一个参数为操作的表名,后边的可选参数依次表示是否去重、查询字段、WHERE子句(可使用?作为占位符)、WHERE子句占位符参数值、GROUP BY子句、HAVING子句、ORDER BY子句、查询的条数、查询的偏移位等。

rawQuery方法第一个参数为一条查询sql语句,可以使用?作为占位符,通过第二个参数填充数据。

3. 修改操作

修改操作同样实现了两个方法:

Future<int> rawUpdate(String sql, [List<dynamic> arguments]);

Future<int> update(String table, Map<String, dynamic> values,
 {String where,
 List<dynamic> whereArgs,
 ConflictAlgorithm conflictAlgorithm});

rawUpdate方法第一个参数为一条更新sql语句,可以使用?作为占位符,通过第二个参数填充数据。

update方法第一个参数为操作的表名,第二个参数为修改的字段和对应值,后边的可选参数依次表示WHERE子句(可使用?作为占位符)、WHERE子句占位符参数值、发生冲突时的操作算法(包括回滚、终止、忽略等等)。

4. 删除操作

修改操作同样实现了两个方法:

Future<int> rawDelete(String sql, [List<dynamic> arguments]);

Future<int> delete(String table, {String where, List<dynamic> whereArgs});

rawDelete方法第一个参数为一条删除sql语句,可以使用?作为占位符,通过第二个参数填充数据。

delete方法第一个参数为操作的表名,后边的可选参数依次表示WHERE子句(可使用?作为占位符)、WHERE子句占位符参数值。

举个栗子

我们以图书管理系统来举例。

首先,我们创建一个书籍类,包括书籍ID、书名、作者、价格、出版社等信息。

final String tableBook = 'book';
final String columnId = '_id';
final String columnName = 'name';
final String columnAuthor = 'author';
final String columnPrice = 'price';
final String columnPublishingHouse = 'publishingHouse';

class Book {
 int id;
 String name;
 String author;
 double price;
 String publishingHouse;
 
 Map<String, dynamic> toMap() {
 var map = <String, dynamic>{
 columnName: name,
 columnAuthor: author,
 columnPrice: price,
 columnPublishingHouse: publishingHouse
 };
 if (id != null) {
 map[columnId] = id;
 }
 return map;
 }

 Book();

 Book.fromMap(Map<String, dynamic> map) {
 id = map[columnId];
 name = map[columnName];
 author = map[columnAuthor];
 price = map[columnPrice];
 publishingHouse = map[columnPublishingHouse];
 }
}

其次,我们开始实现数据库相关操作:

1. 创建数据库文件和对应的表

// 获取数据库文件的存储路径
 var databasesPath = await getDatabasesPath();
 String path = join(databasesPath, 'demo.db');

//根据数据库文件路径和数据库版本号创建数据库表
 db = await openDatabase(path, version: 1,
 onCreate: (Database db, int version) async {
 await db.execute('''
  CREATE TABLE $tableBook (
  $columnId INTEGER PRIMARY KEY, 
  $columnName TEXT, 
  $columnAuthor TEXT, 
  $columnPrice REAL, 
  $columnPublishingHouse TEXT)
  ''');
 });

2. CRUD操作实现

 // 插入一条书籍数据
 Future<Book> insert(Book book) async {
 book.id = await db.insert(tableBook, book.toMap());
 return book;
 }

 // 查找所有书籍信息
 Future<List<Book>> queryAll() async {
 List<Map> maps = await db.query(tableBook, columns: [
 columnId,
 columnName,
 columnAuthor,
 columnPrice,
 columnPublishingHouse
 ]);

 if (maps == null || maps.length == 0) {
 return null;
 }

 List<Book> books = [];
 for (int i = 0; i < maps.length; i++) {
 books.add(Book.fromMap(maps[i]));
 }

 return books;
 }

 // 根据ID查找书籍信息
 Future<Book> getBook(int id) async {
 List<Map> maps = await db.query(tableBook,
 columns: [
  columnId,
  columnName,
  columnAuthor,
  columnPrice,
  columnPublishingHouse
 ],
 where: '$columnId = ?',
 whereArgs: [id]);
 if (maps.length > 0) {
 return Book.fromMap(maps.first);
 }
 return null;
 }

 // 根据ID删除书籍信息
 Future<int> delete(int id) async {
 return await db.delete(tableBook, where: '$columnId = ?', whereArgs: [id]);
 }

 // 更新书籍信息
 Future<int> update(Book book) async {
 return await db.update(tableBook, book.toMap(),
 where: '$columnId = ?', whereArgs: [book.id]);
 }

3. 关闭数据库

数据库对象使用完之后要在适当的时候关闭掉,可在helper类中实现以下方法。

Future close() async => db.close();

事务

sqflite同时支持事务,通过事务可以将多条原子操作放在一起执行,保证操作要么全部执行完成,要么都不执行。
比如有两条书籍数据必须全部插入书库中才算添加成功,则使用如下方法

 Future<bool> insertTwoBook(Book book1, Book book2) async {
 return await db.transaction((Transaction txn) async {
 book1.id = await db.insert(tableBook, book1.toMap());

 book2.id = await db.insert(tableBook, book2.toMap());

 print('book1.id = ${book1.id}, book2.id = ${book2.id}');
 return book1.id != null && book2.id != null;
 });
 }

写在最后

以上介绍了sqflite中我们常用的几个操作,有了sqflite我们就可以开发更丰富的应用程序,在开发实践中大家遇到任何问题都可以给我们发消息反馈,大家一起交流探讨共同进步。针对一些用户的反馈我们将在下一篇介绍Flutter的代码调试。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对小牛知识库的支持。

 类似资料:
  • 目的 配置 NFS 共享为 OpenShift 节点提供存储,并且配置 OpenShift 持久卷以绑定至数据库 Pod。 环境 openshift v3.11.16/kubernetes v1.11.0 步骤 配置 NFS 共享持久卷1. 登录到 NFS 服务器 # ssh nfs.example.com2. 创建 config-nfs.sh 脚本,内容如下 #!/usr/bin/sh exp

  • 主要内容:一、数据持久化,二、持久化的形式,三、源码分析,四、总结一、数据持久化 redis做为一种内存型数据库,做持久化,个人感觉略有鸡肋的意思。似乎有一种,别人有,自己不有也不行的感觉。以目前Redis主流的应用方式,如果仔细分析,基本上都是在内存中即可完成,对持久化没要求或者说不大。再举一个反例,如果内存中有几百G甚至更多的数据,真要是整体当机,恢复的时间基本就是灾难。 目前基本应用仍然是以关系型数据库或者其它数据库(如Hadoop,Mysql等)为持久化

  • 本平台是通过storageclass来动态创建PV。也就是说咱们依赖于storageclass,如果您的Kubernetes不支持相应的存储试,将无法非常方便的进行挂载。 目前暂不支持挂载多个PVC,或许以后会更新吧。 这里演示的是用的NFS进行演示,实际使用时可根据自己的需求配置相应的provisioner,其他配置是一样的不需要调整,只需要在“模版管理” 调整StorageClass和Pers

  • 本地持久化卷允许用户通过标准 PVC 接口以简单便携的方式访问本地存储。PV 中包含系统用于将 Pod 安排到正确节点的节点亲和性信息。 一旦配置了本地卷,外部静态配置器(provisioner)可用于帮助简化本地存储管理。请注意,本地存储配置器与大多数配置器不同,并且尚不支持动态配置。相反,它要求管理员预先配置每个节点上的本地卷,并且这些卷应该是: Filesystem volumeMode(默

  • 持久化存储的相关配置 这里使用的是NFS的方式进行持久化,如果您有自己的持久化方案可以不使用改方案。 $ kubectl apply -f install/kubernetes/storage/serviceaccount.yaml $ kubectl apply -f install/kubernetes/storage/rbac.yaml $ kubectl apply -f install/

  • 本平台是通过storageclass来动态创建PV。也就是说咱们依赖于storageclass,如果您的Kubernetes不支持相应的存储试,将无法非常方便的进行挂载。 目前暂不支持挂载多个PVC,或许以后会更新吧。 这里演示的是用的NFS进行演示,实际使用时可根据自己的需求配置相应的provisioner,其他配置是一样的不需要调整,只需要在“模版管理” 调整StorageClass和Pers