前言
欢迎阅读Flutter系列教程,本文讲解Flutter的数据持久化。主要分三块内容: 1.使用Sqlite 2.读写文件 3.存储键值对
Sqlite的使用
如果你的APP需要经常在本地存储查询大量数据,就选择数据库。通常使用数据库来进行数据的增删改查比其他数据持久化方案速度更快。Flutter 里面可以通过sqflite 插件来操作Sqlite 。
sqlite简介
如果你用过数据库,可以略过此部分,使用时留意一下代码语法就行。
实战
- 首先要添加依赖,在
pubspec.yaml 文件里添加,添加完以后下载一下。
dependencies:
flutter:
sdk: flutter
sqflite:
path:
- 引入库
import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
- 创建数据库模型
在创建数据库之前,先花几分钟对数据库要存储的信息建立一个对象。
class Device{
final String mac;
final String name;
final int ownerId;
Device({
required this.mac,
required this.name,
required this.ownerId,
});
Map<String, dynamic> toMap() {
return {
'mac': mac,
'name': name,
'ownerId': ownerId,
};
}
}
- 写一下建表语句
如下,当调用openDatabase 就新建了一个数据库链接。
当调用openDatabase 时,如果数据库不存在的话就会执行onCreate 回调函数,所以我们可以把建表语句放在onCreate 函数里。
final database = openDatabase(
join(await getDatabasesPath(), 'fridge_database.db'),
onCreate: (db, version) {
return db.execute(
'CREATE TABLE devices(mac TEXT PRIMARY KEY, name TEXT, ownerId INTEGER)',
);
},
version: 1,
);
- 插入
Future<void> insertDevice(Device device) async {
final db = await database;
await db.insert(
'devices',
device.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
- 查询
Future<List<Device>> devices() async {
final db = await database;
final List<Map<String, dynamic>> maps = await db.query('devices');
return List.generate(maps.length, (i) {
return Device(
mac: maps[i]['mac'],
name: maps[i]['name'],
ownerId: maps[i]['ownerId'],
);
});
}
- 改
如下代码,根据mac 修改设备信息
Future<void> updateDevice(Device device) async {
final db = await database;
await db.update(
'dogs',
device.toMap(),
where: 'mac = ?',
whereArgs: [device.mac],
);
}
- 删
根据mac 删除设备信息
Future<void> deleteDevice(String mac) async {
final db = await database;
await db.delete(
'devices',
where: 'mac = ?',
whereArgs: [mac],
);
}
文件读写
添加依赖:
path_provider:
文件系统分为应用目录和临时目录,在安卓里分别对应AppData 和getCacheDir() ,ios对应NSDocumentDirectory 和 NSCachesDirectory 。
临时目录随时可能被系统删除,应用目录只有在系统写在app时才会删除。
下面的代码获取app目录
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
然后根据app可以拼接成完整的文件目录,根据目录返回File 对象
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/counter.txt');
}
此时就可以使用这个File 对象进行文件读写了
Future<File> writeCounter(int counter) async {
final file = await _localFile;
return file.writeAsString('$counter');
}
Future<int> readCounter() async {
try {
final file = await _localFile;
final contents = await file.readAsString();
return int.parse(contents);
} catch (e) {
return 0;
}
}
此处读写的文件需要root 才能查看哦!
键值对
依然添加依赖
shared_preferences:
对应安卓里面的SharedPreferences iso的NSUserDefaults ,用来存储少量的键值对。
写:
final prefs = await SharedPreferences.getInstance();
prefs.setInt('counter', counter);
final counter = prefs.getInt('counter') ?? 0;
prefs.remove('counter');
注意:
- 仅支持
int, double, bool, string, and stringList. - 不要存大量数据
|