我是flutter的新手,我试图创建一个数据库来处理用户,所以我编写了以下数据库服务类
import 'package:banking_system/database/transfer_db.dart';
import 'package:banking_system/database/user_db.dart';
import 'package:flutter/widgets.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import '../models/user.dart';
class UserDatabaseService {
static const _databaseName = "userbankingdb.db";
static const _databaseVersion = 1;
final tableName = "users";
UserDatabaseService._privateConstructor();
static final UserDatabaseService _instance = UserDatabaseService._privateConstructor();
factory UserDatabaseService() => _instance;
Database? _db;
Future<Database> get database async{
if(_db == null){
await init();
return _db!;
}
return _db!;
}
// this opens the database (and creates it if it doesn't exist)
Future<Database> init() async {
final documentsDirectory = await getApplicationDocumentsDirectory();
final path = join(documentsDirectory.path, _databaseName);
_db = await openDatabase(
path,
version: _databaseVersion,
onCreate: (db, version) async{
await createUserTable(db);
},
);
print(_db!.path);
return _db!;
}
// SQL code to create the database table
Future<void> createUserTable(Database database) async{
print("in create user table");
await database.query("""CREATE TABLE IF NOT EXISTS "${tableName}"(
"user_id" INTEGER NOT NULL,
"name" TEXT NOT NULL,
"email" TEXT NOT NULL,
"password" TEXT NOT NULL,
"gender" TEXT NOT NULL,
"balance" REAL NOT NULL,
PRIMARY KEY("user_id" AUTOINCREMENT)
);""");
print("The last inserted row id is ");
print(await createUser(name: "Farida Yasser", email: "[email protected]", password: "12345abcd", gender: "female", balance: 3200));
}
Future<int> createUser({required String name, required String email, required String password, required String gender, required double balance}) async{
final Database database = await UserDatabaseService().database;
return await database.rawInsert(
'''INSERT INTO $tableName (name, email, password, gender, balance) VALUES (?,?,?,?,?)''',
[name, email, password, gender, balance.toString()]
);
}
Future<List<User>> fetchAllUsers() async{
final Database database = await UserDatabaseService().database;
final users = await database.rawQuery('''SELECT * FROM $tableName''');
return users.map((eachUserMap) => User.fromSqfliteDatabase(eachUserMap)).toList();
}
Future<User> fetchUserById(int userId) async{
final Database database = await UserDatabaseService().database;
final user = await database.rawQuery('''SELECT * FROM $tableName WHERE user_id = ?''', [userId.toString()]);
return User.fromSqfliteDatabase(user.first);
}
Future<int> updateUserBalance(int userId, double changeInBalance) async{
final user = await fetchUserById(userId);
double newAmount = user.balance + changeInBalance;
final database = await UserDatabaseService().database;
return await database.update(tableName, {'balance': newAmount}, where: "user_id = ?", whereArgs: [userId]);
}
}
此函数在以下主屏幕小部件中调用
import 'package:banking_system/constants/textstyles.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../database/user_db.dart';
import '../models/user.dart';
class HomeScreen extends StatefulWidget {
final Future<User> currentUser;
HomeScreen({Key? key, required this.currentUser}) : super(key: key);
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title:Text("Home Page"),
titleTextStyle: appbarTitleTextStyle,
),
body: FutureBuilder(
future: widget.currentUser,
builder: (context, snapshot) {
if(snapshot.connectionState == ConnectionState.waiting){
return Center(child: CircularProgressIndicator(),);
}
if(snapshot.hasError){
print(snapshot.error);
}
if(!snapshot.hasData){
return Center(
child: Text("User was not found")
,);
}else{
User currentUserData = snapshot.data!;
return SafeArea(child: Column(
children: [
Image.asset(currentUserData.gender == "female" ? "images/woman.png" : "images/man.png"),
Text("Hello " + currentUserData.name),
Text("Your email address is: " + currentUserData.email),
Text("Yor Current Balance is: " + currentUserData.balance.toString()),
],
));
}
},
)
);
}
}
它会产生这些错误
D/hw-ProcessState(24928): Binder ioctl to enable oneway spam detection failed: Invalid argument
E/OpenGLRenderer(24928): fbcNotifyFrameComplete error: undefined symbol: fbcNotifyFrameComplete
E/OpenGLRenderer(24928): fbcNotifyNoRender error: undefined symbol: fbcNotifyNoRender
D/DecorView[](24928): onWindowFocusChanged hasWindowFocus true
E/BLASTBufferQueue(24928): [SurfaceView[com.example.banking_system/com.example.banking_system.MainActivity]#1](f:0,a:2) isEGL=1, mPendingRelease.size()=1, mMaxAcquiredBuffers=4, currentMaxAcquiredBufferCount=2
I/flutter (24928): /data/user/0/com.example.banking_system/app_flutter/userbankingdb.db
I/flutter (24928): type 'int' is not a subtype of type 'String'
E/BLASTBufferQueue(24928): [SurfaceView[com.example.banking_system/com.example.banking_system.MainActivity]#1](f:0,a:4) isEGL=1, mPendingRelease.size()=2, mMaxAcquiredBuffers=4, currentMaxAcquiredBufferCount=2
需要注意的是,createUserTable 中 print 语句的结果没有出现在控制台上,而且 fetchUserById 函数也返回 null。
我只是想知道我的代码可能有什么问题。
第 1 步:使用等待数据库。execute("""CREATE TABLE IF NOT EXISTS "${tableName}" 不是等待数据库。query("""CREATE TABLE IF NOT EXISTS "${tableName}"
第2步:移动这一行print(await createUser(名称:“Farida Yasser”,电子邮件:“[email protected]”,密码:“12345abcd”,性别:“女”,余额:3200));从 Future createUserTable 到 Init()
第3步:考虑数据类型“balance”REAL NOT NULL和balance.toString(),如果数据库已在Android模拟器中创建,您可以使用Device Explorer将其删除;
测试结果