千家信息网

在Android中如何使用Flutter数据库

发表于:2025-01-20 作者:千家信息网编辑
千家信息网最后更新 2025年01月20日,这篇文章主要介绍了在Android中如何使用Flutter数据库,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。说明Flutter原生是
千家信息网最后更新 2025年01月20日在Android中如何使用Flutter数据库

这篇文章主要介绍了在Android中如何使用Flutter数据库,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

说明

Flutter原生是没有支持数据库操作的,它使用SQLlit插件来使应用具有使用数据库的能力。其实就是Flutter通过插件来与原生系统沟通,来进行数据库操作。

平台支持

  • FLutter的SQLite插件支持IOS,安卓,和MacOS平台

  • 如果要对Linux / Windows / DartVM进行支持请使用sqflite_common_ffi

  • 不支持web平台

  • 数据库操作在安卓或ios的后台执行

使用案例

notepad_sqflite 可以在iOS / Android / Windows / linux / Mac上运行的简单的记事本应用

简单使用

添加依赖

为了使用 SQLite 数据库,首先需要导入 sqflite 和 path 这两个 package

  • sqflite 提供了丰富的类和方法,以便你能便捷实用 SQLite 数据库。

  • path 提供了大量方法,以便你能正确的定义数据库在磁盘上的存储位置。

dependencies:  sqflite: ^1.3.0  path:版本号

使用

导入 sqflite.dart

import 'dart:async';import 'package:path/path.dart';import 'package:sqflite/sqflite.dart';

打开数据库
SQLite数据库就是文件系统中的文件。如果是相对路径,则该路径是getDatabasesPath()所获得的路径,该路径关联的是Android上的默认数据库目录和iOS上的documents目录。

var db = await openDatabase('my_db.db');

许多时候我们使用数据库时不需要手动关闭它,因为数据库会在程序关闭时被关闭。如果你想自动释放资源,可以使用如下方式:

await db.close();

执行原始的SQL查询

使用getDatabasesPath()获取数据库位置

使用 sqflite package 里的 getDatabasesPath 方法并配合 path package里的 join 方法定义数据库的路径。使用path包中的join方法是确保各个平台路径正确性的最佳实践。

var databasesPath = await getDatabasesPath();String path = join(databasesPath, 'demo.db');

打开数据库:

