flutter开发实战-本地SQLite数据存储

flutter开发实战-本地SQLite数据库存储

正在编写一个需要持久化且查询大量本地设备数据的 app,可考虑采用数据库。相比于其他本地持久化方案来说,数据库能够提供更为迅速的插入、更新、查询功能。这里需要用到sqflite package 来使用 SQLite 数据库

预览图
在这里插入图片描述

一、引入sqflite

在工程的pubspec.yaml中引入插件

  # sqflite
  sqflite: ^2.2.8+4
    

二、使用sqflite

使用 sqflite 实现插入,读取,更新,删除数据。

  • 打开数据库
  Future<void> openDB(BuildContext context) async {
    // Open the database and store the reference.
    database = await 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'),
      // 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)',
        );
      },
      version: 1,
    );
  }
    
  • 插入一条记录
Future<void> insertDB(BuildContext context) async {
    dogId++;

    // Create a Dog and add it to the dogs table
    var fido = Dog(
      id: dogId,
      name: 'Fido',
      age: 35,
    );

    // Get a reference to the database.
    final 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',
      fido.toMap(),
      conflictAlgorithm: ConflictAlgorithm.replace,
    );
  }
    
  • 更新一条记录
  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],
    );
  }
    
  • 删除一条记录
  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: 'id = ?',
      // Pass the Dog's id as a whereArg to prevent SQL injection.
      whereArgs: [id],
    );
  }
    
  • 获取存储记录
  // A method that retrieves all the dogs from the dogs table.
  Future<List<Dog>> dogs() async {
    // Get a reference to the database.
    final db = await database;

    // Query the table for all the dogs.
    final List<Map<String, Object?>>? dogMaps = await db?.query('dogs');

    if (dogMaps != null && dogMaps.isNotEmpty) {
      // Convert the list of each dog's fields into a list of `Dog` objects.
      List<Dog> dogs = [];
      for(var dogMap in dogMaps) {
        // Dog dog = Dog(id: dogMap['id']??0, name: name, age: age)
        var id = dogMap['id'] as int;
        var name = dogMap['name'] as String;
        var age = dogMap['age'] as int;

        Dog dog = Dog(id: id, name: name, age: age);
        dogs.add(dog);
      }
      return dogs;
    }

    return [];
  }
    

完整代码如下

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/widgets.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

class SqliteDemoPage extends StatefulWidget {
  const SqliteDemoPage({super.key});

  @override
  State<SqliteDemoPage> createState() => _SqliteDemoPageState();
}

class _SqliteDemoPageState extends State<SqliteDemoPage> {
  Database? database;

  int dogId = 0;

