Persisting Data with SQLite Using sqflite

Summary
Summary
Summary
Summary

This tutorial details how to set up the sqflite plugin in Flutter, create models, perform CRUD operations, and display data. It also covers batch operations, schema migrations, and data encryption for secure, high-performance mobile app storage.

This tutorial details how to set up the sqflite plugin in Flutter, create models, perform CRUD operations, and display data. It also covers batch operations, schema migrations, and data encryption for secure, high-performance mobile app storage.

This tutorial details how to set up the sqflite plugin in Flutter, create models, perform CRUD operations, and display data. It also covers batch operations, schema migrations, and data encryption for secure, high-performance mobile app storage.

This tutorial details how to set up the sqflite plugin in Flutter, create models, perform CRUD operations, and display data. It also covers batch operations, schema migrations, and data encryption for secure, high-performance mobile app storage.

Key insights:
Key insights:
Key insights:
Key insights:
  • Local Persistence: SQLite via sqflite enables secure local storage without a backend.

  • Easy Integration: Simple dependency setup and database initialization.

  • CRUD Operations: Models and methods simplify data handling.

  • UI Binding: Load and show data using stateful widgets.

  • Advanced Techniques: Batch inserts, schema migrations, and encryption.

  • Scalable Pattern: Supports complex schemas for robust apps.

Introduction

Persisting data locally is a common requirement for mobile apps. Flutter SQLite integration—using the sqflite plugin—provides a lightweight, high-performance solution. Whether you need a simple key-value store or a fully relational SQLite database, sqflite lets you execute SQL commands and manage data without a remote backend. In this tutorial, you’ll learn how to set up sqflite in your Flutter project, define a data model, create CRUD operations, and display persisted data in your UI.

Adding sqflite to Your Project

Start by adding the required dependencies to your pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  sqflite: ^2.0.0+4
  path

Run flutter pub get to install. The path package helps construct platform-specific file paths for your SQLite file.

Initializing the SQLite Database

Create a singleton database helper to open and initialize your database. Inside lib/db_helper.dart:

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

class DBHelper {
  static final DBHelper _instance = DBHelper._internal();
  factory DBHelper() => _instance;
  DBHelper._internal();

  static Database? _db;

  Future<Database> get database async {
    if (_db != null) return _db!;
    final dbPath = await getDatabasesPath();
    final path = join(dbPath, 'notes.db');
    _db = await openDatabase(
      path,
      version: 1,
      onCreate: (db, version) => db.execute(
        'CREATE TABLE notes(id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT)',
      ),
    );
    return _db!;
  }
}

This setup uses Flutter SQLite via sqflite to open “notes.db”, creating a table for storing note entries.

Defining the Data Model and CRUD Operations

Model classes encapsulate data and map it to rows in your SQLite database. In lib/note.dart:

class Note {
  final int? id;
  final String title;
  final String content;

  Note({this.id, required this.title, required this.content});

  Map<String, dynamic> toMap() {
    return {'id': id, 'title': title, 'content': content};
  }

  factory Note.fromMap(Map<String, dynamic> map) {
    return Note(
      id: map['id'],
      title: map['title'],
      content: map['content'],
    );
  }
}

Expand DBHelper with CRUD methods in db_helper.dart:

// Inside DBHelper class
Future<int> insertNote(Note note) async {
  final db = await database;
  return await db.insert('notes', note.toMap());
}

Future<List<Note>> fetchNotes() async {
  final db = await database;
  final maps = await db.query('notes', orderBy: 'id DESC');
  return List.generate(maps.length, (i) => Note.fromMap(maps[i]));
}

Future<int> updateNote(Note note) async {
  final db = await database;
  return db.update('notes', note.toMap(),
      where: 'id = ?', whereArgs: [note.id]);
}

Future<int> deleteNote(int id) async {
  final db = await database;
  return db.delete('notes', where: 'id = ?', whereArgs: [id]);
}

With these methods, you can insert, retrieve, update, and delete rows in your SQLite database.

Displaying Data in the UI

Use a StatefulWidget to load and display notes. In lib/main.dart:

import 'package:flutter/material.dart';
import 'db_helper.dart';
import 'note.dart';

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: NoteList());
  }
}

class NoteList extends StatefulWidget {
  @override
  _NoteListState createState() => _NoteListState();
}

class _NoteListState extends State<NoteList> {
  late Future<List<Note>> _noteList;

  @override
  void initState() {
    super.initState();
    _refreshNotes();
  }

