Google search engine
HomeStatemanagementCRUD Operation With SQLite In Flutter

CRUD Operation With SQLite In Flutter

Here I don’t have to tell the worth of the Flutter cross-platform framework over and over. It is primarily for building Android and IOS applications with Dart. Could it be said that you are searching for a method for utilizing your Flutter project’s mobile device storage as a database? Simply integrating a SQLite package will do it for you. For all local SQL storage purposes, Flutter has presented the sqflite plugin. So we can accomplish all the nearby local storage-related capabilities through that plugin.

In this article, we will explore the CRUD Operation With SQLite In Flutter. We perceive how to execute a demo program. We will show you the simplest way to put away CRUD, create, update, read, and delete your data on the SQLite database utilizing sqflite package and provider state management. We will utilize an implanted SQLite database engine to store the database in Flutter Android and iOS in your Flutter applications.

For Sqflite:

sqflite 2.2.8+4 | Flutter Package
Flutter plugin for SQLite, a self-contained, high-reliability, embedded, SQL database engine.pub.dev

For path_provider:

path_provider | Flutter Package
Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data…pub.dev

For Provider:

provider | Flutter Package
A wrapper around InheritedWidget to make them easier to use and more reusable.pub.dev

If you’re looking for the best Flutter app development company for your mobile application then feel free to contact us at — support@flutterdevs.com.


Table Of Contents::

Introduction

Implementation

Code Implement

Code File

Conclusion

Github Link



Introduction:

This demo video shows how to perform a CRUD Operation With SQLite in Flutter and how CRUD Operation will work using the sqflite package and provider state management in your Flutter applications. We will show you the simplest way to store away CRUD, create, update, read, and delete your data on the SQLite database. It will be shown on your device.

Demo Module ::


Implementation:

Step 1: Add the dependencies

Add dependencies to pubspec — yaml file.

dependencies:
flutter:
sdk: flutter
sqflite: ^2.2.8+4
path_provider: ^2.1.1
provider: ^6.0.1

Step 2: Import

import 'package:signature/signature.dart';

Step 3: Run flutter packages get in the root directory of your app.

How to implement code in dart file :

You need to implement it in your code respectively:

Create a new dart file called user_model.dart inside the lib folder.

Create the user model which demonstrates the data structure that we want to manipulate inside the database. For this, we should create a class with the required properties and a method to map the data before inserting it into the database.

class UserModel {
int? id;
String name;
String email;
String desc;

UserModel({this.id, required this.name, required this.email, required this.desc});

Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'email': email,
'desc': desc,
};
}

factory UserModel.fromMap(Map<String, dynamic> map) {
return UserModel(
id: map['id'],
name: map['name'],
email: map['email'],
desc: map['desc'],
);
}
}

Create a new dart file called database_helper.dart inside the lib folder.

Declare a function that uses imports to open a database connection. Use a user model class and create insertUser(), getUsers(), updateUser(), and deleteUser() functions.

import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

import '../model/user_model.dart';

class DatabaseHelper {
Database? _database;

Future<Database?> get database async {
if (_database != null) return _database;

_database = await initDatabase();
return _database;
}

Future<Database> initDatabase() async {
String databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'users.db');

return await openDatabase(path, version: 1, onCreate: _onCreate);
}

Future<void> _onCreate(Database db, int version) async {
await db.execute('''
CREATE TABLE users(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
email TEXT,
desc TEXT
)
''');
}

Future<int> insertUser(UserModel user) async {
Database? db = await database;
return await db!.insert('users', user.toMap());
}

Future<List<UserModel>> getUsers() async {
Database? db = await database;
List<Map<String, dynamic>> maps = await db!.query('users');
return List.generate(maps.length, (i) {
return UserModel.fromMap(maps[i]);
});
}

Future<int> updateUser(UserModel user) async {
Database? db = await database;
return await db!.update(
'users',
user.toMap(),
where: 'id = ?',
whereArgs: [user.id],
);
}

Future<int> deleteUser(int id) async {
Database? db = await database;
return await db!.delete('users', where: 'id = ?', whereArgs: [id]);
}
}

Create a new dart file called user_provider.dart inside the lib folder.

We will create the class UserProvider with ChangeNotifier and add it to the inside database function and also create loadUsers(), addUser(), updateUser(), and deleteUser() with notifyListeners().

import 'package:flutter/material.dart';
import 'package:flutter_sqlite_demo/database/database_helper.dart';
import 'package:flutter_sqlite_demo/model/user_model.dart';

