sqflite
是Flutter
的SQLite
插件,支持的平台有:iOS、Android、MacOS,桌面端可以使用sqflite_common_ffi,本篇文章以sqflite_common_ffi为主。
sqflite_common_ffi定义了一个全局databaseFactoryFfi
允许在 Flutter 和 DartVM 上支持 Linux 和 Windows。所以databaseFactory = databaseFactoryFFi
就可以带来Linux和Windows的支持。databaseFactory
提供了一个直接的 API(openDatabase、deleteDatabase)。
任务要求:构建一个桌面端的任务管理软件,使用sqflite_common_ffi插件。
创建数据库
1、在你的pubspec.yaml文件中添加以下依赖:
2、封装一个数据库操作类 DBHelper()
class DBHelper {//定义了一个静态变量---_dbHelper,保存DBHelper类的单例实例static DBHelper" /> get database async {if (_db != null) {return _db!;}_db = await initDB();return _db!;}}
3、初始化数据库操作 initDB()
a.初始化数据库sqfliteFfiInit();
b.获取databaseFactoryFfi对象
c.使用databaseFactoryFfi 对象来打开数据库,语句:databaseFactory.openDatabase()
String Path.(获取数据库的默认位置,最好使用”path_provider”策略)
path_provider的使用:
1、添加依赖
2、在需要的文件中导入包
import 'package:path/path.dart' as path;
openDatabaseOptions(打开数据库操作)的某些属性:
/// Specify the expected version.int" />
至此,数据库创建完成。
数据库操作
增加:
1、Database.insert
Future insert(String table, //表名Map values,//插入的数据{String? nullColumnHack, ConflictAlgorithm? conflictAlgorithm});
//插入数据Futureinsert(Task task)async{Database db=await database;print("insert function called");print("插入的数据:${task.toJson()}");/*insert方法会返回最后的行id*/return await db.insert(_ALLTask, task.toJson());}
2、Database.rawInsert
Future rawInsert(String sql, [List
//插入数据——法二 rawInsertFuture rawInsert(Task task) async{Database db=await database;return await db.rawInsert("INSERT INTO $_ALLTask (content, ownType, startDate, endDate, createTime,completeTime, repeat, isCompleted) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",[task.content,task.ownType,task.startDate,task.endDate,task.createTime,task.completeTime,task.repeat,task.isCompleted]);}
删除:
使用 whereArgs 将参数传递给 where 语句。有助于防止 SQL 注入攻击
Future delete(String table, {String? where, List
Future delete(Task task)async{Database db=await database;print("delete function called!");await db.delete(_ALLTask,where: "id=?",whereArgs: [task.id]);}
修改:
1、Database.update
Future update(String table, Map values,{String? where,List
//修改任务内容(全部数据)Future update(Task task)async{Database db=await database;return db.update(_ALLTask, task.toJson(), where: 'id=?', whereArgs: [task.id]);}
2、Database.rawUpdate
Future rawUpdate(String sql, [List
Future rawUpdate(Task task,newDate) async{Database db=await database;return db.rawUpdate('''UPDATE $_ALLTaskSET createTime=?WHERE id=?''',[newDate,task.id]);
查询:
1、Database.query
Future<List<Map>> query(String table,{bool? distinct,List? columns,String? where,List
//查询数据/*查询到后返回的是一个List<Map>类型的列表,每一个元素都是Map *result就是List<Map>类型的列表 *result.map((taskMap) => Task.fromJson(taskMap))=======>遍历每一个元素,将每一个元素都执行*给定的函数,此处是Task.fromJson(taskMap),然后返回一个新的迭代器 *所以这个迭代器里的每一个元素都转换成了Task类型 *.toList();将这个迭代器转换成列表 * 所以最后就返回了一个Task类型的列表*/Future<List> query() async{Database db=await database;print("query function called!");var result=await db.query(_ALLTask); /*此时返回的是一个List类型*/return result.map((taskMap) => Task.fromJson(taskMap)).toList();}
2、Database.rawQuery
Future<List<Map>> rawQuery(String sql,[List
Future<List> rawquery() async{Database db=await database;print("query function called!");var result=await db.rawQuery("SELECT * FROM $_ALLTask "); /*此时返回的是一个List类型*/return result.map((taskMap) => Task.fromJson(taskMap)).toList();}
查询时排序:
ASC:表示按升序排序。 DESC:表示按降序排序。
var result=await db.query(_ALLTask,orderBy: "datetime(createTime) ASC");
var result=await db.rawQuery("SELECT * FROM $_ALLTask ORDER BY datetime(createTime) DESC");
此时我想按照字段createTime进行升序、降序。但是字段createTime是String类型。
SQLite中支持多种日期时间格式,但是建议使用ISO 8601格式来存储日期时间值。ISO 8601是一种国际标准,用于表示日期、时间和日期时间值。它的格式如下:
YYYY-MM-DDTHH:MM:SS.SSSZ
其中,YYYY表示年份,MM表示月份,DD表示日期,T表示时间分隔符,HH表示小时,MM表示分钟,SS表示秒,.SSS表示毫秒(可选),Z表示时区偏移量
我的时间格式如下:2023-07-12--11:23:02
String timeStr = "2023-07-12--11:23:02";//首先使用replaceAll()方法将时间字符串中的--替换为T,以便它符合ISO 8601格式//使用DateTime.parse()方法将字符串解析为日期时间类型。DateTime dateTime = DateTime.parse(timeStr.replaceAll("--", "T"));//使用toIso8601String()方法将日期时间类型格式化为ISO 8601字符串String iso8601Str = dateTime.toIso8601String();print("${iso8601Str}");
最后打印出的数据:2023-07-12T15:26:31.000
在现有数据表中插入新列并设置默认值
Future addColumn() async {Database db = await database;await db.execute("ALTER $_ALLTask task ADD COLUMN priority INTEGER DEFAULT 0");}
默认值此时为0,如果不设置默认值的话,默认值全部为null
在priority默认值全部为null的时候修改为0:
//设置新列的默认值Future setdefaultValue()async{Database db = await database;await db.execute("UPDATE $_ALLTaskSET priority = ? WHERE priority IS ?",[0,null]);}