در دنیای برنامهنویسی موبایل، ذخیرهسازی امن و کارآمد اطلاعات یکی از مهمترین چالشها است.
فلاتر چارچوب محبوب ساخت اپلیکیشن موبایل با ارائه کتابخانه SQLite، راهحلی قدرتمند برای این چالش ارائه میدهد. در این مقاله، به آموزش گام به گام ذخیرهسازی اطلاعات در فلاتر با استفاده از دیتابیس SQLite میپردازیم.
در این آموزش قراره با دیتابیس محلی SQLite کار کنیم و وارد کردن ,آپدیت کردن و پاک کردن داده از دیتابیس محلی را یاد بگیریم چون خیلی مواقع به آن نیاز داریم که اطلاعات را در حالت آفلاین ذخیره کنیم.
به طور مثال اپلیکیشن های کتاب یا اپ های آنلاین که گاهی نیاز داریم یک سری اطلاعاتش در دیتابیس محلی ذخیره کنیم.
مراحل آموزش به شرح زیر است
SQLite یک سیستم مدیریت پایگاه داده رابطهای (RDBMS) سبک و خودکار است که به طور گسترده در برنامههای موبایل و وب استفاده میشود.
این دیتابیس به دلیل سادگی، سرعت و قابلیت اطمینان بالا، به انتخابی محبوب برای توسعهدهندگان تبدیل شده است.
مزایای استفاده از SQLite:
موارد استفاده از SQLite:
این مقاله برای برنامهنویسان فلاتر که مایل به یادگیری نحوه ذخیرهسازی اطلاعات در برنامههای خود با استفاده از SQLite هستند، مناسب است.
فرض میشود که خواننده آشنایی مقدماتی با مفاهیم پایگاه داده و برنامهنویسی فلاتر دارد.
پکیج sqflite در فلاتر برای کار با دیتابیس کلاس ها و متد هایی را ارائه می دهد پس به قسمت dependencies رفته و پکیج را به صورت زیر وارد کنید.
علاوه بر آن به پکیج path نیز نیاز داریم.
dependencies:
flutter:
sdk: flutter
sqflite:
path:
برای اینکه بتوانید از این پکیج استفاده کنید باید در کلاس مورد نظر آن را import کنید.
import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
قبل از ساخت جدول و ذخیره ی اطلاعات نیاز به داشتن مدلی از داده ها داریم که در نمونه ی ما Dog است که دارای یک ایدی منحصر به فرد , نام و سن نیز می باشد پس کلاس مورد نظر برای ساخت این مدل را مطابق با زیر می سازیم.
class Dog {
final int id;
final String name;
final int age;
Dog({this.id, this.name, this.age});
}
قبل از انکه بتوانید اطلاعاتی را از دیتابیس بخوانید با بنویسید باید ان را باز کنید برای اینکار آدرس دیتابیس را تعریف کرده و نام دیتابیس مورد نظر را به آن می دهیم.
final Future<Database> database = openDatabase(
join(await getDatabasesPath(), 'doggie_database.db'),
);
خوب بریم سراغ ساخت جدول مورد نظر که دارای id به عنوان عضو منحصر به فرد است و شامل مقادیر name و در نهایت age نیز میباشد.
final Future<Database> database = openDatabase(
join(await getDatabasesPath(), 'doggie_database.db'),
onCreate: (db, version) {
return db.execute(
"CREATE TABLE dogs(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)",
);
},
version: 1,
);
با استفاده از INTEGER PRIMARY KEY متغیر را منحصر به فرد تعریف کرده تا کار کلید اصلی را انجام دهد و Version مورد نظر را مشخص میکنیم.
تمام این موارد در متد executeانجام میشود.
حالا که یک جدول با یک دیتابیس داریم نیاز داریم که اطلاعاتی را وارد آن کنیم در مرحله ی اول باید مدل ساخته شده خود را به Map تبدیل کنیم سپس از متد insert برای ذخیره در جدول مورد نظر dogs استفاده کنیم.
class Dog {
final int id;
final String name;
final int age;
Dog({this.id, this.name, this.age});
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'age': age,
};
}
}
Future<void> insertDog(Dog dog) async {
final Database db = await database;
await db.insert(
'dogs',
dog.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
final fido = Dog(
id: 0,
name: 'Fido',
age: 35,
);
await insertDog(fido);
حالا که یک Dog در دیتابیس مورد نظر وارد کردیم بیایید آن را از دیتابیس بازیابی کنیم که در نهایت اطلاعات بیرون کشیده شود.
در مرحله ی اول لیستی از Map ایجاد میکنیم و اطلاعات را داخل ان قرار می دهیم سپس ان را به لیست مورد نظر یعنی مدل مان تبدیل می کنیم.
Future<List<Dog>> dogs() async {
final Database db = await database;
final List<Map<String, dynamic>> maps = await db.query('dogs');
return List.generate(maps.length, (i) {
return Dog(
id: maps[i]['id'],
name: maps[i]['name'],
age: maps[i]['age'],
);
});
}
print(await dogs());
بعد از وارد کردن اطلاعات در دیتابیس بعدا شاید نیاز داشته باشیم آن را آپدیت کنیم برای این کار از متد update استفاده می کنیم که نیاز داریم ابتدا به Map اطلاعات جایگزین را تبدیل کنیم و سپس از این متد استفاده کنیم.
Future<void> updateDog(Dog dog) async {
final db = await database;
await db.update(
'dogs',
dog.toMap(),
where: "id = ?",
whereArgs: [dog.id],
);
}
await updateDog(Dog(
id: 0,
name: 'Fido',
age: 42,
));
print(await dogs());
البته یادمان باشه همیشه از whereArgs در این متد به کار بگیریم زیرا از حملات در برابر تزریق Sql محافظت می شود .
برای پاک کردن هم می تونید از متد delete استفاده کنید .
Future<void> deleteDog(int id) async {
final db = await database;
await db.delete(
'dogs',
where: "id = ?",
whereArgs: [id],
);
}
import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
void main() async {
final database = openDatabase(
join(await getDatabasesPath(), 'doggie_database.db'),
onCreate: (db, version) {
return db.execute(
"CREATE TABLE dogs(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)",
);
},
version: 1,
);
Future<void> insertDog(Dog dog) async {
final Database db = await database;
await db.insert(
'dogs',
dog.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<List<Dog>> dogs() async {
final Database db = await database;
final List<Map<String, dynamic>> maps = await db.query('dogs');
return List.generate(maps.length, (i) {
return Dog(
id: maps[i]['id'],
name: maps[i]['name'],
age: maps[i]['age'],
);
});
}
Future<void> updateDog(Dog dog) async {
final db = await database;
await db.update(
'dogs',
dog.toMap(),
where: "id = ?",
whereArgs: [dog.id],
);
}
Future<void> deleteDog(int id) async {
final db = await database;
await db.delete(
'dogs',
where: "id = ?",
whereArgs: [id],
);
}
var fido = Dog(
id: 0,
name: 'Fido',
age: 35,
);
await insertDog(fido);
print(await dogs());
fido = Dog(
id: fido.id,
name: fido.name,
age: fido.age + 7,
);
await updateDog(fido);
print(await dogs());
await deleteDog(fido.id);
print(await dogs());
}
class Dog {
final int id;
final String name;
final int age;
Dog({this.id, this.name, this.age});
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'age': age,
};
}
@override
String toString() {
return 'Dog{id: $id, name: $name, age: $age}';
}
}
امیدوارم از یکی دیگر از آموزش های فلاتر لذت برده باشید .
خیلی خوب بود ♥ دمتون گرم
خیلی ممنون از شما دوست عزیز خوشحالم براتون مفید بوده
سلام، برای یک اپ مثل تلگرام که وقتی واردش میشم بعدش ازمون شماره مگیره و کد … بعدش میرم تو برنامه . خب زمانی که برنامه رو میبندیم و میایم بیرون و دوباره وارد میشیم میبینیم که دیگه برنامه از ما شماره تلفت و … نمیخواد و مستقیم وارد میشه . این یعنی در دیتابیس داخلی برنامه سیو شده و با هر بار باز کردن برنماه دیگه از ما شماره و … نمیخواد …
برای این کار میشه از sqlite استفاده کرد ، اگر میشه، لطفا میشه در بارش یک مثال بزنید. به ایمیلم یا همینجا یک پست در بارش بنویسید.
شما باید بعد از ورود کاربر یک مقداری و ذخیره کنید که متوجه بشید کاربر قبلا وارد شده یا خیر.
راه اصولی ذخیره کردن توکن هست ولی اگر وب سرویس شما بر اساس توکن نیست خودتون داخل یک مقداری را برای ذخیره سازی و چک کردن اینکه کاربر قبلا لاگین شده یا نه قرار بدید.
ممنون ، ولی میشه یک آموزشم در مورد shared preference بزارید…و همینطور توکن ها در shared preference
آموزش درباره SharedPreferences داخل سایت قراره داره میتونید استفاده کنید. توکن هم بحثی هست که داخل وب سرویس باید پیاده سازی بشه.
https://flutter-learn.ir/%d8%a2%d9%85%d9%88%d8%b2%d8%b4-%d8%a7%d8%b3%d8%aa%d9%81%d8%a7%d8%af%d9%87-sharedpreferences-%d8%af%d8%b1-%d9%81%d9%84%d8%a7%d8%aa%d8%b1/
سلام
چطور دیتابیس افلاین خودمون رو در سورس قسمت assets قرار بدیم هیج جا اموزشی نیست
تشمر
سلام
کافی فقط دیتابیس رو داخل پروژه بذارید و داخل فایل pubspec در قسمت asset مسیر دیتابیس و را قرار دهید سپس در کلاس دیتابیس خودتون مسیری که فایل دیتابیس قرار داره را جایگزین کنید.