  Future<void> openDB(BuildContext context) async {
    // Open the database and store the reference.
    database = await 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'),
      // 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)',
        );
      },
      version: 1,
    );
  }

  // A method that retrieves all the dogs from the dogs table.
  Future<List<Dog>> dogs() async {
    // Get a reference to the database.
    final db = await database;

    // Query the table for all the dogs.
    final List<Map<String, Object?>>? dogMaps = await db?.query('dogs');

    if (dogMaps != null && dogMaps.isNotEmpty) {
      // Convert the list of each dog's fields into a list of `Dog` objects.
      List<Dog> dogs = [];
      for(var dogMap in dogMaps) {
        // Dog dog = Dog(id: dogMap['id']??0, name: name, age: age)
        var id = dogMap['id'] as int;
        var name = dogMap['name'] as String;
        var age = dogMap['age'] as int;

        Dog dog = Dog(id: id, name: name, age: age);
        dogs.add(dog);
      }
      return dogs;
    }

    return [];
  }

  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],
    );
  }

  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: 'id = ?',
      // Pass the Dog's id as a whereArg to prevent SQL injection.
      whereArgs: [id],
    );
  }


  Future<void> insertDB(BuildContext context) async {
    dogId++;

    // Create a Dog and add it to the dogs table
    var fido = Dog(
      id: dogId,
      name: 'Fido',
      age: 35,
    );

    // Get a reference to the database.
    final 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',
      fido.toMap(),
      conflictAlgorithm: ConflictAlgorithm.replace,
    );
  }

  Future<void> getListFromDB(BuildContext context) async {
    List<Dog> list = await dogs();
    for(var dog in list) {
      print("dog info:${dog.toString()}");
    }
  }

  void updateDB(BuildContext context) {
    var dog = Dog(
      id: dogId,
      name: 'AFarah',
      age: 11,
    );
    updateDog(dog);
  }

  Future<void> deleteDB(BuildContext context) async {
    await deleteDog(dogId);
    dogId--;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('SqliteDemo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            const SizedBox(
              height: 20,
            ),
            TextButton(
              onPressed: () {
                openDB(context);
              },
              child: Container(
                height: 36,
                width: 200,
                color: Colors.lightGreen,
                alignment: Alignment.center,
                child: const Text(
                  'openDatabase',
                  style: TextStyle(fontSize: 12, color: Colors.white),
                ),
              ),
            ),
            const SizedBox(
              height: 20,
            ),
            TextButton(
              onPressed: () {
                insertDB(context);
              },
              child: Container(
                height: 36,
                width: 200,
                color: Colors.lightGreen,
                alignment: Alignment.center,
                child: const Text(
                  '插入一条dog记录',
                  style: TextStyle(fontSize: 12, color: Colors.white),
                ),
              ),
            ),
            const SizedBox(
              height: 20,
            ),
            TextButton(
              onPressed: () {
                getListFromDB(context);
              },
              child: Container(
                height: 36,
                width: 200,
                color: Colors.lightGreen,
                alignment: Alignment.center,
                child: const Text(
                  '获取记录列表',
                  style: TextStyle(fontSize: 12, color: Colors.white),
                ),
              ),
            ),
            const SizedBox(
              height: 20,
            ),
            TextButton(
              onPressed: () {
                updateDB(context);
              },
              child: Container(
                height: 36,
                width: 200,
                color: Colors.lightGreen,
                alignment: Alignment.center,
                child: const Text(
                  '更新一条记录',
                  style: TextStyle(fontSize: 12, color: Colors.white),
                ),
              ),
            ),
            const SizedBox(
              height: 20,
            ),
            TextButton(
              onPressed: () {
                deleteDB(context);
              },
              child: Container(
                height: 36,
                width: 200,
                color: Colors.lightGreen,
                alignment: Alignment.center,
                child: const Text(
                  '删除一条记录',
                  style: TextStyle(fontSize: 12, color: Colors.white),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class Dog {
  final int id;
  final String name;
  final int age;

  const Dog({
    required this.id,
    required this.name,
    required this.age,
  });

  // Convert a Dog into a Map. The keys must correspond to the names of the
  // columns in the database.
  Map<String, Object?> 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.
  @override
  String toString() {
    return 'Dog{id: $id, name: $name, age: $age}';
  }
}

    

三、小结

flutter开发实战-本地SQLite数据库存储

学习记录,每天不停进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/624154.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络工程师----第二十五天

计算机基础 第二章&#xff1a;物理层 物理层的功能&#xff1a;怎样在连接各种计算机的传输媒体上传输数据比特流&#xff0c;屏蔽不同传输媒体和通信手段的差异。 传输媒体接口的特性&#xff1a; 机械特性&#xff1a;接口所用接线器的形状和尺寸、引脚数目和排列、固定…

6. 神经网络的内积

目录 1. 准备知识 1.1 NumPy 的多维数组 1.2 矩阵乘法 1.2.1 矩阵乘法顺序 1.2.2 矩阵乘法范例 2. 神经网络的内积 2.1 使用场合 2.2 Python 实现 1. 准备知识 1.1 NumPy 的多维数组 大家应该对多维数组都很熟悉&#xff0c;我不再多言。在 NumPy 模块中&#xff0c;…

PXI/PXIe规格1553B总线测试模块

面向GJB5186测试专门开发的1553B总线适配卡&#xff0c;支持4Mbps和1Mbps总线速率。该产品提供2个双冗余1553B通道、1个测试专用通道、2个线缆测试通道。新一代的TM53x板卡除了支持耦合方式可编程、总线信号幅值可编程、共模电压注入、总线信号波形采集等功能外&#xff0c;又新…

添砖Java之路(其四)——面向对象的编程,类和对象

目录 前言&#xff1a; 面向对象的编程&#xff1a; this关键字&#xff1a; 构造方法&#xff1a; 前言&#xff1a; 其实中间我还有很多地方没有去讲&#xff0c;因为我觉得里面的很多东西和c/c差不太多&#xff0c;就比如逻辑运算&#xff0c;方法重载&#xff0c;以及数…

【数据结构】 二叉树的顺序结构——堆的实现

普通的二叉树是不适合用数组来存储的&#xff0c;因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储 。 一、堆的概念及结构 父节点比孩子结点大 是大堆 父节点比孩子结点小 是小堆 堆的性质 堆中某…

SpringBoot设置默认文件大小

1、问题发现 有个需求&#xff0c;上传文件的时候&#xff0c;发现提示了这个错误&#xff0c;看了一下意思是说&#xff0c;文件超过了1M。 看我们文件的大小&#xff1a; 发现确实是&#xff0c;文件超出了1M&#xff0c;查了一下资料&#xff0c;tomcat默认上传文件大小为1M…

2024龙年新版ui周易测算网站H5源码/在线起名网站源码/运势测算网站系统源码

更新日志 1、修复时间不能选择子时; 2、部分机型支付后不跳转; 3、新增后台支持按照时间、项目、进行订单筛选查询; 4、数据库新增测算结果的纳音、藏干、感情、性格分析; 5、微信支付支持https证书; 6、修复PC端扫码支付问题; 7、新增代理分销功能; 8、新增会员功能&a…

如何把小程序视频下载保存

在这个快节奏的数字时代&#xff0c;小程序已成为我们生活的一部分&#xff0c;而那些在小程序中流转的精彩视频&#xff0c;常常让我们驻足。想象一下&#xff0c;如果能够将这些瞬间的精彩捕捉下来&#xff0c;让它们不再只是屏幕上的一抹流光&#xff0c;而是成为你个人收藏…

Adobe Media Encoder ME v24.3.0 解锁版 (视频和音频编码渲染工具)

Adobe系列软件安装目录 一、Adobe Photoshop PS 25.6.0 解锁版 (最流行的图像设计软件) 二、Adobe Media Encoder ME v24.3.0 解锁版 (视频和音频编码渲染工具) 三、Adobe Premiere Pro v24.3.0 解锁版 (领先的视频编辑软件) 四、Adobe After Effects AE v24.3.0 解锁版 (视…

[算法][贪心算法][leetcode]2244. 完成所有任务需要的最少轮数

题目地址 https://leetcode.cn/problems/minimum-rounds-to-complete-all-tasks/description/ 错误解法&#xff08;暴力解法&#xff09; class Solution {public int minimumRounds(int[] tasks) {int ans 0;//先用一个hashmap记录每个key值出现的次数//判断他们是否能被2或…

Vue3实战笔记(21)—自定义404页面

文章目录 前言一、标题1二、通过守卫导航配置404总结 前言 一个精致的404页面对于网站的用户体验至关重要。404页面&#xff0c;也称为“未找到”页面&#xff0c;是在用户尝试访问网站中不存在或已删除的页面时显示的。 一、标题1 404都很熟悉了&#xff0c;vue3默认找不到界…

高校推免报名|基于SSM+vue的高校推免报名系统的设计与实现(源码+数据库+文档)

高校推免报名 目录 基于SSM&#xff0b;vue的高校推免报名的设计与实现 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2后台登录模块 5.2.1管理员功能模块 5.2.2考生功能模版 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八…

【数据结构】解密链表之旅(单链表篇)

前言 哈喽大家好&#xff0c;我是野生的编程萌新&#xff0c;首先感谢大家的观看。数据结构的学习者大多有这样的想法&#xff1a;数据结构很重要&#xff0c;一定要学好&#xff0c;但数据结构比较抽象&#xff0c;有些算法理解起来很困难&#xff0c;学的很累。我想让大家知道…

基于PHP+MySQL开发的 外卖点餐在线二合一小程序源码系统 附带源代码以及系统的部署教程

在移动互联网时代&#xff0c;外卖行业蓬勃发展&#xff0c;各大外卖平台竞争激烈。然而&#xff0c;传统的外卖平台存在诸多问题&#xff0c;如用户体验不佳、操作繁琐、系统性能低下等。罗峰给大家分享一款基于PHPMySQL的外卖点餐在线二合一小程序源码系统。该系统旨在为用户…

FullCalendar日历组件集成实战(3)

背景 有一些应用系统或应用功能&#xff0c;如日程管理、任务管理需要使用到日历组件。虽然Element Plus也提供了日历组件&#xff0c;但功能比较简单&#xff0c;用来做数据展现勉强可用。但如果需要进行复杂的数据展示&#xff0c;以及互动操作如通过点击添加事件&#xff0…

什么是工具? 从语言模型视角的综述

24年3月CMU和上海交大的论文“What Are Tools Anyway? A Survey from the Language Model Perspective”。 到底什么是工具&#xff1f; 接下来&#xff0c;工具在哪里以及如何帮助语言模型&#xff1f; 在综述中&#xff0c;对语言模型使用的外部程序工具进行了统一定义&…

Redis-分片集群存储及读取数据详解

文章目录 Redis分片集群是什么&#xff1f;Redis分片集群的存储及读取数据&#xff1f; 更多相关内容可查看 Redis分片集群是什么&#xff1f; Redis分片集群是一种分布式部署方式&#xff0c;通过将数据分散存储在多个Redis节点上&#xff0c;从而提高了系统的性能、扩展性和…

解密跨境电商ERP开发的5大常见问题及解决方案

跨境电商平台开发是一个充满挑战的领域&#xff0c;企业在此过程中常常面临着各种技术、管理和资源等方面的问题。下面是解析这些问题并提供解决方案的五大主要问题&#xff1a; 1. 集成难题&#xff1a; 在跨境电商平台开发中&#xff0c;一个最为常见的问题是集成不同系统和…

中国高分辨率国家土壤信息网格基本属性数据集(2010-2018)

中国高分辨率国家土壤信息网格基本属性数据集&#xff08;2010-2018&#xff09; 数据介绍 土壤是人类生存和发展的基础&#xff0c;多个联合国可持续发展目标&#xff08;SDGs&#xff09;与土壤资源利用和管理直接相关。然而&#xff0c;全球和我国现有土壤信息大多源于历史土…

酒厂做配送分销小程序商城的作用是什么

线上优势明显&#xff0c;酒厂零售批发需要多渠道进行&#xff0c;品牌宣传、酒水经营分销配送、会员管理以及拓展更多营收可能等&#xff0c;商家与客户都需要完善的体系触达对方。 运用【雨科】平台搭建酒厂商城&#xff0c;电脑手机网页端和微信小程序端&#xff0c;多渠道…