欢迎阅读Flutter系列教程,本文讲解Flutter的数据持久化。主要分三块内容:
1.使用Sqlite
2.读写文件
3.存储键值对
如果你的APP需要经常在本地存储查询大量数据,就选择数据库。通常使用数据库来进行数据的增删改查比其他数据持久化方案速度更快。Flutter
里面可以通过sqflite
插件来操作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');//查询devices表,此时返回的时List类型,元素为Map类型
return List.generate(maps.length, (i) { //转换成Device类型
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(
'devices',
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.