如何将 Flutter 应用程序连接到本地数据库?
How to connect a Flutter Application with local Database?
我正在用一个小型数据库做一个简单的 flutter 应用程序,但是当我尝试向我的 table 中插入数据时,我出现了这个错误:
发生异常。
NoSuchMethodError(NoSuchMethodError:方法 'insert' 在 null 上被调用。接收者:null 尝试调用:insert("userTable", _LinkedHashMap len:3))
这是我的代码:
// database_helper.dart
import 'dart:io';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:sqflite/sqlite_api.dart';
import 'package:test_sql/models/user.dart';
class DataBaseHelper{
final String tableUser = "userTable" ;
final String columnId = "id" ;
final String columnName = "username" ;
final String columnPassword = "password" ;
static final DataBaseHelper _instance = new DataBaseHelper.internal();
DataBaseHelper.internal();
factory DataBaseHelper() => _instance ;
static Database _db ;
Future<Database> get dbase async{
if(_db !=null){
return _db ;
}
else
{
_db = await initDb() ;
}
}
initDb() async {
Directory documentDirectory = await getApplicationDocumentsDirectory() ;
String path = join(documentDirectory.path,"mydb.db") ;
var ourDb = await openDatabase(path, version: 1,onCreate: _onCreate);
return ourDb ;
}
void _onCreate(Database db , int version) async {
await db.execute("CREATE TABLE $tableUser($columnId INTEGER PRIMARY KEY , $columnName TEXT,$columnPassword TEXT)");
}
Future<int> saveUser (User user) async{
var dbClient = await dbase ;
await initDb() ;
int result = await dbClient.insert(tableUser, user.toMap(),); // insert(tableUser, user.toMap())
return result ;
}
Future<List> getAllUsers() async {
var dbClient = await dbase ;
var result = await dbClient.rawQuery("SELECT * FROM $tableUser") ;
return result.toList() ;
}
Future<User> getUser(int userId) async {
var dbClient = await dbase ;
var result = await dbClient.rawQuery("SELECT * FROM $tableUser Where $columnId = $userId ") ;
if(result.length==0) return null ;
return new User.fromMap(result.first) ;
}
Future<int> deleteUser(int userId) async{
var dbClient = await dbase ;
return await dbClient.delete(tableUser,where: "$columnId=?",whereArgs: [userId]) ;
}
Future<int> updateUser(User user) async {
var dbClient = await dbase ;
return dbClient.update(tableUser, user.toMap(),where: "$columnId=?",whereArgs: [user.id]) ;
}
Future close() async {
var dbClient = await dbase ;
return dbClient.close() ;
}
}
//user.dart
class User{
String _username ;
String _password ;
int _id ;
User(this._id,this._username,this._password) ;
User.map(dynamic obj ){
this._username = obj['username'] ;
this._password = obj['password'] ;
this._id = obj['id'] ;
}
String get username => _username ;
String get password => _password ;
int get id => _id ;
Map<String,dynamic> toMap() {
var map = new Map<String,dynamic>() ;
map["username"] = _username ;
map["password"] = _password ;
if(_id != null){
map["id"] = _id ;
}
return map ;
}
User.fromMap(Map<String,dynamic>map){
this._username=map["username"] ;
this._password=map["password"] ;
this._id=map["id"] ;
}
}
// main.dart
import 'package:flutter/material.dart';
import 'package:test_sql/database_helper.dart';
import 'package:test_sql/models/user.dart';
void main() async {
var db = new DataBaseHelper() ;
int savedUserId = await db.saveUser(new User(1,"Samir Ben Halima", "Sonia el Ayeb")) ;
print(savedUserId) ;
runApp( MaterialApp(
title: "3atba",
home: MyApp(),
)
);
}
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
appBar: AppBar(
title: Text("3atba"),
centerTitle: true,
backgroundColor: Colors.green,
),
),
);
}
}
pubspec.yaml
name: test_sql
description: A new Flutter project.
# The following defines the vers[![this is the place of the ERROR][1]][1]ion and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
sqflite: any
path_provider: any
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
我认为错误在这里(这是固定代码):
if(_db !=null){
return _db ;
}else
{
_db = await initDb() ;
return _db;
}
你只需要在初始化后return变量_db
希望对您有所帮助
我正在用一个小型数据库做一个简单的 flutter 应用程序,但是当我尝试向我的 table 中插入数据时,我出现了这个错误:
发生异常。
NoSuchMethodError(NoSuchMethodError:方法 'insert' 在 null 上被调用。接收者:null 尝试调用:insert("userTable", _LinkedHashMap len:3))
这是我的代码:
// database_helper.dart
import 'dart:io';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:sqflite/sqlite_api.dart';
import 'package:test_sql/models/user.dart';
class DataBaseHelper{
final String tableUser = "userTable" ;
final String columnId = "id" ;
final String columnName = "username" ;
final String columnPassword = "password" ;
static final DataBaseHelper _instance = new DataBaseHelper.internal();
DataBaseHelper.internal();
factory DataBaseHelper() => _instance ;
static Database _db ;
Future<Database> get dbase async{
if(_db !=null){
return _db ;
}
else
{
_db = await initDb() ;
}
}
initDb() async {
Directory documentDirectory = await getApplicationDocumentsDirectory() ;
String path = join(documentDirectory.path,"mydb.db") ;
var ourDb = await openDatabase(path, version: 1,onCreate: _onCreate);
return ourDb ;
}
void _onCreate(Database db , int version) async {
await db.execute("CREATE TABLE $tableUser($columnId INTEGER PRIMARY KEY , $columnName TEXT,$columnPassword TEXT)");
}
Future<int> saveUser (User user) async{
var dbClient = await dbase ;
await initDb() ;
int result = await dbClient.insert(tableUser, user.toMap(),); // insert(tableUser, user.toMap())
return result ;
}
Future<List> getAllUsers() async {
var dbClient = await dbase ;
var result = await dbClient.rawQuery("SELECT * FROM $tableUser") ;
return result.toList() ;
}
Future<User> getUser(int userId) async {
var dbClient = await dbase ;
var result = await dbClient.rawQuery("SELECT * FROM $tableUser Where $columnId = $userId ") ;
if(result.length==0) return null ;
return new User.fromMap(result.first) ;
}
Future<int> deleteUser(int userId) async{
var dbClient = await dbase ;
return await dbClient.delete(tableUser,where: "$columnId=?",whereArgs: [userId]) ;
}
Future<int> updateUser(User user) async {
var dbClient = await dbase ;
return dbClient.update(tableUser, user.toMap(),where: "$columnId=?",whereArgs: [user.id]) ;
}
Future close() async {
var dbClient = await dbase ;
return dbClient.close() ;
}
}
//user.dart
class User{
String _username ;
String _password ;
int _id ;
User(this._id,this._username,this._password) ;
User.map(dynamic obj ){
this._username = obj['username'] ;
this._password = obj['password'] ;
this._id = obj['id'] ;
}
String get username => _username ;
String get password => _password ;
int get id => _id ;
Map<String,dynamic> toMap() {
var map = new Map<String,dynamic>() ;
map["username"] = _username ;
map["password"] = _password ;
if(_id != null){
map["id"] = _id ;
}
return map ;
}
User.fromMap(Map<String,dynamic>map){
this._username=map["username"] ;
this._password=map["password"] ;
this._id=map["id"] ;
}
}
// main.dart
import 'package:flutter/material.dart';
import 'package:test_sql/database_helper.dart';
import 'package:test_sql/models/user.dart';
void main() async {
var db = new DataBaseHelper() ;
int savedUserId = await db.saveUser(new User(1,"Samir Ben Halima", "Sonia el Ayeb")) ;
print(savedUserId) ;
runApp( MaterialApp(
title: "3atba",
home: MyApp(),
)
);
}
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
appBar: AppBar(
title: Text("3atba"),
centerTitle: true,
backgroundColor: Colors.green,
),
),
);
}
}
pubspec.yaml
name: test_sql
description: A new Flutter project.
# The following defines the vers[![this is the place of the ERROR][1]][1]ion and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
sqflite: any
path_provider: any
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
我认为错误在这里(这是固定代码):
if(_db !=null){
return _db ;
}else
{
_db = await initDb() ;
return _db;
}
你只需要在初始化后return变量_db
希望对您有所帮助