Flutter 中文文档:用 SQLite 做数据持久化

编程入门 行业动态 更新时间:2024-10-04 21:18:23

Flutter <a href=https://www.elefans.com/category/jswz/34/1769975.html style=中文文档:用 SQLite 做数据持久化"/>

Flutter 中文文档:用 SQLite 做数据持久化

如果您正在编写一个需要持久化且查询大量本地设备数据的 app,可考虑采用数据库,而不是本地文件夹或关键值库。总的来说,相比于其他本地持久化方案来说,数据库能够提供更为迅速的插入、更新、查询功能。

Flutter应用程序中可以通过 sqflite package 来使用 SQLite 数据库。本文将通过使用 sqflite 来演示插入,读取,更新,删除各种狗狗的数据。

如果你对于 SQLite 和 SQL 的各种语句还不熟悉,请查看 SQLite 官方的教程,在查看本文之前需要掌握基本的SQL语句。

SQLite 官方的教程:/

步骤:

  1. 添加依赖

  2. 定义 Dog(狗) 数据模型;

  3. 打开数据库;

  4. 创建 dogs 数据表;

  5. 将一条 Dog 数据插入数据库;

  6. 查询所有狗狗的数据;

  7. 更新(修改)一条 Dog 的数据;

  8. 删除一条 Dog 的数据。

1. 添加依赖

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

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

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

dependencies:flutter:sdk: fluttersqflite:path:

2. 定义狗狗的数据模型

在你准备在新建的表里存储狗狗们的信息的的时候,你需要先定义这些数据。 例如,定义一个狗类时,每一条狗狗的数据将包含三个字段: 一个唯一的  id ; 名字  name ; 年龄  age
class Dog {final int id;final String name;final int age;Dog({this.id, this.name, this.age});
}
3. 打开数据库 在你准备读写数据库的数据之前,你要先打开这个数据库。 打开一个数据库有以下两个步骤:
  1. 使用  sqflite package 里的  getDatabasesPath 方法并配合  path package里的  path 方法定义数据库的路径。
  2. Open the database with the  openDatabase() function from  sqflite .
使用  sqflite package 里的  openDatabase 方法打开数据库。
// Open the database and store the reference.
final Future<Database> database = openDatabase(// Set the path to the database. Note: Using the `join` function from the// `path` package is best practice to ensure the path is correctly// constructed for each platform.join(await getDatabasesPath(), 'doggie_database.db'),
);
4. 创建 dogs 表 接下来,你需要创建一个表用以存储各种狗狗的信息。 在这个示例中,创建一个名为  dogs 数据库表,它定义了可以被存储的数据。 这样,每条  Dog 数据就包含了一个  id ,  name 和  age 。 因此,在  dogs 数据库表中将有三列,分别是  id ,  name 和  age
  1. id 是 Dart 的  int 类型,在数据表中是 SQLite 的  INTEGER 数据类型。 最佳实践是将  id 作为数据库表的主键,用以改善查询和修改的时间。
  2. name 是Dart的  String 类型,在数据表中是SQLite的  TEXT 数据类型。
  3. age 也是Dart的  int 类型,在数据表中是SQLite的  INTEGER 数据类型。
关于 SQLite 数据库能够存储的更多的数据类型信息请查阅官方的  SQLite Datatypes 文档:.html 。
final Future<Database> database = openDatabase(// Set the path to the database. join(await getDatabasesPath(), 'doggie_database.db'),// When the database is first created, create a table to store dogs.onCreate: (db, version) {// Run the CREATE TABLE statement on the database.return db.execute("CREATE TABLE dogs(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)",);},// Set the version. This executes the onCreate function and provides a// path to perform database upgrades and downgrades.version: 1,
);
5. 插入一条狗狗的数据 现在你已经准备好了一个数据库用于存储各种狗狗的信息数据,开始读写数据。 首先,在  dogs 数据表中插入一条  Dog 数据。 分以下两步:
  1. 把 Dog 转换成一个 Map 数据类型;

  2. 使用 insert() 方法把 Map 保存到 dogs 数据表中。

