SQLite con sqflite en Flutter: ejercicio resuelto CRUD

  2 minutos

Si necesitas SQLite en Flutter con sqflite, este ejercicio muestra un CRUD mínimo para tareas locales.

Crea una tabla tasks, inserta tareas y lístalas en pantalla.

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

Future<Database> openDb() async {
  return openDatabase(
    join(await getDatabasesPath(), 'tasks.db'),
    version: 1,
    onCreate: (db, _) {
      return db.execute('CREATE TABLE tasks(id INTEGER PRIMARY KEY, title TEXT)');
    },
  );
}

void main() => runApp(const MaterialApp(home: TasksPage()));

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

  @override
  State<TasksPage> createState() => _TasksPageState();
}

class _TasksPageState extends State<TasksPage> {
  final ctrl = TextEditingController();
  List<Map<String, dynamic>> tasks = [];

  Future<void> refreshTasks() async {
    final db = await openDb();
    tasks = await db.query('tasks', orderBy: 'id DESC');
    setState(() {});
  }

  Future<void> addTask() async {
    final db = await openDb();
    await db.insert('tasks', {'title': ctrl.text.trim()});
    ctrl.clear();
    await refreshTasks();
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('sqflite CRUD')),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(12),
            child: Row(
              children: [
                Expanded(child: TextField(controller: ctrl, decoration: const InputDecoration(labelText: 'Tarea'))),
                IconButton(onPressed: addTask, icon: const Icon(Icons.add)),
              ],
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: tasks.length,
              itemBuilder: (_, i) => ListTile(title: Text(tasks[i]['title'] as String)),
            ),
          ),
        ],
      ),
    );
  }
}

Las tareas se guardan localmente y persisten entre sesiones.

  • Crear la base de datos varias veces sin control.
  • No usar await en operaciones de escritura.
  • Mezclar modelo de datos y UI en la misma capa.

Es base para apps offline-first, notas, inventarios y trackers personales.

Sí, para muchos casos offline locales funciona correctamente.

Depende de complejidad. Para apps simples, consultas directas pueden ser suficientes.

No son excluyentes. Muchas apps usan SQLite como cache local y API remota como fuente principal.