MST

星途 面试题库

面试题:Flutter中SQLite与数据模型的整合

假设你正在开发一个需要频繁进行本地数据存储与查询的Flutter应用,选用SQLite作为存储方式。请阐述如何将自定义的数据模型与SQLite进行整合,以实现高效的数据操作,同时说明如何处理事务来保证数据的一致性。
35.9万 热度难度
前端开发Flutter

知识考点

AI 面试

面试题答案

一键面试

自定义数据模型与SQLite整合

  1. 定义数据模型类:在Flutter中,首先定义代表要存储数据的类。例如,若要存储用户信息,可定义如下类:
class User {
  int? id;
  String name;
  int age;

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

  // 将对象转换为Map,用于插入数据库
  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'name': name,
      'age': age,
    };
  }

  // 从Map创建对象,用于从数据库查询结果转换
  factory User.fromMap(Map<String, dynamic> map) {
    return User(
      id: map['id'],
      name: map['name'],
      age: map['age'],
    );
  }
}
  1. 数据库操作类:创建一个专门用于数据库操作的类,管理SQLite数据库连接及相关操作。
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

class DatabaseHelper {
  static final DatabaseHelper instance = DatabaseHelper._init();
  static Database? _database;

  DatabaseHelper._init();

  Future<Database> get database async {
    if (_database != null) return _database!;
    _database = await _initDB('users.db');
    return _database!;
  }

  Future<Database> _initDB(String filePath) async {
    final dbPath = await getDatabasesPath();
    final path = join(dbPath, filePath);
    return await openDatabase(
      path,
      version: 1,
      onCreate: _createDB,
    );
  }

  Future<void> _createDB(Database db, int version) async {
    const idType = 'INTEGER PRIMARY KEY AUTOINCREMENT';
    const textType = 'TEXT NOT NULL';
    const intType = 'INTEGER NOT NULL';
    await db.execute('''
      CREATE TABLE users (
        id $idType,
        name $textType,
        age $intType
      )
    ''');
  }
}
  1. 数据操作方法:在数据库操作类中添加插入、查询、更新和删除方法。
// 插入数据
Future<int> insertUser(User user) async {
  final db = await instance.database;
  return await db.insert('users', user.toMap());
}

// 查询所有数据
Future<List<User>> queryAllUsers() async {
  final db = await instance.database;
  final maps = await db.query('users');
  return List.generate(maps.length, (i) {
    return User.fromMap(maps[i]);
  });
}

// 更新数据
Future<int> updateUser(User user) async {
  final db = await instance.database;
  return await db.update(
    'users',
    user.toMap(),
    where: 'id =?',
    whereArgs: [user.id],
  );
}

// 删除数据
Future<int> deleteUser(int id) async {
  final db = await instance.database;
  return await db.delete(
    'users',
    where: 'id =?',
    whereArgs: [id],
  );
}

处理事务保证数据一致性

  1. 事务操作:SQLite支持事务,在Flutter中可使用transaction方法来执行事务操作。例如,假设有一个复杂操作,需要同时插入多个用户并更新其中一个用户的信息,可使用事务保证数据一致性。
Future<void> complexOperation() async {
  final db = await instance.database;
  await db.transaction((txn) async {
    // 插入多个用户
    final user1 = User(name: 'Alice', age: 25);
    final user2 = User(name: 'Bob', age: 30);
    await txn.insert('users', user1.toMap());
    await txn.insert('users', user2.toMap());

    // 更新其中一个用户信息
    final updateUser = User(id: 1, name: 'Alice Updated', age: 26);
    await txn.update(
      'users',
      updateUser.toMap(),
      where: 'id =?',
      whereArgs: [updateUser.id],
    );
  });
}
  1. 异常处理:在事务操作中,若任何一步操作失败,事务会自动回滚,确保数据的一致性。可通过try - catch块捕获异常并进行处理。
Future<void> complexOperation() async {
  final db = await instance.database;
  try {
    await db.transaction((txn) async {
      // 插入多个用户
      final user1 = User(name: 'Alice', age: 25);
      final user2 = User(name: 'Bob', age: 30);
      await txn.insert('users', user1.toMap());
      await txn.insert('users', user2.toMap());

      // 更新其中一个用户信息
      final updateUser = User(id: 1, name: 'Alice Updated', age: 26);
      await txn.update(
        'users',
        updateUser.toMap(),
        where: 'id =?',
        whereArgs: [updateUser.id],
      );
    });
  } catch (e) {
    print('事务操作失败: $e');
  }
}