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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值