Flutter体验 Day 24-sqflite

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


<<:  Day19:别说那麽多废话,讲重点

>>:  [Day17] Vue 3 单元测试 (Unit Testing) - Vue Test Utils + Jest 基本范例 & 核心语法

LeetCode Weekly Contest 239的详解分享

Hard- 1851. Minimum Interval to Include Each Query...

到底什麽是资安?

时间回到几年前,第一次面试一份资安公司行政助理职 记得那天除了该有的面试考题之外, 主管走到白板前说...

Day11-Database——效能的储备足够吗?-N+1 query

标题参考来源 大家好~ 今天来简单认识一下 N+1 query 吧! 什麽是 N+1 query 呢...

nginx 反向代理到路径时自动添加路径下的 index.html

在设置反向代理静态网站时,当网页在路径目录下 nginx 不会自索引 index.html (例:h...

Day4 带着烤肉香的JavaScript

JavaScript约诞生於1995年,用於操作网页的DOM、BOM,负责处理所有网页与使用者的互动...