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

这篇具有很好参考价值的文章主要介绍了Flutter数据库操作看这一篇就够了。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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 it
  Future<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 database
  Future<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 database
  Future<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 id
  Future<void> delete(int id) async {
    var db = await database;
    await db?.rawDelete('DELETE FROM timerdata WHERE id = ?', [id]);
  }

  //delete sql by title
  Future<void> deleteByTitle(String title) async {
    var db = await database;
    await db?.rawDelete('DELETE FROM timerdata WHERE title = ?', [title]);
  }

  //update database by id
  Future<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 title
  Future<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的数据,则会用新数据替换旧数据,否则直接插入新数据。

之前写的界面,数据用数据库保存后的效果如下图:
Flutter数据库操作看这一篇就够了文章来源地址https://www.toymoban.com/news/detail-462388.html

到了这里,关于Flutter数据库操作看这一篇就够了的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Redis数据库和SpringBoot的故事|这一篇就够了(超详细)

    🙈作者简介:练习时长两年半的Java up主 🙉个人主页:老茶icon 🙊 ps:点赞👍是免费的,却可以让写博客的作者开兴好久好久😎 📚系列专栏:Java全栈,计算机系列(火速更新中) 💭 格言:种一棵树最好的时间是十年前,其次是现在 🏡动动小手,点个关注不迷路,感谢宝

    2024年02月01日
    浏览(34)
  • 大数据超全面入门干货知识,看这一篇就够了!

    随着科技的飞速发展和互联网的普及,大数据已成为 21 世纪最炙手可热的话题之一。它像一面神秘的面纱,覆盖着现实世界,隐藏着无穷无尽的可能性。今天将带领大家一起揭开大数据这个未知世界的神秘面纱,带你了解大数据的概念、应用以及大数据相关组件。 大数据是

    2024年04月26日
    浏览(47)
  • 如何利用Python中的pymysql库来操作Mysql数据库,看这篇就够啦~

     为了使python连接上数据库,你需要一个驱动,这个驱动是用于与数据库交互的库,本文是向大家介绍了如何利用python中的pymysql库来操作mysql数据库。 1、什么是pymysql? pymysql是从python连接到mysql数据库服务器的接口, 简单理解就是,pymysql是python操作mysql数据库的三方模块,可

    2024年02月06日
    浏览(49)
  • Flutter开发进阶之并发操作数据库

    尽管 Flutter 本身不包含任何数据库功能,但可以使用各种第三方库和插件来在 Flutter 应用程序中实现数据库功能; 以下将使用sqflite作为例子,sqflite允许在 Flutter 应用程序中执行 SQL 查询,创建和管理数据库表,以及执行其他常见的数据库操作。 在将sqflite添加到Flutter项目的

    2024年01月17日
    浏览(33)
  • 【YOLO系列】基于YOLOv7模型的目标检测与实现——利用PASCALVOC数据集(超详细,看这一篇足矣)

    最近因为在公司实习,迷上了计算机视觉,对目标检测这一方向饶有兴趣。再加上yolov7的论文也才出了不久,笔者就想着带着学习的心态,搞一搞基于yolov7的目标检测的实现。同时笔者也是踩了无数的坑🕳,心态几近崩溃,前前后后搞了一个多星期才跑完,网上的资料零零碎

    2024年02月13日
    浏览(30)
  • 数据结构—顺序表(如果想知道顺序表的全部基础知识点,那么只看这一篇就足够了!)

            前言:学习完了C语言的基础知识点之后,我们就需要使用我们所学的知识来进一步对存储在内存中的数据进行操作,这时候我们就需要学习数据结构。而这篇文章为数据结构中顺序表的讲解。 ✨✨✨ 这里是秋刀鱼不做梦的BLOG ✨✨✨ 想要了解更多内容可以访问我的

    2024年04月13日
    浏览(39)
  • CSS基础——看这一篇就够了

    目录 一、CSS简介 1.CSS是什么? 2.CSS的作用 3.CSS的构成 二、CSS选择器 1.基础选择器 (1).标签选择器 (2)类选择器 (3)标签选择器 (4) 通配符选择器 2.复合选择器 (1)后代选择器(包含选择器) (2)子选择器 (3)并集选择器 (4)伪类选择器  三、基本属性 1.字体属性

    2024年02月09日
    浏览(47)
  • 精通线程池,看这一篇就够了

    当我们运用多线程技术处理任务时,需要不断通过new的方式创建线程,这样频繁创建和销毁线程,会造成cpu消耗过多。那么有没有什么办法 避免频繁创建线程 呢? 当然有,和我们以前学习过多连接池技术类似,线程池通过提前创建好线程保存在线程池中, 在任务要执行时取

    2023年04月17日
    浏览(75)
  • 超图(HyperGraph)学习,看这一篇就够了

    最近事多,好久没更新了,随便写写(Ctrl+V)点 一、超图定义 通常图论中的图,一条edge只能连接2个vertex,在超图中,不限量 如何理解呢,就用我正在做的KT问题来看:7道题目-7个顶点;4种概念-4条超边,其中第1,2,3题都是考察概念1的,则构建一个包含了这仨的超边,以此类

    2024年02月02日
    浏览(48)
  • 还不会二分查找?看这一篇就够了

    二分查找分为整数二分和浮点数二分,一般所说的二分查找都是指整数二分。 满足单调性的数组一定可以使用二分查找,但可以使用二分查找的数组不一定需要满足单调性。 不妨假设我们找到了条件 C 1 C_1 C 1 ​ ,它和它的 对立条件 C 2 C_2 C 2 ​ 能够将数组 a a a 一分为二,

    2024年01月19日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包