初始化数据库仍然 returns 为 null [Flutter, sqflite]
Initialized database still returns as null [Flutter, sqflite]
我正在尝试使用 sqflite 库在 Flutter 上执行 CRUD 操作。在线资源指向了一堆解决这个问题的方法。这是我的实现:
class SqlManager {
static const String tname = 'table1';
static const String dname = 'database.db';
Future<Database> db;
initDB() async {
Directory path = await getApplicationDocumentsDirectory();
db = openDatabase(join(path.path, dname), version: 1, onCreate: (db, version) {
return db.execute(
'CREATE TABLE $tname (id INTEGER PRIMARY KEY, name TEXT, type TEXT, time1 INTEGER, time2 INTEGER, imp INTEGER, urg INTEGER)');
});
}
Future<void> writing(Task task) async {
print("called");
final Database DB = await db;
await DB.insert(
tname,
task.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
print("Execution completed");
}
Future<List<Task>> reading() async {
Database DB = await db;
List<Map<String, dynamic>> maps = await DB.query(tname);
return List.generate(maps.length, (i) {
return Task.fromMap(maps[i]);
});
}
}
每当我尝试调用这些函数中的任何一个时,我都会遇到一个 NoSuchMethodError,由其中一个函数中的变量 'DB' 抛出。感谢任何帮助,谢谢!
Whenever I attempt to call any of these functions, I hit upon a NoSuchMethodError, thrown by the variable 'DB' inside one of these functions. Any help is appreciated, thanks!
这是因为您还没有通过调用 initDB()
来初始化您的数据库。因此,在调用使用数据库的方法之前先调用它。但是您最终会为每次调用重新创建每个实例。
更好的方法是为您的数据库创建单例。将您的 SqlManager
修改为如下内容:
class SqlManager {
static const String tname = 'table1';
static const String dname = 'database.db';
// Future<Database> db;
// Make a singleton class
SqlManager._privateConstructor();
static final SqlManager instance = SqlManager._privateConstructor();
// Use a single reference to the db.
static Database _db;
// Use this getter to use the database.
Future<Database> get database async {
if (_db != null) return _database;
// Instantiate db the first time it is accessed
_db = await _initDB();
return _db;
}
// Init the database for the first time.
_initDB() async {
Directory path = await getApplicationDocumentsDirectory();
return await openDatabase(join(path.path, dname), version: 1, onCreate: (db, version) {
return db.execute(
'CREATE TABLE $tname (id INTEGER PRIMARY KEY, name TEXT, type TEXT, time1 INTEGER, time2 INTEGER, imp INTEGER, urg INTEGER)');
});
}
// Then you can use the database getter in another method
Future<List<Task>> reading() async {
Database DB = await instance.database;
List<Map<String, dynamic>> maps = await DB.query(tname);
return List.generate(maps.length, (i) {
return Task.fromMap(maps[i]);
});
}
}
我正在尝试使用 sqflite 库在 Flutter 上执行 CRUD 操作。在线资源指向了一堆解决这个问题的方法。这是我的实现:
class SqlManager {
static const String tname = 'table1';
static const String dname = 'database.db';
Future<Database> db;
initDB() async {
Directory path = await getApplicationDocumentsDirectory();
db = openDatabase(join(path.path, dname), version: 1, onCreate: (db, version) {
return db.execute(
'CREATE TABLE $tname (id INTEGER PRIMARY KEY, name TEXT, type TEXT, time1 INTEGER, time2 INTEGER, imp INTEGER, urg INTEGER)');
});
}
Future<void> writing(Task task) async {
print("called");
final Database DB = await db;
await DB.insert(
tname,
task.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
print("Execution completed");
}
Future<List<Task>> reading() async {
Database DB = await db;
List<Map<String, dynamic>> maps = await DB.query(tname);
return List.generate(maps.length, (i) {
return Task.fromMap(maps[i]);
});
}
}
每当我尝试调用这些函数中的任何一个时,我都会遇到一个 NoSuchMethodError,由其中一个函数中的变量 'DB' 抛出。感谢任何帮助,谢谢!
Whenever I attempt to call any of these functions, I hit upon a NoSuchMethodError, thrown by the variable 'DB' inside one of these functions. Any help is appreciated, thanks!
这是因为您还没有通过调用 initDB()
来初始化您的数据库。因此,在调用使用数据库的方法之前先调用它。但是您最终会为每次调用重新创建每个实例。
更好的方法是为您的数据库创建单例。将您的 SqlManager
修改为如下内容:
class SqlManager {
static const String tname = 'table1';
static const String dname = 'database.db';
// Future<Database> db;
// Make a singleton class
SqlManager._privateConstructor();
static final SqlManager instance = SqlManager._privateConstructor();
// Use a single reference to the db.
static Database _db;
// Use this getter to use the database.
Future<Database> get database async {
if (_db != null) return _database;
// Instantiate db the first time it is accessed
_db = await _initDB();
return _db;
}
// Init the database for the first time.
_initDB() async {
Directory path = await getApplicationDocumentsDirectory();
return await openDatabase(join(path.path, dname), version: 1, onCreate: (db, version) {
return db.execute(
'CREATE TABLE $tname (id INTEGER PRIMARY KEY, name TEXT, type TEXT, time1 INTEGER, time2 INTEGER, imp INTEGER, urg INTEGER)');
});
}
// Then you can use the database getter in another method
Future<List<Task>> reading() async {
Database DB = await instance.database;
List<Map<String, dynamic>> maps = await DB.query(tname);
return List.generate(maps.length, (i) {
return Task.fromMap(maps[i]);
});
}
}