iT邦幫忙

2021 iThome 鐵人賽

DAY 24
0

sqflite

昨日我們使用WebSocket技術建立了一個簡單聊天室,不過每次重新刷新畫面後聊天室的記錄就消失了,
讓我們使用 sqflite 來處理聊天室的訊息記錄吧。

sqflite 是一個用來操作 SQLite 資料庫的套件,我們在 pubspec.yaml 加入套件設定

 dependencies:
  flutter:
    sdk: flutter
  web_socket_channel: ^2.1.0
  rxdart: ^0.27.2
  sqflite: ^2.0.0+4
  path: ^1.8.0

建立 DB

首先我們使用 dart singleton 語法產生一個操作 db 的實例

class ChatDB {
  static final ChatDB _instance = ChatDB._internal();

  Database? _db;

  ChatDB._internal();

  factory ChatDB() {
    return _instance;
  }
}

初始化 database

我們透過openDatabase函式開啟資料庫,並通過onCreate建立資料表

  Future<Database> _initDB() async {
    final dbPath = await getDatabasesPath();
    return _db ??= await openDatabase(
      join(dbPath, 'chat.sqlite'),
      onCreate: (db, version) {
        return db.execute(
          'CREATE TABLE chat(id INTEGER PRIMARY KEY, by TEXT, msg TEXT, mid TEXT, time INTEGER)',
        );
      },
      version: 1,
    );
  }

插入一筆聊天記錄

我們使用已定義好的 Message Model 類別,使用 insert 語法匯入資料

  Future insert(Message msg) async {
    final db = await _initDB();

    await db.insert(
      'chat',
      msg.toJson(),
      conflictAlgorithm: ConflictAlgorithm.replace,
    );
  }

使用 query 語法取得離線記錄

也可以使用 sqlite SELECT 語法取得資料

  Future<List<Message>> query() async {
    final db = await _initDB();
    final List<Map<String, dynamic>> maps =
        await db.rawQuery('SELECT * FROM chat ORDER BY time DESC LIMIT 30;');

    var data = List.generate(maps.length, (i) {
      return Message.fromJson(maps[i]);
    });

    return List.from(data.reversed);
  }

根據 mid 刪除聊天記錄

使用 sqlite DELETE 語法刪除特定資料

  Future<int> delete(String mid) async {
    final db = await _initDB();
    return await db.rawDelete('DELETE FROM chat WHERE mid = ?', [mid]);
  }

關閉資料庫

若確認不在使用需透過 close 關閉資料庫

 Future<void> close() async {
    final db = await _initDB();
    await db.close();
  }

聊天室 初始化

StatefulWidget 生命週期 initState 階段從 DB 取回資料

  • ChatRoomStatefulWidget
 @override
  initState() {
    super.initState();
    chat.initData();
  • ChatViewModel
  void initData() async {
    data.addAll(await db.query());
    stream.add(data);
  }

聊天室 刪除記錄

  • ChatViewModel
  delete(String mid) async {
    await db.delete(mid);
    data.removeWhere((item) => item.mid == mid);
    stream.add(data);
  }

今日成果

chat_db


上一篇
Flutter體驗 Day 23-WebSocket
下一篇
Flutter體驗 Day 25-SharedPreferences
系列文
Flutter / Dart 跨平台App開發體驗30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言