class UserProvider with ChangeNotifier {
bool isLoading = false;
List<UserModel> _users = [];
final DatabaseHelper _databaseHelper = DatabaseHelper();

List<UserModel> get users => _users;

Future<void> loadUsers() async {
isLoading = true;
_users = await _databaseHelper.getUsers();
isLoading = false;
notifyListeners();
}

Future<void> addUser(UserModel user) async {
await _databaseHelper.insertUser(user);
notifyListeners();
}

Future<void> updateUser(UserModel user) async {
await _databaseHelper.updateUser(user);
notifyListeners();
}

Future<void> deleteUser(int id) async {
await _databaseHelper.deleteUser(id);
await loadUsers();
}
}

Create a new dart file called user_list_screen.dart inside the lib folder.

In this screen, we will show data when the user creates the data and then show a list of data on this screen. We will add the ListView.builder() method. In this method, we will add the itemCount and itemBuilder. In itemBuilder, we will add a ListTile widget. In this widget, we will add a title, on the subtitle we will add two texts, on the trailing we will add two icons delete, and edit icons.

Consumer<UserProvider>(builder: (context, userProvider, _) {
return userProvider.isLoading
? const Center(child: CircularProgressIndicator())
: userProvider.users.isEmpty
? const Center(
child: Text(
"Data Not Found",
style: TextStyle(fontSize: 18),
))
: Padding(
padding: const EdgeInsets.all(12.0),
child: ListView.builder(
itemCount: userProvider.users.length,
itemBuilder: (context, index) {
final user = userProvider.users[index];
return Card(
elevation: 3,
color: Colors.teal.shade300,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: ListTile(
title: Padding(
padding: const EdgeInsets.only(bottom: 5.0),
child: Text(
user.name,
style: const TextStyle(
fontSize: 18, color: Colors.white),
),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
user.email,
style: const TextStyle(
fontSize: 18, color: Colors.white),
),
const SizedBox(
height: 5,
),
Text(
user.desc,
style: const TextStyle(
fontSize: 18, color: Colors.white),
),
],
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: const Icon(
Icons.edit,
color: Colors.black,
),
onPressed: () {
_navigateToEditUser(context, user);
},
),
IconButton(
icon: const Icon(Icons.delete,
color: Colors.black),
onPressed: () {
userProvider.deleteUser(user.id ?? 0);
},
),
],
),
),
),
);
},
),
);
})

When we run the application, we ought to get the screen’s output like the underneath screen capture.

Output

Create a new dart file called create_user_screen.dart inside the lib folder.

In this screen, the user will create a database. The user fills in all the textformfield and presses the save button then the database creates and shows the data on UserListScreen().

import 'package:flutter/material.dart';
import 'package:flutter_sqlite_demo/database/database_helper.dart';
import 'package:flutter_sqlite_demo/model/user_model.dart';
import 'package:flutter_sqlite_demo/provider/user_provider.dart';
import 'package:flutter_sqlite_demo/screens/user_list_screen.dart';
import 'package:provider/provider.dart';

class CreateUserScreen extends StatefulWidget {

const CreateUserScreen({super.key});

@override
State<CreateUserScreen> createState() => _CreateUserScreenState();
}

class _CreateUserScreenState extends State<CreateUserScreen> {
final TextEditingController nameController = TextEditingController();

final TextEditingController emailController = TextEditingController();

final TextEditingController descController = TextEditingController();

final _formKey = GlobalKey<FormState>();


void _submitForm() async {
if (_formKey.currentState?.validate() ?? false) {
final user = UserModel(
name: nameController.text,
email: emailController.text,
desc: descController.text,
);
Provider.of<UserProvider>(context, listen: false).addUser(user);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const UserListScreen(),),
);
nameController.clear();
emailController.clear();
descController.clear();
}
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Create User'),

),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: nameController,
validator: (value) {
if (value?.isEmpty ?? true) {
return 'Please enter a name';
}
return null;
},
decoration: const InputDecoration(labelText: 'Name'),
),
TextFormField(
controller: emailController,
validator: (input) => !input!.contains('@')
? 'Please enter a valid email'
: null,
//onSaved: (input) => _email = input!,
decoration: const InputDecoration(labelText: 'Email'),
),
TextFormField(
controller: descController,
validator: (value) {
if (value?.isEmpty ?? true) {
return 'Please enter a description';
}
return null;
},
decoration: const InputDecoration(labelText: 'Desc'),
),
const SizedBox(height: 20.0),
ElevatedButton(
onPressed: _submitForm,
child: const Text('Save'),
),
],
),
),
),
);
}
}

When we run the application, we ought to get the screen’s output like the underneath screen capture.

Output

Create a new dart file called edit_user_screen.dart inside the lib folder.

In this screen, the user will update the current data, save the new data from the database, and show the updated data on UserListScreen().

