首页 > 数据库 >Flutter中使用Sqflite封装数据库操作与更新管理

Flutter中使用Sqflite封装数据库操作与更新管理

时间:2024-09-22 13:19:47浏览次数:3  
标签:封装 Users 数据库 await db Sqflite email async Flutter

1. 简介

在Flutter中,sqflite 是一个强大的插件,用于SQLite数据库操作。我们可以通过封装sqflite库的数据库操作来使代码更清晰和模块化。本篇文章将介绍如何封装增删改查、数据库版本控制与更新的处理,以及如何将查询结果映射到实体类。

2. 初始化数据库与数据库封装

创建数据库及其表结构

首先,我们需要初始化数据库,并创建表。下面的代码展示了如何初始化数据库,并在数据库创建时,执行多张表的创建。

Future<Database> _initDatabase() async {
    final databasesPath = await getDatabasesPath();
    final path = join(databasesPath, 'myapp.db');

    return await openDatabase(path, version: 2, onCreate: (Database db, int version) async {
      await db.execute('''CREATE TABLE IF NOT EXISTS Users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT,
            age INTEGER
          )''');
    }, onUpgrade: (db, oldVersion, newVersion) {
      if (oldVersion < 2) {
        db.execute('ALTER TABLE Users ADD COLUMN email TEXT');
      }
    });
}

封装数据库操作(增删改查)

为了更方便地使用数据库操作,我们可以对数据库的增删改查进行封装。

Future<int> insertData(String tableName, Map<String, dynamic> values) async {
    final db = await database;
    return await db.insert(tableName, values);
}

Future<int> updateData(String table, Map<String, dynamic> values, String whereClause, List<dynamic> whereArgs) async {
    final db = await database;
    return await db.update(table, values, where: whereClause, whereArgs: whereArgs);
}

Future<int> deleteData(String table, String whereClause, List<dynamic> whereArgs) async {
    final db = await database;
    return await db.delete(table, where: whereClause, whereArgs: whereArgs);
}

Future<List<Map<String, dynamic>>> queryData(String table, {String? whereClause, List<dynamic>? whereArgs}) async {
    final db = await database;
    return await db.query(table, where: whereClause, whereArgs: whereArgs);
}

3. 数据库版本控制与更新

数据库结构变更处理

当我们需要修改数据库结构(比如添加字段、删除表或修改表结构)时,数据库的版本号需要增加,并在onUpgrade方法中处理结构变更。例如:

onUpgrade: (db, oldVersion, newVersion) {
  if (oldVersion < 2) {
    db.execute('ALTER TABLE Users ADD COLUMN email TEXT');
  }
  if (oldVersion < 3) {
    db.execute('ALTER TABLE Users ADD COLUMN phone TEXT');
  }
}

数据表字段变更的处理

在 sqflite 中,不能直接修改已经存在的表的字段名称(如将 mail 字段改为 email),因为 sqflite 不支持直接重命名字段的操作。需要通过创建一个新表并将数据迁移到新表中来实现这种修改字段的需求。

onUpgrade(db, oldVersion, newVersion) async {
  if (oldVersion < 2) {
    // 1. 创建新表,字段将 mail 改为 email
    await db.execute('''
      CREATE TABLE Users_New(
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT,
        email TEXT
      )
    ''');

    // 2. 将旧表的数据插入到新表中
    await db.execute('''
      INSERT INTO Users_New (id, name, email)
      SELECT id, name, mail AS email FROM Users
    ''');

    // 3. 删除旧表
    await db.execute('DROP TABLE IF EXISTS Users');

    // 4. 将新表重命名为旧表名
    await db.execute('ALTER TABLE Users_New RENAME TO Users');
  }
}

4. 数据查询与映射

将查询结果映射到实体类

查询操作的结果通常是一个Map<String, dynamic>的列表。我们可以将这些查询结果赋值给自定义的实体类。

class User {
  int id;
  String name;
  int age;
  String? email;

  User.fromMap(Map<String, dynamic> map)
      : id = map['id'],
        name = map['name'],
        age = map['age'],
        email = map['email'];
}

Future<User> getUserFromMap(Map<String, dynamic> map) async {
  return User.fromMap(map);
}

高效查询与赋值

在查询大量数据时,可以将查询结果封装成一个集合,并映射为实体类对象。