  void _refreshNotes() {
    _noteList = DBHelper().fetchNotes();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Flutter SQLite Demo')),
      body: FutureBuilder<List<Note>>(
        future: _noteList,
        builder: (ctx, snap) {
          if (!snap.hasData) return Center(child: CircularProgressIndicator());
          final notes = snap.data!;
          return ListView.builder(
            itemCount: notes.length,
            itemBuilder: (_, i) => ListTile(
              title: Text(notes[i].title),
              subtitle: Text(notes[i].content),
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () async {
          await DBHelper().insertNote(
            Note(title: 'New Note', content: 'Details here'),
          );
          setState(_refreshNotes);
        },
      ),
    );
  }
}

This example demonstrates sqflite in action: fetching, displaying, and inserting into an SQLite database.

Advanced Tips

• Batch Operations: Use transactions for bulk inserts to improve performance.

• Migrations: Handle schema changes by passing an onUpgrade callback to openDatabase.

• Encryption: For sensitive data, consider using sqflite_sqlcipher for encrypted SQLite.

Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.

Conclusion

You’ve learned how to integrate Flutter SQLite using the sqflite plugin: adding dependencies, initializing the database, defining models, implementing CRUD operations, and displaying data in widgets. This pattern can scale to more complex schemas and relationships in a robust SQLite database.

With these building blocks, you’re ready to persist complex data and build rich offline experiences in Flutter. Happy coding!

Introduction

Persisting data locally is a common requirement for mobile apps. Flutter SQLite integration—using the sqflite plugin—provides a lightweight, high-performance solution. Whether you need a simple key-value store or a fully relational SQLite database, sqflite lets you execute SQL commands and manage data without a remote backend. In this tutorial, you’ll learn how to set up sqflite in your Flutter project, define a data model, create CRUD operations, and display persisted data in your UI.

Adding sqflite to Your Project

Start by adding the required dependencies to your pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  sqflite: ^2.0.0+4
  path

Run flutter pub get to install. The path package helps construct platform-specific file paths for your SQLite file.

Initializing the SQLite Database

Create a singleton database helper to open and initialize your database. Inside lib/db_helper.dart:

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

class DBHelper {
  static final DBHelper _instance = DBHelper._internal();
  factory DBHelper() => _instance;
  DBHelper._internal();

  static Database? _db;

  Future<Database> get database async {
    if (_db != null) return _db!;
    final dbPath = await getDatabasesPath();
    final path = join(dbPath, 'notes.db');
    _db = await openDatabase(
      path,
      version: 1,
      onCreate: (db, version) => db.execute(
        'CREATE TABLE notes(id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT)',
      ),
    );
    return _db!;
  }
}

This setup uses Flutter SQLite via sqflite to open “notes.db”, creating a table for storing note entries.

Defining the Data Model and CRUD Operations

Model classes encapsulate data and map it to rows in your SQLite database. In lib/note.dart:

class Note {
  final int? id;
  final String title;
  final String content;

  Note({this.id, required this.title, required this.content});

  Map<String, dynamic> toMap() {
    return {'id': id, 'title': title, 'content': content};
  }

  factory Note.fromMap(Map<String, dynamic> map) {
    return Note(
      id: map['id'],
      title: map['title'],
      content: map['content'],
    );
  }
}

Expand DBHelper with CRUD methods in db_helper.dart:

// Inside DBHelper class
Future<int> insertNote(Note note) async {
  final db = await database;
  return await db.insert('notes', note.toMap());
}

Future<List<Note>> fetchNotes() async {
  final db = await database;
  final maps = await db.query('notes', orderBy: 'id DESC');
  return List.generate(maps.length, (i) => Note.fromMap(maps[i]));
}

Future<int> updateNote(Note note) async {
  final db = await database;
  return db.update('notes', note.toMap(),
      where: 'id = ?', whereArgs: [note.id]);
}

Future<int> deleteNote(int id) async {
  final db = await database;
  return db.delete('notes', where: 'id = ?', whereArgs: [id]);
}

With these methods, you can insert, retrieve, update, and delete rows in your SQLite database.

Displaying Data in the UI

Use a StatefulWidget to load and display notes. In lib/main.dart:

import 'package:flutter/material.dart';
import 'db_helper.dart';
import 'note.dart';

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: NoteList());
  }
}

class NoteList extends StatefulWidget {
  @override
  _NoteListState createState() => _NoteListState();
}

class _NoteListState extends State<NoteList> {
  late Future<List<Note>> _noteList;

  @override
  void initState() {
    super.initState();
    _refreshNotes();
  }

  void _refreshNotes() {
    _noteList = DBHelper().fetchNotes();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Flutter SQLite Demo')),
      body: FutureBuilder<List<Note>>(
        future: _noteList,
        builder: (ctx, snap) {
          if (!snap.hasData) return Center(child: CircularProgressIndicator());
          final notes = snap.data!;
          return ListView.builder(
            itemCount: notes.length,
            itemBuilder: (_, i) => ListTile(
              title: Text(notes[i].title),
              subtitle: Text(notes[i].content),
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () async {
          await DBHelper().insertNote(
            Note(title: 'New Note', content: 'Details here'),
          );
          setState(_refreshNotes);
        },
      ),
    );
  }
}

This example demonstrates sqflite in action: fetching, displaying, and inserting into an SQLite database.

Advanced Tips

• Batch Operations: Use transactions for bulk inserts to improve performance.

• Migrations: Handle schema changes by passing an onUpgrade callback to openDatabase.

• Encryption: For sensitive data, consider using sqflite_sqlcipher for encrypted SQLite.

Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.

Conclusion

You’ve learned how to integrate Flutter SQLite using the sqflite plugin: adding dependencies, initializing the database, defining models, implementing CRUD operations, and displaying data in widgets. This pattern can scale to more complex schemas and relationships in a robust SQLite database.

With these building blocks, you’re ready to persist complex data and build rich offline experiences in Flutter. Happy coding!

Build Your Next Flutter App Faster

Build Your Next Flutter App Faster

Build Your Next Flutter App Faster

Build Your Next Flutter App Faster

Vibe Studio combines Flutter with Firebase to create beautiful apps efficiently—no coding required.

Vibe Studio combines Flutter with Firebase to create beautiful apps efficiently—no coding required.

Vibe Studio combines Flutter with Firebase to create beautiful apps efficiently—no coding required.

Vibe Studio combines Flutter with Firebase to create beautiful apps efficiently—no coding required.

Other Insights

Other Insights

Other Insights

Other Insights

Join a growing community of builders today

Join a growing
community

of builders today

Join a growing

community

of builders today

© Steve • All Rights Reserved 2025

© Steve • All Rights Reserved 2025

© Steve • All Rights Reserved 2025

© Steve • All Rights Reserved 2025