Database database = await openDatabase(path, version: 1,    onCreate: (Database db, int version) async {  // 创建数据库时创建表  await db.execute(      'CREATE TABLE Test (id INTEGER PRIMARY KEY, name TEXT, value INTEGER, num REAL)');});

增:

在事务中向表中插入几条数据

await database.transaction((txn) async {  int id1 = await txn.rawInsert(      'INSERT INTO Test(name, value, num) VALUES("some name", 1234, 456.789)');  print('inserted1: $id1');  int id2 = await txn.rawInsert(      'INSERT INTO Test(name, value, num) VALUES(?, ?, ?)',      ['another name', 12345678, 3.1416]);  print('inserted2: $id2');});

删:

删除表中的一条数据

count = await database    .rawDelete('DELETE FROM Test WHERE name = ?', ['another name']);

改:

修改表中的数据

int count = await database.rawUpdate('UPDATE Test SET name = ?, value = ? WHERE name = ?',    ['updated name', '9876', 'some name']);print('updated: $count');

查:

查询表中的数据

// Get the recordsList list = await database.rawQuery('SELECT * FROM Test');List expectedList = [  {'name': 'updated name', 'id': 1, 'value': 9876, 'num': 456.789},  {'name': 'another name', 'id': 2, 'value': 12345678, 'num': 3.1416}];print(list);print(expectedList);

查询表中存储数据的总条数 :

count = Sqflite.firstIntValue(await database.rawQuery('SELECT COUNT(*) FROM Test'));

关闭数据库:

await database.close();

删除数据库:

await deleteDatabase(path);

使用SQL助手

创建表中的字段及关联类

//字段final String tableTodo = 'todo';final String columnId = '_id';final String columnTitle = 'title';final String columnDone = 'done';//对应类class Todo {  int id;  String title;  bool done;  //把当前类中转换成Map,以供外部使用  Map toMap() {    var map = {      columnTitle: title,      columnDone: done == true ? 1 : 0    };    if (id != null) {      map[columnId] = id;    }    return map;  }  //无参构造  Todo();    //把map类型的数据转换成当前类对象的构造函数。  Todo.fromMap(Map map) {    id = map[columnId];    title = map[columnTitle];    done = map[columnDone] == 1;  }}

使用上面的类进行创建删除数据库以及数据的增删改查操作。

class TodoProvider {  Database db;  Future open(String path) async {    db = await openDatabase(path, version: 1,        onCreate: (Database db, int version) async {      await db.execute('''  create table $tableTodo (   $columnId integer primary key autoincrement,   $columnTitle text not null,  $columnDone integer not null)                        ''');    });  }  //向表中插入一条数据,如果已经插入过了,则替换之前的。  Future insert(Todo todo) async {    todo.id = await db.insert(tableTodo, todo.toMap(),conflictAlgorithm: ConflictAlgorithm.replace,);    return todo;  }  Future getTodo(int id) async {    List maps = await db.query(tableTodo,        columns: [columnId, columnDone, columnTitle],        where: '$columnId = ?',        whereArgs: [id]);    if (maps.length > 0) {      return Todo.fromMap(maps.first);    }    return null;  }  Future delete(int id) async {    return await db.delete(tableTodo, where: '$columnId = ?', whereArgs: [id]);  }  Future update(Todo todo) async {    return await db.update(tableTodo, todo.toMap(),        where: '$columnId = ?', whereArgs: [todo.id]);  }  Future close() async => db.close();}

"="查询表中的所有数据:

List> records = await db.query('my_table');

获取结果中的第一条数据:

Map mapRead = records.first;

上面查询结果的列表中Map为只读数据,修改此数据会抛出异常

mapRead['my_column'] = 1;// Crash... `mapRead` is read-only

创建map副本并修改其中的字段

// 根据上面的map创建一个map副本Map map = Map.from(mapRead);// 在内存中修改此副本中存储的字段值map['my_column'] = 1;

把查询出来的List< map>类型的数据转换成List< Todo>类型,这样我们就可以痛快的使用啦。

// Convert the List into a List.  return List.generate(maps.length, (i) {    return Todo(      id: maps[i][columnId],      title: maps[i][columnTitle],      done: maps[i][columnDown],    );  });

批处理

您可以使用批处理来避免dart与原生之间频繁的交互。

batch = db.batch();batch.insert('Test', {'name': 'item'});batch.update('Test', {'name': 'new_item'}, where: 'name = ?', whereArgs: ['item']);batch.delete('Test', where: 'name = ?', whereArgs: ['item']);results = await batch.commit();

获取每个操作的结果是需要成本的(插入的Id以及更新和删除的更改数)。如果您不关心操作的结果则可以执行如下操作关闭结果的响应

await batch.commit(noResult: true);

事务中使用批处理

在事务中进行批处理操作,当事务提交后才会提交批处理。

await database.transaction((txn) async {  var batch = txn.batch();    // ...    // commit but the actual commit will happen when the transaction is committed  // however the data is available in this transaction  await batch.commit();    //  ...});

批处理异常忽略

默认情况下批处理中一旦出现错误就会停止(未执行的语句则不会被执行了),你可以忽略错误,以便后续操作的继续执行。

await batch.commit(continueOnError: true);

关于表名和列名

通常情况下我们应该避免使用SQLite关键字来命名表名称和列名称。如:

"add","all","alter","and","as","autoincrement","between","case","check","collate",
"commit","constraint","create","default","deferrable","delete","distinct","drop",
"else","escape","except","exists","foreign","from","group","having","if","in","index",
"insert","intersect","into","is","isnull","join","limit","not","notnull","null","on",
"or","order","primary","references","select","set","table","then","to","transaction",
"union","unique","update","using","values","when","where"

支持的存储类型

  • 由于尚未对值进行有效性检查,因此请避免使用不受支持的类型。参见:

  • 不支持DateTime类型,可将它存储为int或String

  • 不支持bool类型,可存储为int类型 0:false,1:true

SQLite类型dart类型值范围
integerint从-2 ^ 63到2 ^ 63-1
realnum
textString
blobUint8List

感谢你能够认真阅读完这篇文章,希望小编分享的"在Android中如何使用Flutter数据库"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

0