在學(xué)習(xí)了ui的制作之后满败,我準(zhǔn)備先實(shí)現(xiàn)一個(gè)用戶管理系統(tǒng),簡單的來說就是在后臺建立一個(gè)用戶名的數(shù)據(jù)庫邓嘹。
需要用到的技術(shù)詳解:
sqflite詳解 http://www.reibang.com/p/3995ca566d9b
sqflite的官方文檔 https://pub.dev/documentation/sqflite/latest/英語不好的建議與上面那個(gè)聯(lián)合閱讀
await和async異步處理 http://www.reibang.com/p/e12185251e40
flutter中的json解析 http://www.reibang.com/p/51eb9dd8ca0c
flutter頁面跳轉(zhuǎn)routehttp://www.reibang.com/p/6df3349268f3
數(shù)據(jù)庫建立
數(shù)據(jù)庫一般來說有以下幾個(gè)操作辖所,初始化(創(chuàng)建新的數(shù)據(jù)庫,設(shè)定好行列名)舆乔、插入新值、查詢數(shù)據(jù)庫、刪除值念脯。
在flutter當(dāng)中酥宴,sqlite數(shù)據(jù)庫是通過sqflite這個(gè)庫進(jìn)行調(diào)用的,首先我們要使用這個(gè)庫進(jìn)行數(shù)據(jù)庫的創(chuàng)建颜武,建議將關(guān)于數(shù)據(jù)庫的函數(shù)單獨(dú)封裝成一個(gè)類璃搜,放到一個(gè)文件里。
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart';
class SqlManager{
static const _VERSION=1;
static const _NAME="test.db";
static Database _database;
這是一開始需要引用的一些庫和一些簡單的變量定義鳞上,這里的Database就是sqflite當(dāng)中數(shù)據(jù)庫變量的類型这吻。創(chuàng)建一個(gè)數(shù)據(jù)庫,要輸入的變量有它的路徑篙议、名字和版本號唾糯。
關(guān)于數(shù)據(jù)庫處理的程序:
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart';
import 'package:meta/meta.dart';
import 'package:sqflite/sqlite_api.dart';
import '../model.dart';
class SqlManager {
static const _VERSION = 1;
static const _NAME = "qss.db";
static Database _database;
///初始化
static init() async {
var databasesPath = (await getExternalStorageDirectory()).path;
print(databasesPath);
String path = join(databasesPath, _NAME);
_database = await openDatabase(path,
version: _VERSION, onCreate: (Database db, int version) async {});
}
///判斷表是否存在
static isTableExits(String tableName) async {
await getCurrentDatabase();
var res = await _database.rawQuery(
"select * from Sqlite_master where type = 'table' and name = '$tableName'");
return res != null && res.length > 0;
}
///獲取當(dāng)前數(shù)據(jù)庫對象
static Future<Database> getCurrentDatabase() async {
if (_database == null) {
await init();
}
return _database;
}
///關(guān)閉
static close() {
_database?.close();
_database = null;
}
}
abstract class BaseDbProvider {
bool isTableExits = false;
createTableString();
tableName();
///創(chuàng)建表sql語句
tableBaseString(String sql) {
return sql;
}
Future<Database> getDataBase() async {
return await open();
}
///super 函數(shù)對父類進(jìn)行初始化
@mustCallSuper
prepare(name, String createSql) async {
isTableExits = await SqlManager.isTableExits(name);
if (!isTableExits) {
Database db = await SqlManager.getCurrentDatabase();
return await db.execute(createSql);
}
}
@mustCallSuper
open() async {
if (!isTableExits) {
await prepare(tableName(), createTableString());
}
return await SqlManager.getCurrentDatabase();
}
}
class PersonDbProvider extends BaseDbProvider{
///表名
final String name = 'PresonInfo';
final String columnId="id";
final String columnName="name";
final String columnSecret="secret";
PersonDbProvider();
@override
tableName() {
return name;
}
@override
createTableString() {
return '''
create table $name (
$columnId integer primary key,$columnName text not null,
$columnSecret text not null)
''';
}
///查詢數(shù)據(jù)庫
Future _getPersonProvider(Database db, int id) async {
List<Map<String, dynamic>> maps =
await db.rawQuery("select * from $name where $columnId = $id");
return maps;
}
///插入到數(shù)據(jù)庫
Future insert(UserModel model) async {
Database db = await getDataBase();
var userProvider = await _getPersonProvider(db, model.id);
if (userProvider != null) {
///刪除數(shù)據(jù)
await db.delete(name, where: "$columnId = ?", whereArgs: [model.id]);
}
return await db.rawInsert("insert into $name ($columnId,$columnName,$columnSecret) values (?,?,?)",[model.id,model.name,model.secret]);
}
///更新數(shù)據(jù)庫
Future<void> update(UserModel model) async {
Database database = await getDataBase();
await database.rawUpdate(
"update $name set $columnName = ?,$columnSecret = ? where $columnId= ?",[model.name,model.secret,model.id]);
}
///獲取事件數(shù)據(jù)
Future<UserModel> getPersonInfo(int id) async {
Database db = await getDataBase();
List<Map<String, dynamic>> maps = await _getPersonProvider(db, id);
if (maps.length > 0) {
return UserModel.fromJson(maps[0]);
}
return null;
}
}
這里面包括了數(shù)據(jù)庫的生成、調(diào)用鬼贱、插入跟刪除的程序移怯。
這個(gè)程序把底下的一些操作就封裝成一個(gè)個(gè)函數(shù),我們之后調(diào)用這些函數(shù)就可以了吩愧。
new RaisedButton(
onPressed: () {
insert(_id, _name.text, _secret.text);}
把這個(gè)按鈕插入到你想放的地方芋酌,通過點(diǎn)擊,就可以把之前我們輸入的用戶名跟密碼給存到數(shù)據(jù)庫當(dāng)中了雁佳。
tips
你們?nèi)绻肟催@個(gè)數(shù)據(jù)庫當(dāng)中的數(shù)據(jù)表的話脐帝,可以把上面存儲(chǔ)db的路徑打印一下同云,然后去里面復(fù)制出來看。
推薦使用sqlite Studio https://sqlitestudio.pl/index.rvt
頁面跳轉(zhuǎn)
當(dāng)我們做好了一個(gè)頁面之后堵腹,我們可以把它單獨(dú)放在一個(gè)文件當(dāng)中炸站,變成一個(gè)類。
然后在頁面上插入一個(gè)RaisedButton疚顷,這個(gè)button的onPressd屬性里可以加入一些函數(shù)旱易,我們可以通過路由轉(zhuǎn)換來跳轉(zhuǎn)到另外一個(gè)頁面,我的另外一個(gè)界面的類名字叫做RegisitorScreen腿堤,所以通過點(diǎn)擊按鈕就會(huì)跳轉(zhuǎn)到下個(gè)頁面去了阀坏。
new Container(
margin: new EdgeInsets.fromLTRB(10.0, 0.0, 0.0, 0.0),
child: new RaisedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
new RegisitorScreen()));
},
child: new Text('注冊'),
我們可以在跳轉(zhuǎn)到的那個(gè)頁面上加一個(gè)跳轉(zhuǎn)回原頁面的按鈕,這樣就可以實(shí)現(xiàn)一個(gè)閉環(huán)笆檀,讓我們可以在不同頁面之間進(jìn)行轉(zhuǎn)換忌堂。