前言
日记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);
}
}
}
}
项目较简单,大概的操作就这些,后续会继续更新其他开发内容,有不当之处,欢迎指正。