Flutter 日记APP-数据库Sqflite

前言

日记App的主要功能是记录文本信息,类似于日常的笔记本,一个笔记本对应的一个梦想日记。考虑到日记信息需要长期存储且不确定日记内容的多少及大小,所以采用Sqflite数据库进行本地缓存。

为了便于操作,将数据库操作封装成单例

java 复制代码
import 'package:sqflite/sqflite.dart';
class SSLDBManager{
  static int version = 1;
  //单例类创建
  SSLDBManager._internal();
  //保存单例
  static final SSLDBManager _dbManager = SSLDBManager._internal();
  //工厂构造函数
  factory SSLDBManager(){
    return _dbManager;
  }
  //数据库
  late final Database db;
}

设计数据格式,创建表格

dart 复制代码
//考虑到数据库要在程序启动时先启动,而数据库的初始化是异步的,这里也采用异步函数,后面通过await函数同步执行
Future<bool> openDB(String path) async{
//获取数据库存放地址
  var databasesPath = await getDatabasesPath();
  String dbPath = '$databasesPath/$path.db';
  //打开数据库,如果数据库中没有对应的表格则创建
  db = await openDatabase(dbPath, version: 1, onCreate: (Database db, int version){
      String dreamTable = "CREATE TABLE If NOT EXISTS Dreams ("
          "id INTEGER PRIMARY KEY autoincrement,"
          "dreamId TEXT,"//唯一笔记本id
          "type INTEGER,"//笔记本类型,便于后面扩展做其他类型笔记
          "title TEXT,"
          "cycleType INTEGER,"//循环闹钟提醒类型,日、周、月
          "isWarning INTEGER,"//是否开启闹钟
          "cycleTime INTEGER,"//循环体系的时间单位,如果是周则对应周几,如果是月对应每月几号
          "time TEXT,"//每天闹钟的提醒时间,比如晚上九点21:00
          "subTitle TEXT,"//日记描述
          "createTime INTEGER,"//创建时间
          "state INTEGER,"//日记状态,是否完结等
          "lastTime INTEGER)";//最后更新时间
      db.execute(dreamTable);

      String recordTable = "CREATE TABLE If NOT EXISTS Records ("
          "id INTEGER PRIMARY KEY autoincrement,"
          "recordId TEXT,"//日记ID
          "type INTEGER,"//日记类型,便于后面扩展
          "dreamId TEXT,"//对应的日记本ID
          "title TEXT,"
          "subTitle TEXT,"
          "time TEXT,"//日记时间
          "price TEXT,"
          "createTime INTEGER,"//创建日记时间
          "lastTime INTEGER,"//最后修改时间
          "filePath TEXT)";//便于扩展其他日记类型
      db.execute(recordTable);

  }, onUpgrade: (Database db, int oldVersion, int version) async {

  });

  return true;
}

数据库操作

