Flutter 陈航 25-持久化 文件 SP 数据库 sqflite
目录
25 | 本地存储与数据库的使用
Flutter 提供了三种数据持久化方法,即文件、SharedPreferences 与数据库。
文件
需要引入 path_provider 库
Flutter 提供了两种文件存储的目录:
- 临时目录:可以随时清除,在 Android 上对应着
getCacheDir
返回的值 - 文档目录:只有在删除应用程序时才会被清除,在 Android 上对应着
AppData
目录
void testFile() async {
// 文件读写是耗时操作,需要在异步环境下进行
Directory directory = await getApplicationDocumentsDirectory();
String path = directory.path;
flog(path); // /data/user/0/com.bqt.flutter.flutter_app_test/app_flutter
File file = File('$path/content.txt'); // 创建文件
List<String> formats = ['bqt ', yyyy, '-', mm, '-', dd, ' ', HH, ':', nn, ':', ss, '\n'];
String content = formatDate(DateTime.now(), formats);
file.writeAsString(content, mode: FileMode.append); // 将字符串写入文件
String text = await file.readAsString(); // 从文件读出字符串
flog(text);
}
除了字符串读写之外,Flutter 还提供了二进制流的读写能力,可以支持图片、压缩包等二进制文件的读写。
SharedPreferences
需要引入 shared_preferences 库
SharedPreferences 会以原生平台相关的机制,为简单的键值对数据提供持久化存储,即在 iOS 上使用 NSUserDefaults
,在 Android 使用 SharedPreferences
。
SharedPreferences 只能存储基本类型的数据,比如 int、double、bool 和 string。
void testSP() async {
// 由于涉及到耗时的文件读写,需要在异步环境下进行
SharedPreferences sp = await SharedPreferences.getInstance();
int counter = (sp.getInt('counter') ?? 0);
sp.setInt('counter', ++counter);
flog("${sp.getInt('counter')}");
}
注意:setter 方法会同步更新内存中的键值对,然后将数据保存至磁盘。
数据库 sqflite
需要引入 sqflite 库
SharedPrefernces 只适用于持久化少量数据的场景,如果需要持久化大量格式化后的数据,并且这些数据还会以较高的频率更新,通常会选用 sqlite
数据库。
dbDemo() async {
// 创建数据库
String createSql = "CREATE TABLE students(id TEXT PRIMARY KEY, name TEXT, score INTEGER)";
Future<Database> database = openDatabase(
// join 方法需要手动导包 import 'package:path/path.dart';
join(await getDatabasesPath(), 'students_database.db'),
onCreate: (db, version) => db.execute(createSql),
onUpgrade: (db, oldVersion, newVersion) => flog("old:$oldVersion, new:$newVersion"),
version: 1,
);
Database db = await database;
await db.insert(
'students',
HashMap(), // 插入数据
conflictAlgorithm: ConflictAlgorithm.replace, // 插入冲突策略:新的替换旧的
);
List<Map<String, dynamic>> maps = await db.query('students'); // 批量查询数据
db.close(); // 释放数据库资源
}
- 使用
join
方法对两段地址进行拼接时,会使用操作系统的路径分隔符 - 调用
openDatabase
创建数据库时传入的 version,和在onCreate
中回调的 version 是相等的 - 数据库只会创建一次,所以
onCreate
方法在应用从安装到卸载的生命周期中,只会执行一次 - 如果想对数据库的存储字段进行改动,可以根据
onUpgrade
中的 oldVersion 和 newVersion 确定升级策略- oldVersion 代表用户手机上的数据库版本
- newVersion 代表当前版本的数据库版本
- 用户的升级顺序并不总是连续的,因此需要在
onUpgrade
中制定合适的升级方案
- 插入冲突策略:如果同样的对象被插入两次,则后者替换前者
- 查询的时候可以采用批量读的方式,也可以指定查询规则读特定对象
除了基础的数据库读写操作之外,sqlite 还提供了更新、删除以及事务等高级特性,这与原生 Android、iOS 上的 SQLite 或是 MySQL 并无不同。
2023-3-9
本文来自博客园,作者:白乾涛,转载请注明原文链接:https://www.cnblogs.com/baiqiantao/p/17196833.html