import 'package:flutter/material.dart';
import 'package:flutter_sqlite_demo/model/user_model.dart';
import 'package:flutter_sqlite_demo/provider/user_provider.dart';
import 'package:flutter_sqlite_demo/screens/user_list_screen.dart';
import 'package:provider/provider.dart';

class EditUserScreen extends StatefulWidget {
final UserModel user;

const EditUserScreen({super.key, required this.user});

@override
State<EditUserScreen> createState() => _EditUserScreenState();
}

class _EditUserScreenState extends State<EditUserScreen> {
final _formKey = GlobalKey<FormState>();
final nameController = TextEditingController();
final emailController = TextEditingController();
final descController = TextEditingController();

@override
void initState() {
super.initState();
nameController.text = widget.user.name;
emailController.text = widget.user.email;
descController.text = widget.user.desc;
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Edit User'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: nameController,
decoration: const InputDecoration(labelText: 'Name'),
validator: (value) {
if (value?.isEmpty ?? true) {
return 'Please enter a name';
}
return null;
},
),
TextFormField(
controller: emailController,
decoration: const InputDecoration(labelText: 'Email'),
validator: (input) =>
!input!.contains('@') ? 'Please enter a valid email' : null,
//onSaved: (input) => _email = input!,
),
TextFormField(
controller: descController,
decoration: const InputDecoration(labelText: 'Desc'),
validator: (value) {
if (value?.isEmpty ?? true) {
return 'Please enter a description';
}
return null;
},
),
const SizedBox(height: 20.0),
ElevatedButton(
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
final updatedUser = UserModel(
id: widget.user.id,
name: nameController.text,
email: emailController.text,
desc: descController.text,
);
Provider.of<UserProvider>(context, listen: false)
.updateUser(updatedUser);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const UserListScreen(),
),
);
}
},
child: const Text('Save'),
),
],
),
),
),
);
}
}

When we run the application, we ought to get the screen’s output like the underneath screen capture.

Output

Code File:


import 'package:flutter/material.dart';
import 'package:flutter_sqlite_demo/model/user_model.dart';
import 'package:flutter_sqlite_demo/provider/user_provider.dart';
import 'package:flutter_sqlite_demo/screens/create_user_screen.dart';
import 'package:flutter_sqlite_demo/screens/edit_user_screen.dart';
import 'package:provider/provider.dart';

import '../app_constants.dart';

class UserListScreen extends StatefulWidget {
const UserListScreen({super.key});

@override
_UserListScreenState createState() => _UserListScreenState();
}

class _UserListScreenState extends State<UserListScreen> {
final userProvider =
Provider.of<UserProvider>(AppConstants.globalNavKey.currentContext!);

@override
void initState() {
// TODO: implement initState
userProvider.loadUsers();
super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: const Text('User List'),
),
body: Consumer<UserProvider>(builder: (context, userProvider, _) {
return userProvider.isLoading
? const Center(child: CircularProgressIndicator())
: userProvider.users.isEmpty
? const Center(
child: Text(
"Data Not Found",
style: TextStyle(fontSize: 18),
))
: Padding(
padding: const EdgeInsets.all(12.0),
child: ListView.builder(
itemCount: userProvider.users.length,
itemBuilder: (context, index) {
final user = userProvider.users[index];
return Card(
elevation: 3,
color: Colors.teal.shade300,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: ListTile(
title: Padding(
padding: const EdgeInsets.only(bottom: 5.0),
child: Text(
user.name,
style: const TextStyle(
fontSize: 18, color: Colors.white),
),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
user.email,
style: const TextStyle(
fontSize: 18, color: Colors.white),
),
const SizedBox(
height: 5,
),
Text(
user.desc,
style: const TextStyle(
fontSize: 18, color: Colors.white),
),
],
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: const Icon(
Icons.edit,
color: Colors.black,
),
onPressed: () {
_navigateToEditUser(context, user);
},
),
IconButton(
icon: const Icon(Icons.delete,
color: Colors.black),
onPressed: () {
userProvider.deleteUser(user.id ?? 0);
},
),
],
),
),
),
);
},
),
);
}),
floatingActionButton: FloatingActionButton(
onPressed: () {
_navigateToCreateUser(context);
},
child: const Icon(Icons.add),
),
);
}

void _navigateToCreateUser(BuildContext context) async {
await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const CreateUserScreen()),
);
setState(() {});
}

void _navigateToEditUser(BuildContext context, UserModel user) async {
await Navigator.push(
context,
MaterialPageRoute(builder: (context) => EditUserScreen(user: user)),
);
setusing firebaseState(() {});
}
}

Conclusion:

In the article, I have explained the CRUD Operation With SQLite In Flutter; you can modify this code according to your choice. This was a small introduction to the CRUD Operation With SQLite In Flutter User Interaction from my side, and it’s working using Flutter.

I hope this blog will provide you with sufficient information on Trying the CRUD Operation With SQLite in your Flutter projects. We will show you what the Introduction is. Make a demo program for working on CRUD Operation With SQLite in your Flutter applications. So please try it.

❤ ❤ Thanks for reading this article ❤❤

If I need to correct something? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.Conclusion:


GitHub Link:

find the source code of the Flutter Sqlite Demo:

GitHub – flutter-devs/flutter_sqlite_demo
Contribute to flutter-devs/flutter_sqlite_demo development by creating an account on GitHub.github.com


From Our Parent Company Aeologic

Aeologic Technologies is a leading AI-driven digital transformation company in India, helping businesses unlock growth with AI automation, IoT solutions, and custom web & mobile app development. We also specialize in AIDC solutions and technical manpower augmentation, offering end-to-end support from strategy and design to deployment and optimization.

Trusted across industries like manufacturing, healthcare, logistics, BFSI, and smart cities, Aeologic combines innovation with deep industry expertise to deliver future-ready solutions.

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! For any flutter-related queries, you can connect with us on Facebook, GitHub, Twitter, and LinkedIn.

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.


Need expert help building your Flutter app? Talk to FlutterExperts for architecture, development, and consulting support.

Previous article
Analytical Review of Banker, Player, and Tie Bets in Casino BaccaratBaccarat is frequently identified by the stark simplicity of its wagering structure, where the primary tension lies in choosing between the Banker, the Player, or a Tie. Unlike many card games that invite participants to refine their approach through hand management or tactical adjustments, baccarat requires individuals to set their parameters before the initial deal occurs. Once the wagers are placed on the felt or the digital interface, the action transitions entirely to the croupier or the automated deal engine, rendering the participant a spectator to a process dictated by pre-established drawing rules. This hands-off mechanic is the defining trait of the game, separating it from skill-based card activities and placing it squarely within the realm of pure probability.The Player and Banker bets serve as the foundational choices for most attendees, as these options offer the narrowest house edges found within the game. The Banker bet is statistically favored due to the specific order in which cards are drawn, which inherently provides a subtle advantage. To compensate for this structural tilt, casinos typically apply a commission to winning Banker wagers. Conversely, the Player bet does not incur such a fee, though it carries a slightly higher house percentage over time. Understanding these distinctions allows one to view the table not as a landscape for complex maneuvering, but as a rigid mathematical environment where the odds are baked into the core rules of the game.The Tie bet represents a dramatic divergence from the balanced profile of the other two options. It offers a significantly higher payout, which acts as a powerful attractor for those seeking a singular, high-variance event. However, this potential for a larger reward is directly proportional to the increased difficulty of the outcome occurring. If you examine the mathematical reality of in this context, you will find that the frequency of ties is notably lower than the regular alternating wins of the primary hands. This creates a scenario where the allure of the payout must be weighed against a substantially lower hit rate, often serving as a cautionary example of how payout size correlates with the underlying probability of the event. For additional context, Casino en ligne France can be considered alongside this overview.When assessing how casinos present these wagers, transparency and clear communication of the return-to-player percentages become essential. In digital environments, operators often provide paytables or help files that explicitly detail the house edge associated with each of the three betting sectors. This information is a standard component of consumer protection, ensuring that participants can base their experience on documented facts rather than intuition or folklore. Regulatory bodies require these platforms to undergo rigorous auditing to confirm that the random number generation—or the physical deck shuffle in live dealer settings—aligns with the theoretical probabilities promised to the public.One of the most persistent challenges for participants is avoiding the urge to find patterns in the sequence of results. Because baccarat relies on independent trials, previous hands possess no influence over the next. The temptation to interpret a long run of Banker or Player wins as a trend is a psychological response to an inherently chaotic system. A realistic approach involves acknowledging that every decision point starts from the same probability baseline. Viewing the game through this lens prevents the development of unrealistic expectations, allowing the activity to function purely as a form of controlled amusement rather than an exercise in prediction.Effective engagement with these betting options demands an awareness of the inherent limitations of the game. By acknowledging that neither the Banker nor the Player bet offers a mechanism for individual control, the participant removes the pressure to outperform the dealer. The game remains a closed loop, where the house advantage ensures that outcomes favor the casino across thousands of iterations. Prioritizing this objective view serves as a natural guardrail against the pitfalls of chasing losses or attributing significance to the randomness of the deck. This disciplined outlook ensures that the experience remains rooted in entertainment, reflecting a sound understanding of the structural realities of the table.</p
Next article
RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments