Flutter数据库操作看这一篇就够了

news/2025/1/15 8:32:06/

文章目录

  • Flutter常用数据库操作库
  • 最常用的sqflite介绍
    • 简介
    • 举例
  • 依赖sqflite,单例模式封装一个sqlite操作类
  • 说明
    • initDb说明
    • conflictAlgorithm说明

Flutter常用数据库操作库

Flutter是一种跨平台的移动应用程序开发框架,支持使用多种类型的数据库进行数据存储和管理。Flutter中使用数据库通常需要依赖第三方库来实现,以下是一些常用的Flutter数据库库:

  • sqflite:是一个SQLite数据库的Flutter插件,提供了类似于Android中SQLite的API接口,支持基本的CRUD操作。
  • firebase_database:是谷歌提供的一种实时的NoSQL数据库,可用于Flutter应用程序的数据存储和同步。
  • hive:是一种快速、轻量级的键值对数据库,具有高性能和低延迟的特点,适用于Flutter应用程序中的本地数据存储。

最常用的sqflite介绍

简介

sqflite是一个SQLite数据库的Flutter插件,提供了类似于Android中SQLite的API接口,支持基本的CRUD操作。它是Flutter中使用最广泛的本地数据库库之一,可用于存储应用程序的本地数据。sqflite具有轻量级、高性能和易于使用的特点,适合于小型应用程序或需要简单本地数据存储的应用程序。

举例

下面是一个使用sqflite库的示例代码,演示如何在Flutter应用程序中创建和使用SQLite数据库:

  1. 添加sqflite库的依赖:

在Flutter项目的pubspec.yaml文件中添加sqflite库的依赖:

dependencies:sqflite: ^2.2.8+4
  1. 创建数据库:

在Flutter应用程序中创建一个数据库示例,可以通过执行以下代码来创建一个名为my_database.db的SQLite数据库:

import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';class MyDatabase {static final MyDatabase _instance = MyDatabase._internal();factory MyDatabase() => _instance;static Database _database;MyDatabase._internal();Future<Database> get database async {if (_database != null) return _database;_database = await _initDatabase();return _database;}Future<Database> _initDatabase() async {final dbPath = await getDatabasesPath();final path = join(dbPath, 'my_database.db');return await openDatabase(path,version: 1,onCreate: (db, version) async {await db.execute('CREATE TABLE users(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)',);},);}
}

在上述代码中,我们使用了sqflite库中的openDatabase方法来创建数据库并指定数据库文件路径。我们还提供了一个onCreate回调函数,在创建数据库时执行一些初始化操作,例如创建表等。

  1. 插入数据:

下面是一个示例代码,演示如何向数据库中插入一条数据:

final db = await MyDatabase().database;
await db.insert('users',{'name': 'John'},conflictAlgorithm: ConflictAlgorithm.replace,
);

在上述代码中,我们首先获取了一个数据库实例,然后使用insert方法向名为users的表中插入一条数据。我们将数据存储为一个Map对象,其中键为列名,值为要插入的值。如果表中已经有相同主键的记录,我们使用conflictAlgorithm参数指定了冲突处理策略,这里使用了ConflictAlgorithm.replace,表示用新数据替换旧数据。

  1. 查询数据:

下面是一个示例代码,演示如何从数据库中查询数据:

final db = await MyDatabase().database;
final List<Map<String, dynamic>> users = await db.query('users');

在上述代码中,我们首先获取了一个数据库实例,然后使用query方法查询名为users的表中的所有数据。查询结果将返回一个包含多个Map对象的列表,其中每个Map对象表示一条记录,键为列名,值为对应的值。

  1. 更新数据:

下面是一个示例代码,演示如何更新数据库中的数据:

final db = await MyDatabase().database;
await db.update('users',{'name': 'Mary'},where: 'id = ?',whereArgs: [1],
);

在上述代码中,我们首先获取了一个数据库实例,然后使用update方法更新名为users的表中的一条数据。我们使用where参数指定了要更新的记录的条件,这里表示id为1,使用whereArgs参数指定了条件中的参数值。我们将要更新的数据存储为一个Map对象,其中键为列名,值为要更新的值。

  1. 删除数据:

下面是一个示例代码,演示如何从数据库中删除数据:

final db = await MyDatabase().database;
await db.delete('users',where: 'id = ?',whereArgs: [1],
);

在上述代码中,我们首先获取了一个数据库实例,然后使用delete方法删除名为users的表中的一条数据。我们使用where参数指定了要删除的记录的条件,这里表示id为1,使用whereArgs参数指定了条件中的参数值。

依赖sqflite,单例模式封装一个sqlite操作类

import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:learning/model/task_model.dart';class DatabaseHelper {DatabaseHelper._(); //单例模式static final DatabaseHelper db = DatabaseHelper._();static Database? _database;Future<Database?> get database async {_database ??= await initDb();return _database;}//init database and open itFuture<Database> initDb() async {print("initDb");Directory documentDirectory = await getApplicationDocumentsDirectory();String path = join(documentDirectory.path, 'yytimer.db');print("initDb ${path}");Database db = await openDatabase(path, version: 1, onOpen: (db) async {// 等待表创建完成await db.execute('CREATE TABLE IF NOT EXISTS timerdata (id INTEGER PRIMARY KEY, title TEXT, sptime INTEGER, retime INTEGER, cycle INTEGER, setsgap INTEGER, groups INTEGER)');});return db;}//insert databaseFuture<int?> insert(Task task) async {print('insert data Saving Task...');final db = await database; // 确保database在上下文中定义try {var result = await db?.rawInsert('INSERT OR REPLACE INTO timerdata (id,title,sptime,retime, cycle,setsgap,groups) VALUES (?,?,?,?,?,?,?)',[task.id,task.title,task.sptime,task.retime,task.cycle,task.setsgap,task.groups]);print('insert data id timerdata saved! ${task.id}, ${task.title}, ${task.sptime}, ${task.retime},${task.cycle}, ${task.setsgap}, ${task.groups}');return result;} on DatabaseException catch (e) {print(e);return -1;}}//query databaseFuture<List<Task>> getAll() async {print('getAll database...');var db = await database;var query = await db?.query('timerdata', orderBy: 'id DESC');List<Task> tasks =query!.isNotEmpty ? query.map((t) => Task.fromMap(t)).toList() : [];print('getAll in database: ${tasks.length} , ${tasks[0].title},${tasks[1].title}');return tasks;}//delete sql by idFuture<void> delete(int id) async {var db = await database;await db?.rawDelete('DELETE FROM timerdata WHERE id = ?', [id]);}//delete sql by titleFuture<void> deleteByTitle(String title) async {var db = await database;await db?.rawDelete('DELETE FROM timerdata WHERE title = ?', [title]);}//update database by idFuture<void> updateDatabase(Task task) async {final db = await database;await db?.update('timerdata',task.toMap(),where: "id = ?",whereArgs: [task.id],conflictAlgorithm: ConflictAlgorithm.replace,);}//update database by titleFuture<void> updateDatabaseByTitle(Task task) async {final db = await database;await db?.update('timerdata',task.toMap(),where: "title = ?",whereArgs: [task.title],conflictAlgorithm: ConflictAlgorithm.replace,);}
}

在initDb()中,可以使用await db.execute()来等待数据库表的创建完成,避免在创建表之前使用数据库出现问题。
在insert()方法中,可以使用INSERT OR REPLACE语句来实现插入或更新操作,以避免插入重复数据。
在getAll()方法中,可以使用db!.query(‘timerdata’, orderBy: ‘id DESC’)来按照id倒序获取所有数据,这样可以避免获取数据后再排序的操作。
在updateDatabase()和updateDatabaseByTitle()方法中,可以使用update()方法的conflictAlgorithm参数来实现插入或更新操作,以避免更新重复数据的问题。

说明

initDb说明

onCreate是在第一次打开数据库时调用的回调函数,用于创建数据库表和初始化数据。在Dart的sqflite库中,onCreate回调函数的签名为(Database db, int version),其中db参数是打开的数据库对象,version参数是数据库的版本号。

在onCreate回调函数中,我们可以使用db.execute()方法来执行SQL语句,以创建表和初始化数据。例如,在以下代码中:

Database db = await openDatabase(path, version: 1, onCreate: (Database db, int version) async {await db.execute('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)');await db.execute('INSERT INTO users (name) VALUES ("Alice")');
});

我们创建了一个名为users的表,并插入了一条记录。具体来说,我们使用了CREATE TABLE IF NOT EXISTS语句来创建一个users表,该表有两个字段:id和name,其中id是主键,name是文本类型。然后,我们使用INSERT INTO语句向users表中插入一条记录,该记录的name字段为"Alice"``onCreate是在第一次打开数据库时调用的回调函数,用于创建数据库表和初始化数据。在Dart的sqflite库中,onCreate回调函数的签名为(Database db, int version),其中db参数是打开的数据库对象,version参数是数据库的版本号。

conflictAlgorithm说明

conflictAlgorithm是在数据插入或更新时发生冲突(例如违反唯一性约束)时的解决策略。在Dart的sqflite库中,有以下四种冲突解决策略:

  1. ConflictAlgorithm.rollback:回滚事务,放弃所有更改。
  2. ConflictAlgorithm.abort:放弃当前操作,但不回滚事务。
  3. ConflictAlgorithm.fail:放弃当前操作,但是不回滚事务,并抛出异常。
  4. ConflictAlgorithm.replace:替换旧数据,或者插入新数据,以解决冲突。

在代码中,ConflictAlgorithm.replace的作用是在插入或更新数据时,如果发生冲突,则用新数据替换旧数据。这种策略可以保证数据的唯一性,并且不会抛出异常。如果数据不存在,则直接插入新数据,如果数据已经存在,则用新数据替换旧数据。

例如,在上面的代码中,updateDatabase()updateDatabaseByTitle()方法中使用了conflictAlgorithm: ConflictAlgorithm.replace参数,以避免更新或插入重复数据。如果表中已经存在具有相同id或title的数据,则会用新数据替换旧数据,否则直接插入新数据。

之前写的界面,数据用数据库保存后的效果如下图:
在这里插入图片描述


http://www.ppmy.cn/news/87995.html

相关文章

基于Go开发PaaS平台2

Go开发PaaS平台核心功能 代码仓库地址GitHub - yunixiangfeng/gopaas 第7章 云原生 Go PaaS 平台路由管理功能开发&#xff0c;对外域名映射&#xff0c;动态设置域名 域名能够让我们的服务提供外网访问的能力&#xff0c;让公网也能够访问到集群内部的资源&#xff0c;是我…

python+vue高校网上跳蚤二手市场的设计与实现

商品信息是卖家供应用户必不可少的一个部分。在跳蚤市场发展的整个过程中&#xff0c;商品担负着最重要的角色。为满足如今日益复杂的管理需求&#xff0c;各类管理系统程序也在不断改进。本课题所设计的普通高校网上跳蚤市场&#xff0c;使用Django框架&#xff0c;Python语言…

OMA-AC-1

6 最小功能集 在其他环境中运行的应用程序通常使用安全元件作为增强系统安全性的手段。 因此&#xff0c;任何符合 Open Mobile API 的移动设备都应该提供对设备上所有 SE 的访问。 因此&#xff0c;传输 API 对于兼容 Open Mobile API 的设备是强制性的。 目前最常见的 SE 是…

Revit幕墙:这些命令在幕墙嵌板中的妙用及快速幕墙

一、Revit中这些命令在幕墙嵌板中的妙用 在我们做幕墙时&#xff0c;通常会有不同种类的幕墙&#xff0c;比如材质不同&#xff0c;颜色不同。这时我们就需要去选中嵌板进行替换新样式的嵌板。 1.通常我们在替换嵌板时都是通过Tab切换&#xff0c;然后选中嵌板。这样进行来回切…

华为开源自研AI框架昇思MindSpore应用案例:Pix2Pix实现图像转换

目录 一、环境准备1.进入ModelArts官网2.使用CodeLab体验Notebook实例 在实际应用场景中&#xff0c;由于训练数据集不足&#xff0c;所以很少有人会从头开始训练整个网络。普遍的做法是&#xff0c;在一个非常大的基础数据集上训练得到一个预训练模型&#xff0c;然后使用该模…

【算法题】2358. 分组的最大数量

插&#xff1a; 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家一起学习鸭~~~ 题目&#xff1a; 给你一个正整数数组 grades &#…

SSM_jsp游戏-账-号-装-备虚拟物品交易系统

开发语言&#xff1a;Java 框架&#xff1a;ssm 前端框架:jsp/Bootstrap JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat8 数据库工具&#xff1a;Navicat 开发软件&#xff1a;idea 支持eclipse 游戏账号交易系统主要是为了提高工作人员的工作效率和更方便快捷的满足用户…

企业级低代码开发,迈向企业数字化时代

当下&#xff0c;随着科技的快速发展&#xff0c;软件开发的成本不断降低&#xff0c;越来越多的人可以参与到软件开发的过程中。但是在这个过程中&#xff0c;我们也发现了一个问题&#xff0c;就是软件开发的成本越来越高。传统的开发模式需要投入大量人力物力&#xff0c;而…