Flutter реляционная база данных (локальная)

Вопрос или проблема

Я хотел бы хранить данные в локальной базе данных, где у меня будут классы моделей с отношениями друг с другом, например:

class Member {
int id;
String name;
List<Documents> documents}

class Document {
int id;
String docType;
String path;
}

Я хотел бы хранить, обновлять и получать записи в базе данных с отношениями. Когда у меня есть участник с установленным списком документов, я хотел бы иметь функцию, которая сохраняет участника в его таблице и документы в их таблице (с внешними ключами)…

Может ли кто-нибудь подсказать, в каком направлении двигаться, какую технологию использовать? И указать на какую-нибудь документацию, примеры?

Ответ или решение

Для организации локальной базы данных в приложении Flutter с реляционными отношениями между моделями, такими как Member и Document, рекомендуется использовать SQLite в сочетании с пакетом sqflite. Этот пакет предоставляет удобный интерфейс для взаимодействия с базой данных SQLite, что делает его идеальным выбором для отслеживания связанных сущностей.

Способы реализации

  1. Подключение необходимых библиотек:
    Вам потребуется добавить следующие библиотеки в файл pubspec.yaml:

    dependencies:
     flutter:
       sdk: flutter
     sqflite: ^2.0.0+3
     path: ^1.8.0
  2. Создание моделей:
    Вы уже представили две модели. Давайте добавим конструкторы и методы для сериализации и десериализации:

    class Member {
     int id;
     String name;
     List<Document> documents;
    
     Member({required this.id, required this.name, required this.documents});
    
     Map<String, dynamic> toMap() {
       return {
         'id': id,
         'name': name,
       };
     }
    
     static Member fromMap(Map<String, dynamic> map, List<Document> docs) {
       return Member(
         id: map['id'],
         name: map['name'],
         documents: docs,
       );
     }
    }
    
    class Document {
     int id;
     String docType;
     String path;
     int memberId; // Внешний ключ
    
     Document({required this.id, required this.docType, required this.path, required this.memberId});
    
     Map<String, dynamic> toMap() {
       return {
         'id': id,
         'docType': docType,
         'path': path,
         'memberId': memberId,
       };
     }
    
     static Document fromMap(Map<String, dynamic> map) {
       return Document(
         id: map['id'],
         docType: map['docType'],
         path: map['path'],
         memberId: map['memberId'],
       );
     }
    }
  3. Создание базы данных и таблиц:
    Реализуйте функцию для инициализации базы данных и создания необходимых таблиц:

    class DatabaseHelper {
     static final DatabaseHelper _instance = DatabaseHelper._internal();
     factory DatabaseHelper() => _instance;
     DatabaseHelper._internal();
    
     Database? _database;
    
     Future<Database> get database async {
       if (_database != null) return _database!;
       _database = await _initDB('app.db');
       return _database!;
     }
    
     Future<Database> _initDB(String filePath) async {
       return await openDatabase(
         filePath,
         version: 1,
         onCreate: (db, version) async {
           await db.execute('''CREATE TABLE members(
               id INTEGER PRIMARY KEY AUTOINCREMENT,
               name TEXT
             )''');
           await db.execute('''CREATE TABLE documents(
               id INTEGER PRIMARY KEY AUTOINCREMENT,
               docType TEXT,
               path TEXT,
               memberId INTEGER,
               FOREIGN KEY (memberId) REFERENCES members (id) ON DELETE CASCADE
             )''');
         },
       );
     }
    }
  4. Функции для работы с данными:
    Определите функции для сохранения, обновления и получения данных:

    Future<void> insertMember(Member member) async {
     final db = await database;
     await db.insert('members', member.toMap());
    
     for (var doc in member.documents) {
       await db.insert('documents', doc.toMap());
     }
    }
    
    Future<Member> getMember(int id) async {
     final db = await database;
     final memberMap = await db.query('members', where: 'id = ?', whereArgs: [id]);
    
     if (memberMap.isNotEmpty) {
       List<Document> documents = await getDocumentsForMember(id);
       return Member.fromMap(memberMap.first, documents);
     }
     throw Exception('Member not found');
    }
    
    Future<List<Document>> getDocumentsForMember(int memberId) async {
     final db = await database;
     final List<Map<String, dynamic>> docMaps = await db.query(
       'documents',
       where: 'memberId = ?',
       whereArgs: [memberId],
     );
    
     return List.generate(docMaps.length, (i) {
       return Document.fromMap(docMaps[i]);
     });
    }

Заключение

Выше описаны основные шаги по созданию локальной реляционной базы данных в Flutter с использованием SQLite и пакета sqflite. Данная реализация поддерживает связи между моделями через внешние ключи, что позволяет эффективно управлять данными пользователей и документами.

Для дальнейшего изучения, ознакомьтесь с официальной документацией:

Следуя этим шагам, вы сможете успешно интегрировать локальную базу данных в свое приложение Flutter, обеспечив возможность хранения и управления связанными данными.

Оцените материал
Добавить комментарий

Капча загружается...