Flutter CRUD Operations Example: A Step-by-Step Guide with SQLite
CRUD operations—Create, Read, Update, and Delete—are essential for managing data in any application. In this guide, we’ll cover how to implement CRUD operations in Flutter using Dart and an SQLite database. This approach is ideal for apps that need offline data storage and basic database functionalities.
Step 1: Set Up Your Flutter Project and SQLite Database
To get started, follow these steps:
- Create a New Flutter Project: Open your terminal or command prompt, navigate to your preferred directory, and run:
flutter create flutter_crud_example
cd flutter_crud_example
Add Dependencies: Open the pubspec.yaml
file and add sqflite
and path
dependencies. These packages help you work with SQLite databases in Flutter: dependencies:
sqflite: ^2.0.0+4
path: ^1.8.0
Step 2: Define the Database Schema
Let’s create a simple database schema. For this example, we’ll create a Todo
model with properties like id
, title
, and description
.
class Todo {
final int? id;
final String title;
final String description;
Todo({this.id, required this.title, required this.description});
// Convert a Todo into a Map
Map toMap() {
return {
'id': id,
'title': title,
'description': description,
};
}
// Convert a Map into a Todo
factory Todo.fromMap(Map map) {
return Todo(
id: map['id'],
title: map['title'],
description: map['description'],
);
}
}
Step 3: Initialize the Database
Create a new file db_helper.dart
to manage database operations. We’ll set up the database and define the CRUD functions here.
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'todo.dart';
class DatabaseHelper {
static final DatabaseHelper instance = DatabaseHelper._init();
static Database? _database;
DatabaseHelper._init();
Future get database async {
if (_database != null) return _database!;
_database = await _initDB('todo.db');
return _database!;
}
Future _initDB(String filePath) async {
final dbPath = await getDatabasesPath();
final path = join(dbPath, filePath);
return await openDatabase(path, version: 1, onCreate: _createDB);
}
Future _createDB(Database db, int version) async {
const idType = 'INTEGER PRIMARY KEY AUTOINCREMENT';
const textType = 'TEXT NOT NULL';
await db.execute('''
CREATE TABLE Todo (
id $idType,
title $textType,
description $textType
)
''');
}
}
Step 4: Implement CRUD Operations
1. Create Operation
The addTodo
function inserts a new record into the Todo
table.
Future addTodo(Todo todo) async {
final db = await instance.database;
return await db.insert('Todo', todo.toMap());
}
2. Read Operation
The getTodos
function fetches all records from the Todo
table.
Future> getTodos() async {
final db = await instance.database;
final result = await db.query('Todo');
return result.map((json) => Todo.fromMap(json)).toList();
}
3. Update Operation
The updateTodo
function modifies an existing record based on the id
.
Future updateTodo(Todo todo) async {
final db = await instance.database;
return await db.update(
'Todo',
todo.toMap(),
where: 'id = ?',
whereArgs: [todo.id],
);
}
4. Delete Operation
The deleteTodo
function removes a record from the Todo
table.
Future deleteTodo(int id) async {
final db = await instance.database;
return await db.delete(
'Todo',
where: 'id = ?',
whereArgs: [id],
);
}
Step 5: Connect the Database to the UI
Now that you have the CRUD operations in place, it’s time to integrate them into your Flutter UI. For simplicity, here’s how you could use a button to add a new todo:
ElevatedButton(
onPressed: () async {
final todo = Todo(
title: 'Sample Task',
description: 'Description of the sample task',
);
await DatabaseHelper.instance.addTodo(todo);
print('New task added!');
},
child: Text('Add Todo'),
)
Step 6: Test Your CRUD Operations
Testing is crucial to make sure everything works as expected:
- Create: Add a new record and confirm it’s added to the database.
- Read: Fetch all records and display them in a list.
- Update: Modify an existing record and verify the change.
- Delete: Delete a record and ensure it’s removed from the database.
Additional Tips
- Error Handling: Implement error handling with
try-catch
blocks to manage exceptions like database connection failures or invalid queries. - Use Stateful Widgets: For dynamic updates in the UI, such as updating the list of todos after adding or deleting, use
StatefulWidget
. - Explore State Management: Use
Provider
,GetX
, orRiverpod
for better state management if your app scales. - Testing: Write test cases for each CRUD function using Flutter's testing framework to ensure they work correctly.
By following this guide, you’ve built a functional Flutter app with CRUD operations using SQLite. With robust features like data persistence, offline access, and an easy-to-navigate UI, you’re well on your way to creating high-quality Flutter applications.
0 Comments
Please Do Not Comments Any Span Or Span link..