Flutter中sqflite本地数据库使用及代码理解问题求助
问题修复与实现逻辑说明
一、现有代码的错误修复
你当前的代码存在6处可直接运行的问题,按优先级修复如下:
- 单例初始化错误
原代码静态实例直接初始化会导致递归构造报错,修改为:// 原代码:static DatabaseHelper _databaseHelper = DatabaseHelper(); static DatabaseHelper? _databaseHelper; // 改为初始为null - 数据库路径拼接错误
不同系统路径分隔符不同,不要手动拼接字符串,先导入path包,再用join方法拼接:// 顶部导入 import 'package:path/path.dart'; // initializeDatabase方法内修改路径代码 String path = join(directory.path, 'note.db'); - _createDb方法返回值错误
async方法不要用void作为返回值,修改为:Future<void> _createDb(Database db, int newVersion) async { // 原有建表逻辑不变 } - update方法where条件错误
缺少占位符会导致更新匹配失败,修改为:var result = await db.update( noteTable, note.toMap(), where: '$colID = ?', // 加=?作为占位符 whereArgs: [note.id] ); - delete方法SQL注入风险
不要直接拼接ID到SQL语句,修改为官方推荐写法:var result = await db.delete( noteTable, where: '$colID = ?', whereArgs: [id] ); - getNoteList方法未完成
你已经拿到了数据库返回的Map列表,需要手动转换为Note对象返回,补充代码如下:
注意你需要提前在Future<List<Note>> getNoteList() async { var noteMapList = await getNoteMapList(); int count = noteMapList.length; List<Note> noteList = []; for (int i = 0; i < count; i++) { noteList.add(Note.fromMap(noteMapList[i])); } return noteList; }note.dart的Note类中实现fromMap静态方法和toMap实例方法,示例如下:class Note { int? id; String title; String description; int priority; String date; Note({ this.id, required this.title, required this.description, required this.priority, required this.date, }); Map<String, dynamic> toMap() { return { 'id': id, 'title': title, 'description': description, 'priority': priority, 'date': date, }; } static Note fromMap(Map<String, dynamic> map) { return Note( id: map['id'], title: map['title'], description: map['description'], priority: map['priority'], date: map['date'], ); } }
二、实现逻辑通俗说明
整个封装的逻辑可以分为3层理解:
- 单例控制层:DatabaseHelper全局只会创建1个实例,避免重复打开数据库浪费资源,工厂构造的作用就是第一次调用时创建实例,后续所有调用都返回同一个实例。
- 数据库初始化层:第一次调用数据库操作时,会先获取App私有存储目录,在该目录下创建
note.db数据库文件,首次创建文件时会自动执行建表SQL生成你的笔记表。 - 增删改查操作层:所有操作都是先拿到已经打开的数据库实例,调用sqflite封装好的操作方法,数据库返回的数据是Map格式,你需要自己和自定义的Note类做转换即可在业务代码里使用。
三、使用示例
你在业务代码里可以直接这样调用:
// 初始化实例 final dbHelper = DatabaseHelper(); // 新增笔记 Note newNote = Note( title: '测试笔记', description: '测试内容', priority: 1, date: DateTime.now().toString(), ); await dbHelper.insertData(newNote); // 获取所有笔记 List<Note> allNotes = await dbHelper.getNoteList(); // 更新笔记 newNote.title = '修改后的标题'; await dbHelper.updateNote(newNote); // 删除笔记 await dbHelper.deleteNote(newNote.id!);
内容的提问来源于stack exchange,提问作者myself_rana.raj
相关产品推荐
相关产品推荐

