flutter-文件储存与数据库储存

520 阅读4分钟

前言

即使是flutter中也无可避免的会使用一些数据缓存内容,虽然很多缓存框架有了,但是也不能满足我们日益增加的需求,总有一些使我们要接触的,下面就介绍一下常见的一些文件操作库

key-value形式持久化

数据持久化之shared_preferences 前面已经介绍了,这里面就不多介绍了

一款 key-value形式的持久化,就像iosNSUserDefaluts一样,使用起来很方便,但是局限性也很强,键值多了多人编写就很难管理,一般用于少量数据储存,例如:用户信息

文件储存

这里的文件储存,指的就是常见的目录+文件的方式,一般图片缓存就是这个模式的

文件储存需要用到 path_provider 和 dart的io模块,之前介绍 http的时候说了这个io库,它实际上主要就是做文件读写的,而 path_provider 主要用来获取android和ios目录的

///文件操作
//保存文件信息
saveFile() async {
  final file = await getFile("name.txt");
  //同步保存名字,结果返回路径 Future,可以await获取路径
  final res = await file.writeAsString("Marshal");
  //异步保存内容
  file.writeAsStringSync("Marshal");
}

//读取文件信息
readFile() async {
  final file = await getFile("name.txt");
  file.readAsString().then((str) {
    print('str');
    print(str);
  }).catchError((err) {
    //自己存放的文件一般只有不存在才能读取失败,或者文件异常
    //可以都当做没有处理,可以覆盖保存
    print('读取失败');
    print(err);
  });
}

Future<File> getFile(String fileName) async {
  //获取应用文件目录类似于Ios的NSDocumentDirectory和Android上的 AppData目录
  //为path_provider,其他文件操作都在io库
  final fileDirectory = await getApplicationDocumentsDirectory();
  //获取存储路径
  final filePath = fileDirectory.path;

  //文件相关操作都在 io库
  return File("$filePath/$fileName");
}

数据库

这里用用到的数据库就是sqlite,其为手机平台轻量级关系型数据库

这里简单介绍下关系型数据库非关系型数据库,可以根据自己的项目需求来选择

关系型数据库: 数据库各个表之间存在某种关联,这种关联能够保证数据唯一,不会存在一条数据多个表维护的情况,每个表都有每个表的意义,与非关系数据库不同的是,一般支持外键查询,减少了用户的操作,查询速度稍慢,常见的有:SQLite、Core Data,服务端的 oracle、mysql、sqlserver就不多说了

非关系型数据库: 数据库各个表之间没有明显的关联,(但不代表用户不能做成关联,只不过代价稍大,很多逻辑查跨表逻辑需要自己另写,且自己写逻辑的不一定有关系型数据库的快),没有外键查询相关,由于没有关联,查询速度相对较快,但是存在关系表需要自己复出更多的代码维护,常见的有:Realm、UnQLite

另外这个也需要了解上面的文件操作,毕竟数据库只是一个文件管理系统,基本的文件操作还是需要系统来处理的

使用的数据库三方库(案例):sqflite

///数据库操作
///这里只介绍简单的增删改查
//初始化数据库存储路径,这里在生成数据库文件,同时构建了一个默认表user,实际使用中,这两个是分开的
Future<Database> getDataBase() async {
    var databasesPath = await getDatabasesPath();
    var path = "${databasesPath}${sqflite_demo.db}";
    //构建数据库
    return openDatabase(path, version: 1,
        onCreate: (Database db, int version) async {
          //初次创建时走该方法,这里默认县创建一个表
          //创建一个表,id和name属性,其中id为主键,自增
          await db.execute("CREATE TABLE user (id INTEGER PRIMARY KEY, name TEXT)");
        });

    //构建数据库对象后,也可以创建其他表
    //创建一个表,id和name属性,其中id为主键,自增
    //await database.execute("CREATE TABLE user (id INTEGER PRIMARY KEY, name TEXT)");
}

//保存数据到user表
saveString() async {
  final db = await getDataBase('my_db');
  //写入字符串,transaction是一个事务,具备原子性、一致性、隔离性、持久性性质
  db.transaction((trx) {
    const textStr = 'marshal';
    //插入一个元素,两种方式
    //直接使用 sql语句
    trx.rawInsert(
        'INSERT INTO user(name) VALUES("$textStr")');
    //这下知道他们两个区别了吧
    //格式化插入,后面都采用格式化的了,相信也很容易明白
    trx.rawInsert(
        'INSERT INTO user(name) VALUES("?")', [textStr]);
    return Future(() => null);
  });
}

//检索数据
Future getInfo() async {
  final db = await getDataBase();
  //查询名字为 marshal的,如果没有 where那么就是user表所有
  db.rawQuery('SELECT * FROM user WHERE name=?', ['marshal']).then((List<Map> lists) {
    print('----------------$lists');
    var listSize = lists.length;
  });
  // db.query //通用查询可以自己点进去查询一下,只不过更具体话
}

//更新数据
updateInfo() async {
  final db = await getDataBase();
  //更新user表name为帅仔,当name为marshal的时候
  //如果没有where那么就是针对所有
  int count = await db.rawUpdate(
    'UPDATE user SET name=? WHERE name=?',
    ['帅仔', 'marshal']);
  //db.update //可以点进去看一下,类似
}

//删除数据
deleteInfo() async {
  final db = await getDataBase();
  //删除user表name为的那条数据,当name为marshal的时候
  //如果没有where那么就是删除该表所有数据,新手谨记
  final count = await db.rawDelete('DELETE FROM user WHERE user=?', ['marshal']);
  //db.delete //可以点进去看一下,类似
}