SQFlite In Flutter
SQFlite is a plugin in flutter which is used to store the data. In SQFlite we perform many operations like create, delete, update, etc. This operation is called CRUD Operations. Using this we can easily store the data in a local database.
Table Of Contents::
Introduction:
There are many ways to store the data in flutter but SQFlite is a very easy plugin to store the data locally. SQFlite plugin supports IOS, Android, and macOS. SQFLite is one of the most used and up-to-date packages for linking to SQLite databases in Flutter.
Add Dependency:
In your project go to the pubspec. yaml and add the dependencies under the dependencies: add the latest version of sqflite, into, and flutter_staggered_grid_view.
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
sqflite: ^2.0.0+3
intl: ^0.17.0
flutter_staggered_grid_view: ^0.4.0-nullsafty.3
We use sqflite for database storage, intl is used for DateTime format and flutter_staggered_grid_view is used for display todos in the grid.
Create Database:
- > Create Database: We need to open a connection of the database to reach and write data. And for this, we create a database, and inside of it we want to return our database in case it already exists however if it does not exist then we need to initialize our database and for that, we create new file notes. db and in this we store database. and return the database so that can later make use of it.
Future<Database> get database async {
if (_database != null) return _database!;
_database = await _initDB('notes.db');
return _database!;
}
- > Initialize Database: For initialize database we add a new method where we get the file path. and store our database in our file storage system.
Future<Database> _initDB(String filePath) async {
final dbPath = await getDatabasesPath();
final path = join(dbPath, filePath);
return await openDatabase(path, version: 1, onCreate: _createDB);
}
- > Database Method: we create a _createDB method inside openDatabase(). And inside this method we want to call the database execute method(), we can put our create table statement and define the structure of our table.
Future _createDB(Database db, int version) async {
final idType = 'INTEGER PRIMARY KEY AUTOINCREMENT';
final textType = 'TEXT NOT NULL';
final boolType = 'BOOLEAN NOT NULL';
final integerType = 'INTEGER NOT NULL';
await db.execute('''
CREATE TABLE $tableNotes (
${NoteFields.id} $idType,
${NoteFields.isImportant} $boolType,
${NoteFields.number} $integerType,
${NoteFields.title} $textType,
${NoteFields.description} $textType,
${NoteFields.time} $textType
)
''');
}
Create Model Class:
We create a class Note and here inside we add all the fields which we want to store in our database. To store our node we need to create a table. So we create table name notes.
class Note {
final int? id;
final bool isImportant;
final int number;
final String title;
final String description;
final DateTime createdTime;
const Note({
this.id,
required this.isImportant,
required this.number,
required this.title,
required this.description,
required this.createdTime,
});
And all the fields which we want to create. For that, we create a new class NoteFields in which we define our field name.
CURD Operations:
> Create:
The Sqflite package provides two ways to hold these operations using RawSQL
queries or by using table name and a map that contains the data :
rawInsert:
Future<Note> create(Note note) async {
final db = await instance.database;
final json = note.toJson();
final columns =
'${NoteFields.title}, ${NoteFields.description}, ${NoteFields.time}';
final values =
'${json[NoteFields.title]}, ${json[NoteFields.description]}, ${json[NoteFields.time]}';
final id = await db
.rawInsert('INSERT INTO table_name ($columns) VALUES ($values)');
return note.copy(id: id);
}
Insert:
Future<Note> create(Note note) async {
final db = await instance.database;
final id = await db.insert(tableNotes, note.toJson());
return note.copy(id: id);
}
> Read:
We create a ReadNote and pass id in it. which we have before generated and if you pass down the id inside then we can get from our database the note object again. We define our database and then create a method query(), first we add a table(tableNotes) inside and define all the columns. Create a value list in NoteFiels class. and define which note object you want to read. Use where and whereArgs which prevents SQL injection attacks.
Future<Note> readNote(int id) async {
final db = await instance.database;
final maps = await db.query(
tableNotes,
columns: NoteFields.values,
where: '${NoteFields.id} = ?',
whereArgs: [id],
);
if (maps.isNotEmpty) {
return Note.fromJson(maps.first);
} else {
throw Exception('ID $id not found');
}
}
> Update:
To update our notes we use the update Curd operation. By which we can update the text. ER create an update method in which we pass note object inside. Add the database reference and return the update method and as same we need to define the table which we want to update and secondly, we need to pass the note object and pass JSON object inside.
Future<int> update(Note note) async {
final db = await instance.database;
return db.update(
tableNotes,
note.toJson(),
where: '${NoteFields.id} = ?',
whereArgs: [note.id],
);
}
> Delete:
When we need to delete our object so we use the delete Curd operation. For deleting anything we need to create a method which name is delete(). And pass the note object, therefore we simply call here this method db. delete() and define here a table which we want to delete and lastly we define which object we want to delete.
Future<int> delete(int id) async {
final db = await instance.database;
return await db.delete(
tableNotes,
where: '${NoteFields.id} = ?',
whereArgs: [id],
);
}
Implementation:
In the SQFlite demo first, we take a stateful class. and define a list which name is notes and a bool variable isLoading. after that we create a method refreshNotes() in which we pass isLoading is true and refresh readallnotes(),
Future refreshNotes() async {
setState(() => isLoading = true);
this.notes = await NotesDatabase.instance.readAllNotes();
setState(() => isLoading = false);
}
And pass this method to initstate(). In the BuildContext() we pass the Scaffold and use the property of the appbar. In the body, we pass a method which is buildNotes(), In this method, we pass StaggeredGridView.countBuilder() IN this weight we show all the card which is created, and if there is no card so it shows an empty screen.
Widget buildNotes() => StaggeredGridView.countBuilder(
padding: EdgeInsets.all(8),
itemCount: notes.length,
staggeredTileBuilder: (index) => StaggeredTile.fit(2),
crossAxisCount: 4,
mainAxisSpacing: 4,
crossAxisSpacing: 4,
itemBuilder: (context, index) {
final note = notes[index];
return GestureDetector(
onTap: () async {
await Navigator.of(context).push(MaterialPageRoute(
builder: (context) => NoteDetailPage(noteId: note.id!),
));
refreshNotes();
},
child: NoteCardWidget(note: note, index: index),
);
},
);
At the bottom, we create a FloatingActionButton() which is used for creating new notes. On the click at FloatingActionButton(), its navigate to the AddEditNotePage().
In the AddEditNotePage() we create a form() in which we write our text and we pass a button which name is saved, it is used to save the text. For this, we create a method which name is buildButton() in this we check whether it isFormValid or not.
Widget buildButton() {
final isFormValid = title.isNotEmpty && description.isNotEmpty;
return Padding(
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 12),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
onPrimary: Colors.white,
primary: isFormValid ? null : Colors.grey.shade700,
),
onPressed: addOrUpdateNote,
child: Text('Save'),
),
);
}
In the appbar we define two buttons one is for update and the other one is for deleting the notes. To edit the note we create a method editButton(). at the click of this button, we navigate to the edit page and after editing this its refreshes the page.
Widget editButton() => IconButton(
icon: Icon(Icons.edit_outlined),
onPressed: () async {
if (isLoading) return;
await Navigator.of(context).push(MaterialPageRoute(
builder: (context) => AddEditNotePage(note: note),
));
refreshNote();
});
And the other button which is used for deleting notes, we create a method deleteButton() in which we delete the instance of the note.
Widget deleteButton() => IconButton(
icon: Icon(Icons.delete),
onPressed: () async {
await NotesDatabase.instance.delete(widget.noteId);
Navigator.of(context).pop();
},
);
When we run the application, we ought to get the screen’s output like the underneath screen video.
Conclusion:
In this article, we have been through What is SQFlite in Flutter along with how to implement it in a Flutter. By using we can perform many curd orations. And we can easily add or delete the database locally.
❤ Thanks for reading this article ❤❤
If I got something wrong? Let me know in the comments. I would love to improve.
Clap 👏 If this article helps you.
GitHub Link:
Find the source code of the SQFlite In Flutter :
GitHub – flutter-devs/flutter_sqflite
A new Flutter project. This project is a starting point for a Flutter application. A few resources to get you started…github.com
Feel free to connect with us:
And read more articles from FlutterDevs.com.
FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! You can connect with us on Facebook, GitHub, Twitter, and LinkedIn for any flutter-related queries.
We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.