dart 复制代码
//TODO: 插入梦想记录
  void insertDream(Map data, SSLDBCallback? callback) async {
    await db.transaction((txn) async{
      String dreamId = data["dreamId"].toString();
      int type = data["type"];
      String title = data["title"].toString();
      String subTitle = data["subTitle"].toString();
      String time = data["time"].toString();
      int cycleType = data["cycleType"];
      int cycleTime = data["cycleTime"];
      int createTime = data["createTime"];
      int lastTime = data["lastTime"];
      bool isWarning = data["isWarning"];
      String dataStr = "INSERT INTO Dreams("
          "dreamId,"
          "type,"
          "title,"
          "cycleType,"
          "cycleTime,"
          "isWarning,"
          "time,"
          "subTitle,"
          "state,"
          "createTime,"
          "lastTime"
          ") VALUES('$dreamId', $type, '$title', $cycleType, $cycleTime, $isWarning, '$time', '$subTitle', 0, $createTime, $lastTime)";
      int id1 = await txn.rawInsert(dataStr);
      if (callback != null){
        callback(id1, "insert dream success");
      }
      debugPrint('ssl get id $id1');
    });
  }
  //TODO: 更新梦想数据
  Future<int> updateDream(Map data) async {
    String dreamId = data["dreamId"].toString();
    String title = data["title"].toString();
    String subTitle = data["subTitle"].toString();
    String time = data["time"].toString();
    int cycleType = data["cycleType"];
    int cycleTime = data["cycleTime"];
    int lastTime = data["lastTime"];
    bool isWarning = data["isWarning"];
    String sqlData = 'UPDATE Dreams SET '
        "title='$title',"
        "subTitle='$subTitle',"
        "time='$time',"
        "cycleType=$cycleType,"
        "cycleTime=$cycleTime,"
        "lastTime=$lastTime,"
        "isWarning=$isWarning "
        "WHERE dreamId='$dreamId'";
    int count = await db.rawUpdate(sqlData);
    return count;
  }
  //TODO: 查询梦想记录
  Future<List<DreamModel>> selectDream() async {
    String data = "SELECT * FROM Dreams";
    List<Map<String, dynamic>> list = await db.rawQuery(data);
    if (list.isEmpty){
      return [];
    }

    List<DreamModel> models = list.map((e) => DreamModel.fromJson(e)).toList();
    return models;
  }

  //TODO: 查询梦想记录
  Future<DreamModel?> selectDreamById(String dreamId) async {
    String data = "SELECT * FROM Dreams WHERE dreamId = '$dreamId'";
    List<Map<String, dynamic>> list = await db.rawQuery(data);
    if (list.isEmpty){
      return null;
    }
    //将查询到的数据映射成模型
    List<DreamModel> models = list.map((e) => DreamModel.fromJson(e)).toList();
    return models.first;
  }


  //TODO: 更新梦想状态
  Future<int> updateDreamState(String dreamId, int state) async {
    String data = 'UPDATE Dreams SET name = state, value = $state WHERE dreamId = $dreamId';
    int count = await db.rawUpdate(data);
    return count;
  }
  //TODO:插入日记记录
  void insertRecord(Map data, SSLDBCallback? callback) async {
    await db.transaction((txn) async{
      String dreamId = data["dreamId"].toString();
      String recordId = data["recordId"].toString();
      int type = data["type"];
      String title = data["title"].toString();
      String subTitle = data["subTitle"].toString();
      String time = data["time"].toString();
      int createTime = data["createTime"];
      String filePath = data["filePath"].toString();
      int lastTime = data["lastTime"];
      String price = data["price"].toString();
      String dataStr = "INSERT INTO Records("
          "dreamId,"
          "recordId,"
          "type,"
          "title,"
          "subTitle,"
          "time,"
          "price,"
          "createTime,"
          "lastTime,"
          "filePath"
          ")VALUES('$dreamId', '$recordId', $type, '$title', '$subTitle', '$time', '$price', $createTime, $lastTime, '$filePath')";
      int id1 = await txn.rawInsert(dataStr);
      debugPrint('ssl get id $id1');
      if (callback != null){
        callback(id1, "insert record success");
      }
    });
  }
  //TODO: 更新日记数据
  Future<int> updateRecord(Map data) async {
    String dreamId = data["dreamId"].toString();
    String recordId = data["recordId"].toString();
    String title = data["title"].toString();
    String subTitle = data["subTitle"].toString();
    String time = data["time"].toString();
    String filePath = data["filePath"].toString();
    int lastTime = data["lastTime"];
    int createTime = data["createTime"];
    String price = data["price"].toString();
    String sqlData = 'UPDATE Records SET '
        "title='$title',"
        "subTitle='$subTitle',"
        "time='$time',"
        "lastTime=$lastTime,"
        "createTime=$createTime,"
        "price='$price',"
        "filePath='$filePath' "
        "WHERE recordId='$recordId' AND dreamId='$dreamId'";
    int count = await db.rawUpdate(sqlData);
    return count;
  }
  //TODO: 查询日记记录
  Future<List<RecordModel>> selectRecord(String dreamId, int page) async {
    int size = 20;//order by id
    String dataStr = "SELECT * FROM Records  WHERE dreamId='$dreamId' ORDER BY lastTime DESC limit $size offset $page";
    List<Map<String, dynamic>> list = await db.rawQuery(dataStr);
    if (list.isEmpty){
      return [];
    }
    //将查询到的数据映射成模型
    List<RecordModel> models = list.map((e) => RecordModel.fromJson(e)).toList();
    return models;
  }

  //TODO: 根据ID查询日记记录
  Future<RecordModel?> selectRecordById(String recordId, String dreamId) async {
    String data = "SELECT * FROM Records WHERE recordId='$recordId' AND dreamId='$dreamId'";
    List<Map<String, dynamic>> list = await db.rawQuery(data);
    if (list.isEmpty){
      return null;
    }

    List<RecordModel> models = list.map((e) => RecordModel.fromJson(e)).toList();
    return models.first;
  }

  //TODO: 查询日记记录条数
  Future<int> selectRecordCount(String  dreamId) async {
    String data = "SELECT COUNT(*) FROM Records WHERE dreamId='$dreamId'";
    int? count = Sqflite.firstIntValue(await db.rawQuery(data));

    return count ?? 0;
  }

}