// Update the Dog class to include a `toMap` method.
class Dog {final int id;final String name;final int age;Dog({this.id, this.name, this.age});// Convert a Dog into a Map. The keys must correspond to the names of the // columns in the database.Map<String, dynamic> toMap() {return {'id': id,'name': name,'age': age,};}
}// Define a function that inserts dogs into the database
Future<void> insertDog(Dog dog) async {// Get a reference to the database.final Database db = await database;// Insert the Dog into the correct table. You might also specify the // `conflictAlgorithm` to use in case the same dog is inserted twice. // // In this case, replace any previous data.await db.insert('dogs',dog.toMap(),conflictAlgorithm: ConflictAlgorithm.replace,);
}// Create a Dog and add it to the dogs table.
final fido = Dog(id: 0, name: 'Fido', age: 35,
);await insertDog(fido);
6. 查询狗狗列表 现在已经有了一条  Dog 存储在数据库里。 你可以通过查询数据库,检索到一只狗狗的数据或者所有狗狗的数据。 分为以下两步:
  1. 调用 dogs 表对像的 query 方法。这将返回一个List <Map>

  2. 将 List<Map> 转换成 List<Dog> 数据类型。

// A method that retrieves all the dogs from the dogs table.
Future<List<Dog>> dogs() async {// Get a reference to the database.final Database db = await database;// Query the table for all The Dogs.final List<Map<String, dynamic>> maps = await db.query('dogs');// Convert the List<Map<String, dynamic> into a List<Dog>.return List.generate(maps.length, (i) {return Dog(id: maps[i]['id'],name: maps[i]['name'],age: maps[i]['age'],);});
}// Now, use the method above to retrieve all the dogs.
print(await dogs()); // Prints a list that include Fido.
7. 修改一条 Dog 数据
使用  sqflite package 中的  update() 方法,可以对已经插入到数据库中的数据进行修改(更新)。
Future<void> updateDog(Dog dog) async {// Get a reference to the database.final db = await database;// Update the given Dog.await db.update('dogs',dog.toMap(),// Ensure that the Dog has a matching id.where: "id = ?",// Pass the Dog's id as a whereArg to prevent SQL injection.whereArgs: [dog.id],);
}// Update Fido's age.
await updateDog(Dog(id: 0, name: 'Fido', age: 42,
));// Print the updated results.
print(await dogs()); // Prints Fido with age 42.

 请注意

使用 whereArgs 将参数传递给 where 语句。有助于防止 SQL 注入攻击。

这里不要使用字符串模板,比如: where: "id = ${dog.id}"

8. 删除一条 Dog 的数据
除了插入和修改狗狗们的数据,你还可以从数据库中删除狗狗的数据。 删除数据用到了  sqflite package 中的  delet e() 方法。 在这一小节,新建一个方法用来接收一个 id 并且删除数据库中与这个 id 匹配的那一条数据。 为了达到这个目的,你必须使用  where 语句限定哪一条才是被删除的数据。
Future<void> deleteDog(int id) async {// Get a reference to the database (获得数据库引用)final db = await database;// Remove the Dog from the Database.await db.delete('dogs',// Use a `where` clause to delete a specific dog (使用 `where` 语句删除指定的狗狗).where: "id = ?",// Pass the Dog's id as a whereArg to prevent SQL injection (通过 `whereArg` 将狗狗的 id 传递给 `delete` 方法,以防止 SQL 注入)whereArgs: [id],);
}
示例 运行示例需要以下几步:
  1. 创建一个新的 Flutter 工程;
  2. 将  sqfite 和  path 包添加到  pubspec.yaml 文件里;
  3. 将以下代码粘贴在  lib/db_test.dart 文件里(若无则新建,若有则覆盖);
  4. 运行  flutter run lib/db_test.dart
