六、Flutter之数据库

Flutter中操作数据库可以通过sqflite来实现,支持事务和批量操作,支持在Android、iOS后台线程执行任务,详见文档 https://pub.dartlang.org/packages/sqflite;
另外可参考 https://www.jianshu.com/p/7ac3ce2bc0c6 ;
对应的demo地址 https://github.com/zhujian1989/flutter_study/blob/master/lib/widget/demo_database/data_page.dart
本文代码参考上面demo作了一些调整。

1、添加依赖

在demo中会用到路径等多个插件库,一并加载
在pubspec.yaml添加

dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  event_bus: ^1.0.1
  sqflite: ^1.1.0
  shared_preferences: ^0.5.1
  path_provider: ^0.5.0

dart文件中导入包

import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart';
import 'dart:io';

2、数据库的创建、打开

  //创建数据库
  Future _createNewDb(String dbName) async {
    //获取数据库文件路径
    var dbPath = await getDatabasesPath();
    print('dbPath:' + dbPath);

    String path = join(dbPath, dbName);

    if (await new Directory(dirname(path)).exists()) {
      await deleteDatabase(path);
    } else {
      try {
        await new Directory(dirname(path)).create(recursive: true);
      } catch (e) {
        print(e);
      }
    }
    return path;
  }

  _create() async {
    dbPath = await _createNewDb(dbName);
    Database db = await openDatabase(dbPath);

    await db.execute(sql_createTable);
    await db.close();
    setState(() {
      _result = '创建user.db成功,创建user_table成功';
    });
  }

  //打开数据库,获取数据库对象
  _open() async {
    if(null == dbPath){
      var path = await getDatabasesPath();
      dbPath = join(path, dbName);
      print('dbPath:' + dbPath);
    }
    return await openDatabase(dbPath);
  }

数据库的创建、打开,都需要先获取数据库文件的路径,获取到path之后Database db = await openDatabase(dbPath);获取数据库对象,注意数据库的操作全都是异步的,要用关键字await。

3、数据库的增删改查

  _add() async {
    Database db = await _open();

    String sql =
        "INSERT INTO user_table(username,pwd) VALUES('$username','$pwd')";
    //开启事务
    await db.transaction((txn) async {
      int id = await txn.rawInsert(sql);
    });
    await db.close();

    setState(() {
      _result = "插入username=$username,pwd=$pwd数据成功";
    });
  }

  _delete() async {
    Database db = await _open();

    //删除最近一条
    String sql = "DELETE FROM user_table where id in (select id from user_table order by id desc limit 1)";
    int count = await db.rawDelete(sql);

    await db.close();

    setState(() {
      if (count == 1) {
        _result = "删除成功,请查看";
      } else {
        _result = "删除0条数据或删除失败,请看log";
      }
    });
  }

  _update() async {
    Database db = await _open();
    String sql = "UPDATE user_table SET pwd = ? WHERE id = ?";
    int count = await db.rawUpdate(sql, ["654321", '1']);
    print(count);
    await db.close();
    setState(() {
      _result = "更新数据成功,请查看";
    });
  }

  //批量增、改、删数据
  _batch() async {
    Database db = await _open();
    var batch = db.batch();
    batch.insert("user_table", {"username": "batchName1"});
    batch.update("user_table", {"username": "batchName2"}, where: "username = ?",whereArgs: ["batchName1"]);
    batch.delete("user_table", where: "username = ?", whereArgs: ["Leon"]);
    //返回每个数据库操作的结果组成的数组 [6, 3, 0]:新增返回id=6,修改了3条数据,删除了0条数据
    var results = await batch.commit();
    await db.close();
    setState(() {
      _result = "批量增、改数据成功 "+results.toString();
    });

  }

  _queryNum() async {
    Database db = await _open();
    int count = Sqflite.firstIntValue(await db.rawQuery(sql_query_count));
    await db.close();
    setState(() {
      _result = "数据条数:$count";
    });
  }

  _query() async {
    Database db = await _open();
    List list = await db.rawQuery(sql_query);
    await db.close();
    setState(() {
      _result = "数据详情:$list";
    });
  }

上面的增加数据代码中开启了事务,可以进行批量插入,每次数据库操作结束都要记得关闭await db.close();
注意,当使用transaction对象访问数据时,不能再使用database对象访问数据库

await database.transaction((txn) async {
  await txn.execute("CREATE TABLE Test1 (id INTEGER PRIMARY KEY)");

  // 不能在transaction对象里面使用database对象,这会发生死锁
  // await database.execute("CREATE TABLE Test2 (id INTEGER PRIMARY KEY)");
});

支持批量操作,但是真正操作被执行是在事务被提交的时候,比如上面代码中的var results = await batch.commit();

后续待补充...

你可能感兴趣的:(六、Flutter之数据库)