数据库使用

上面是数据的基本操作的封装,下面介绍一下使用:

dart 复制代码
//初始化数据库
await sslDB.openDB("ssl");

void saveDreamRecordAction() async{
//如果ID不存在则插入数据
  if (recordId.isEmpty){
    Map data = {
      "dreamId" : dreamId,
      "title" : titleStr,
      "price" : "",
      "recordId" : SSLEngine.createRecordId(),
      "time" : timeStr,
      "subTitle" : subDescribe,
      "createTime" : createTime,
      "lastTime" : createTime,
      "type" : 1,
      "filePath" : "",
    };
    //这里是用数据库完成后回调函数
    sslDB.insertRecord(data, (int id, String value){
      debugPrint("ssl create dream $id  $data");
      if (id > 0){
        Fluttertoast.showToast(msg: SSLLocales.l_dreamRecord_add_success.tr);

        Get.back(result: id);
      }else{

      }
    });
  }else{
  //id 存在则更新数据
    int temTimestamp = DateTime.now().millisecondsSinceEpoch;
    Map data = {
      "dreamId" : dreamId,
      "title" : titleStr,
      "price" : "",
      "recordId" : recordId,
      "time" : timeStr,
      "subTitle" : subDescribe,
      "createTime" : createTime,
      "lastTime" : temTimestamp,
      "type" : 1,
      "filePath" : "",
    };
    //等待数据库数据存储完成
    int count = await sslDB.updateRecord(data);
    if (count > 0){
      RecordModel? recordTem = await sslDB.selectRecordById(recordId,dreamId);
      if (recordTem != null){
        Fluttertoast.showToast(msg: SSLLocales.l_toast_record_update.tr);
        Get.back(result: recordTem);
      }
    }
  }
}

项目较简单,大概的操作就这些,后续会继续更新其他开发内容,有不当之处,欢迎指正。

相关推荐
兔云程序20 分钟前
消息称苹果iPhone系列将完全放弃LCD屏幕
ios·iphone
Python私教1 小时前
Flutter概述及其优势
flutter
JackLee182 小时前
Metal 之旅之MTLLibrary
ios·metal·图形绘制·视频渲染·mtllibrary
Python私教7 小时前
Flutter组件化开发
flutter
helloxmg8 小时前
鸿蒙harmonyos next flutter混合开发之开发FFI plugin
flutter
早起的年轻人1 天前
Flutter String 按 ,。分割
flutter
missmisslulu1 天前
电容笔值得买吗?2024精选盘点推荐五大惊艳平替电容笔!
学习·ios·电脑·平板
GEEKVIP1 天前
手机使用技巧:8 个 Android 锁屏移除工具 [解锁 Android]
android·macos·ios·智能手机·电脑·手机·iphone
GEEKVIP1 天前
如何在 Windows 10 上恢复未保存/删除的 Word 文档
macos·ios·智能手机·电脑·word·笔记本电脑·iphone
奇客软件1 天前
iPhone使用技巧:如何恢复变砖的 iPhone 或 iPad
数码相机·macos·ios·电脑·笔记本电脑·iphone·ipad