Future<List<User>> getUsers() async {
  final List<Map<String, dynamic>> maps = await myQuery('Users');

  return List.generate(maps.length, (i) {
    return User.fromMap(maps[i]);
  });
}

5. 总结与实践建议

通过对sqflite的封装,我们可以使数据库操作变得更加简洁高效,特别是在处理复杂的增删改查操作时。保持数据库版本的更新管理对于避免数据丢失和表结构冲突也至关重要。

标签:封装,Users,数据库,await,db,Sqflite,email,async,Flutter
From: https://blog.csdn.net/qq_52871405/article/details/142354308

相关文章

  • 软件测试笔记|web自动化测试|自动化测试中,模块封装有哪些?封装的目的是什么?
    在自动化测试中,常见的模块封装有以下几种:一、页面元素定位封装将页面上的各种元素定位方式(如通过ID、Name、XPath、CSS选择器等)进行封装,形成统一的元素定位方法。例如,可以创建一个函数,传入定位方式和定位表达式,返回定位到的元素对象。二、操作封装1.把对页面元素的常见......
  • flutter 占位widget
    在Flutter中,如果你需要返回一个空的Widget,可以使用以下几种常见的选择:1.SizedBox.shrink()SizedBox.shrink()是一个大小为0的Widget,非常适合用来返回一个不可见的占位符。returnSizedBox.shrink();这是最常见的方式,表示不占用任何空间的Widget。2.Container()空......
  • Java入门:09.Java中三大特性(封装、继承、多态)02
    2继承需要两个类才能实现继承的效果。比如:类A继承类BA类称为子类,衍生类,派生类B类称为父类,基类,超类继承的作用子类自动的拥有父类的所有属性和方法(父类编写,子类不需要再编写)。代码复用目前私有的属性和方法无法访问。多态的基础。继承语法先定义父......
  • gin的基础及其简单封装
    文章目录自我介绍gin的优势gin框架[官方文档链接](https://gin-gonic.com/zh-cn/docs/quickstart/"官方文档连接")持续化刷新界面安装可以用fresh来启动可以把gin框架来实现beego框架的封装gin框架的中间件路由gin框架返回自我介绍大家好,我是Gin。在Go语......
  • 使用 Flutter 3.19 更高效地开发
    我们已隆重推出全新的Flutter版本——Flutter3.19。此版本引入了专为Gemini设计的新DartSDK、一个能让开发者对Widget动画实现精细化控制的全新Widget,Impeller更新带来的渲染性能提升、有助于实现深层链接的工具和对WindowsArm64的支持,以及更多丰富功能!Flutter社......
  • 组件封装有哪些注意事项—面试常问优美回答
    组件封装有哪些注意事项—面试常问优美回答关键点及回答建议与代码案例组件设计原则关键点:高内聚低耦合、接口清晰、职责单一。回答建议:“在设计组件时,我遵循高内聚低耦合的原则,确保组件内部逻辑紧密相关,同时减少与其他组件的直接依赖。”“我注重定义清晰的接口,使得......
  • go的事务操作,封装try
    1、使用trypackagemainimport( "fmt" _"github.com/go-sql-driver/mysql" "gorm.io/driver/mysql" "gorm.io/gorm")varDb*gorm.DBtypeDade1struct{ Idint Dadestring Dadastring}//初始化数据库连接funcinit(......
  • VS(visual studio) C++ 封装dll,以及其隐式调用与显式调用(静态\动态)
    DLL介绍DLL(动态链接库,DynamicLinkLibrary)是一种可执行文件,它包含可以在其他程序中调用的函数和数据。他是Windows操作系统中的一个重要概念,用于代码共享和模块化。特点代码共享:多个程序可以同时使用同一个DLL文件,而不需要将其代码编译到每个程序中。这样可以节省磁盘空间和......
  • uniapp 封装请求方法
    目录uni.request()封装uni.showLoading()封装使用request() 方法uni.request()封装//request.jsconstBASE_URL='https://tea.qingnian8.com/api';//请求函数exportconstrequest=(option={})=>{ //解构并赋初始值 let{ url, data={}, ......
  • asp sql封装成函数
    <%'定义数据库连接字符串DimconnectionStringconnectionString="Provider=sqloledb;DataSource=你的数据库服务器;InitialCatalog=你的数据库名;UserId=你的用户名;Password=你的密码;"'定义数据库连接和命令对象Dimconn,cmd,rs'定义函数来执行SQL查询并返回记录集F......