import 'dart:async';import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';void main() async {final database = openDatabase(// Set the path to the database. Note: Using the `join` function from the// `path` package is best practice to ensure the path is correctly// constructed for each platform.// 设置数据库的路径。注意:使用 `path` 包中的 `join` 方法是// 确保在多平台上路径都正确的最佳实践。join(await getDatabasesPath(), 'doggie_database.db'),// When the database is first created, create a table to store dogs.// 当数据库第一次被创建的时候,创建一个数据表,用以存储狗狗们的数据。onCreate: (db, version) {return db.execute("CREATE TABLE dogs(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)",);},// Set the version. This executes the onCreate function and provides a// path to perform database upgrades and downgrades.// 设置版本。它将执行 onCreate 方法,同时提供数据库升级和降级的路径。version: 1,);Future<void> insertDog(Dog dog) async {// Get a reference to the database (获得数据库引用)final Database db = await database;// Insert the Dog into the correct table. Also specify the// `conflictAlgorithm`. In this case, if the same dog is inserted// multiple times, it replaces the previous data.// 在正确的数据表里插入狗狗的数据。我们也要在这个操作中指定 `conflictAlgorithm` 策略。// 如果同样的狗狗数据被多次插入,后一次插入的数据将会覆盖之前的数据。await db.insert('dogs',dog.toMap(),conflictAlgorithm: ConflictAlgorithm.replace,);}Future<List<Dog>> dogs() async {// Get a reference to the database (获得数据库引用)final Database db = await database;// Query the table for all The Dogs (查询数据表,获取所有的狗狗们)final List<Map<String, dynamic>> maps = await db.query('dogs');// Convert the List<Map<String, dynamic> into a List<Dog> (将 List<Map<String, dynamic> 转换成 List<Dog> 数据类型)return List.generate(maps.length, (i) {return Dog(id: maps[i]['id'],name: maps[i]['name'],age: maps[i]['age'],);});}Future<void> updateDog(Dog dog) async {// Get a reference to the database (获得数据库引用)final db = await database;// Update the given Dog (修改给定的狗狗的数据)await db.update('dogs',dog.toMap(),// Ensure that the Dog has a matching id (确定给定的狗狗id是否匹配)where: "id = ?",// Pass the Dog's id as a whereArg to prevent SQL injection (通过 whereArg 传递狗狗的 id 可以防止 SQL 注入)whereArgs: [dog.id],);}Future<void> deleteDog(int id) async {// Get a reference to the database (获得数据库引用)final db = await database;// Remove the Dog from the database (将狗狗从数据库移除)await db.delete('dogs',// Use a `where` clause to delete a specific dog (使用 `where` 语句删除指定的狗狗)where: "id = ?",// Pass the Dog's id as a whereArg to prevent SQL injection (通过 `whereArg` 将狗狗的 id 传递给 `delete` 方法,以防止 SQL 注入)whereArgs: [id],);}var fido = Dog(id: 0,name: 'Fido',age: 35,);// Insert a dog into the database (在数据库插入一条狗狗的数据)await insertDog(fido);// Print the list of dogs (only Fido for now) [打印一个列表的狗狗们 (现在列表里只有一只叫 Fido 的狗狗)]print(await dogs());// Update Fido's age and save it to the database (修改数据库中 Fido 的年龄并且保存)fido = Dog(id: fido.id,name: fido.name,age: fido.age + 7,);await updateDog(fido);// Print Fido's updated information (打印 Fido 的修改后的信息)print(await dogs());// Delete Fido from the database (从数据库中删除 Fido)await deleteDog(fido.id);// Print the list of dogs (empty) [打印一个列表的狗狗们 (这里已经空了)]print(await dogs());
}class Dog {final int id;final String name;final int age;Dog({this.id, this.name, this.age});Map<String, dynamic> toMap() {return {'id': id,'name': name,'age': age,};}// Implement toString to make it easier to see information about// each dog when using the print statement.// 重写 toString 方法,以便使用 print 方法查看每个狗狗信息的时候能更清晰。@overrideString toString() {return 'Dog{id: $id, name: $name, age: $age}';}
}

更多推荐

Flutter 中文文档:用 SQLite 做数据持久化

本文发布于:2024-02-07 04:34:41,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1753557.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:中文   持久   文档   数据   Flutter

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!