Flutter İle Yerel Veri Tabanı Kaydı Nasıl Yapılır?

Flutter İle Yerel Veri Tabanı Kaydı Nasıl Yapılır?
Flutter İle Yerel Veri Tabanı Kaydı Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Projeye başlamadan önce geliştirme ortamınızın güncel olduğundan emin olmalısınız. 2026 standartlarına uygun olarak Flutter 3.x sürümü ve Dart 3.x kullanımı önerilmektedir. Projenize yerel veri tabanı yeteneği kazandırmak için pubspec.yaml dosyanıza gerekli paketleri eklemeniz gerekmektedir.

Aşağıdaki komutları terminalinizde çalıştırarak bağımlılıkları projenize dahil edebilirsiniz:

flutter pub add sqflite path

Burada sqflite, SQLite veritabanı motoruna erişmemizi sağlarken, path paketi cihaz üzerindeki dosya yollarını işletim sisteminden bağımsız (cross-platform) bir şekilde yönetmemize yardımcı olur.

Veri Tabanı Bağlantısını Yapılandırma

Veri tabanı işlemlerini yönetmek için bir "Singleton" yapısı kurmak, uygulamanın her yerinden aynı veri tabanı bağlantısına erişebilmenizi sağlar. Bu, kaynak yönetimi ve performans açısından en iyi pratiktir.

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

class VeritabaniYardimcisi {
  static final VeritabaniYardimcisi instance = VeritabaniYardimcisi._init();
  static Database? _database;

  VeritabaniYardimcisi._init();

  Future get database async {
    if (_database != null) return _database!;
    _database = await _initDB('kullanici_verileri.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 {
    await db.execute('''
      CREATE TABLE kullanicilar (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        isim TEXT NOT NULL,
        yas INTEGER NOT NULL
      )
    ''');
  }
}

Yukarıdaki kod bloğu, uygulama ilk çalıştığında kullanicilar tablosunu oluşturur. _initDB metodu, cihazın yerel depolama alanında veritabanı dosyasının yolunu belirler ve tabloyu tanımlar.

Veri Ekleme (Create) İşlemi

Veri tabanına yeni bir kayıt eklemek için insert metodunu kullanırız. Güvenlik açısından, SQL sorgularını doğrudan birleştirmek yerine (String concatenation), parametreli sorguları tercih etmelisiniz. Bu, SQL Injection saldırılarını önlemek için hayati önem taşır.

Future kullaniciEkle(String isim, int yas) async {
  final db = await instance.database;
  return await db.insert('kullanicilar', {
    'isim': isim,
    'yas': yas,
  });
}

Bu metot, eklenen kaydın ID değerini döndürür. Eğer başarılı olursa, dönen değer 0'dan büyük olacaktır.

Verileri Okuma (Read) İşlemi

Yerel veri tabanından verileri çekmek için query metodunu kullanırız. Bu metot, verileri bir List yapısında döndürür. Aşağıdaki örnekte, tablodaki tüm kullanıcıları listeleyen bir fonksiyon görüyoruz.

Future tumKullanicilariGetir() async {
  final db = await instance.database;
  return await db.query('kullanicilar', orderBy: 'isim ASC');
}

Bu işlem, verileri alfabetik sıraya göre getirir. Uygulama arayüzünde bu verileri göstermek için bir FutureBuilder widget'ı kullanmanız önerilir.

Veri Güncelleme ve Silme

Veri yönetimi, sadece ekleme ve okumadan ibaret değildir. Mevcut verileri değiştirmek veya tamamen kaldırmak da uygulamanın yaşam döngüsü için gereklidir.

// Güncelleme
Future kullaniciGuncelle(int id, String yeniIsim) async {
  final db = await instance.database;
  return await db.update(
    'kullanicilar',
    {'isim': yeniIsim},
    where: 'id = ?',
    whereArgs: [id],
  );
}

// Silme
Future kullaniciSil(int id) async {
  final db = await instance.database;
  return await db.delete(
    'kullanicilar',
    where: 'id = ?',
    whereArgs: [id],
  );
}

whereArgs kullanımı, SQL Injection'a karşı koruma sağlar. Parametreleri doğrudan sorgu metnine yazmak yerine bu listeyi kullanmak, girdilerin temizlenmesini sağlar.

Yerel Veri Tabanı Yöntemlerinin Karşılaştırılması

Yöntem Avantajı Dezavantajı
Sqflite İlişkisel veri, karmaşık sorgular SQL bilgisi gerektirir
Shared Preferences Çok basit ayarlar için hızlı Büyük veride performanssız
Hive Çok hızlı, NoSQL, Dart dostu İlişkisel veri için uygun değil

Kritik Güvenlik Uyarısı: Yerel veri tabanında hassas kullanıcı verilerini (şifre, kredi kartı bilgisi vb.) saklamayın. Eğer saklamanız gerekiyorsa, flutter_secure_storage gibi şifreleme sağlayan kütüphaneleri kullanın ve veritabanı dosyasını şifreleyin (SQLCipher). SQL sorgularınızda asla kullanıcıdan gelen veriyi doğrudan string formatında birleştirmeyin.

Sıkça Sorulan Sorular

Sqflite veritabanını nasıl güncellerim?

Veritabanı şemanızı değiştirmeniz gerektiğinde, openDatabase metodundaki version parametresini artırın ve onUpgrade callback fonksiyonunu kullanarak gerekli ALTER TABLE sorgularını çalıştırın.

Verilerim neden görünmüyor?

Genellikle veritabanı dosyasının doğru yolda oluşturulmaması veya sorgu sonucunun asenkron (Future) olarak işlenmemesinden kaynaklanır. await anahtar kelimesini doğru kullandığınızdan ve veritabanı bağlantısının açık olduğundan emin olun.

Uygulamayı silersem verilerim silinir mi?

Evet, sqflite ile cihazın uygulama dizininde tutulan veriler, uygulama kaldırıldığında işletim sistemi tarafından silinir. Kalıcı veriler için bulut senkronizasyonu kullanmalısınız.

Performans için ne yapmalıyım?

Çok fazla veriniz varsa, sorgularınızı ana iş parçacığında (Main Thread) çalıştırmayın. compute fonksiyonu ile işlemleri arka planda yönetmek, uygulamanın donmasını engeller.

SQLite yerine neden Hive kullanmamalıyım?

Eğer verileriniz arasında ilişkiler (Foreign Key) varsa ve karmaşık filtrelemeler yapmanız gerekiyorsa, SQLite (sqflite) çok daha güvenli ve standart bir seçenektir.

Veritabanı İşlemlerinde Repository Tasarım Deseni

Uygulamanız büyüdükçe, doğrudan UI katmanından veya basit servis sınıflarından veritabanı sorguları yapmak, kodun bakımını zorlaştırır. Repository deseni, veritabanı mantığını iş mantığından ayırarak uygulamanızın daha modüler ve test edilebilir olmasını sağlar.

Aşağıdaki örnekte, veritabanı işlemlerini soyutlayan bir arayüz ve bu arayüzü uygulayan bir sınıf yapısını görebilirsiniz:

abstract class UserRepository {
  Future getAllUsers();
  Future addUser(String name);
}

class SqliteUserRepository implements UserRepository {
  final Database db;

  SqliteUserRepository(this.db);

  @override
  Future getAllUsers() async {
    return await db.query('users');
  }

  @override
  Future addUser(String name) async {
    await db.insert('users', {'name': name});
  }
}

Veritabanı Şeması Geçişleri (Migrations) ve Versiyon Yönetimi

Uygulamanızın yeni sürümlerinde veritabanı yapısını değiştirmeniz gerekebilir (örneğin yeni bir sütun eklemek). Bu durumda onUpgrade parametresini kullanarak eski verileri kaybetmeden şemayı güncelleyebilirsiniz.

Aşağıdaki kod bloğu, veritabanı versiyonu yükseldiğinde yeni bir sütunun nasıl ekleneceğini gösterir:

openDatabase(
  path,
  version: 2,
  onUpgrade: (db, oldVersion, newVersion) async {
    if (oldVersion < 2) {
      await db.execute('ALTER TABLE users ADD COLUMN age INTEGER');
    }
  },
);

Hata Ayıklama (Debugging) İçin İpuçları

Veritabanı işlemlerinde yaşanan sorunları tespit etmek için şu yöntemleri izleyebilirsiniz:

  • SQL Sorgularını Loglamak: sqflite kütüphanesinin sağladığı databaseFactory.setLogLevel(sqfliteLogLevelVerbose) komutu ile tüm sorguları konsola yazdırabilirsiniz.
  • Veritabanı Dosyasını İncelemek: Uygulamanızın veritabanı dosyasını (genellikle /data/user/0/com.paket.adiniz/databases/ dizininde bulunur) bilgisayarınıza çekerek "DB Browser for SQLite" gibi araçlarla içeriğini görsel olarak kontrol edebilirsiniz.
  • İşlem (Transaction) Kullanımı: Veri bütünlüğünü korumak için birden fazla tabloyu etkileyen işlemleri db.transaction bloğu içerisinde gerçekleştirin. Bu, hata durumunda veritabanının eski haline dönmesini (rollback) sağlar.
await db.transaction((txn) async {
  await txn.insert('logs', {'action': 'user_added'});
  await txn.insert('users', {'name': 'Yeni Kullanıcı'});
});

Sonuç

Flutter ile yerel veri tabanı yönetimi, uygulamanızın profesyonellik seviyesini artıran temel bir yetenektir. Bu rehberde, sqflite kullanarak nasıl güvenli bir yapı kuracağınızı, verileri nasıl işleyeceğinizi ve SQL Injection gibi risklerden nasıl korunacağınızı öğrendiniz. Bir sonraki adım olarak, veritabanı işlemlerinizi bir Repository tasarım deseni ile soyutlayarak uygulamanızın test edilebilirliğini artırabilirsiniz. Başarılar dilerim.

Sorumluluk Reddi: Bu rehberde paylaşılan kod örnekleri eğitim amaçlıdır. Uygulamanızın üretim ortamına (Production) geçmeden önce, veritabanı şifreleme ve veri yedekleme stratejilerini projenizin güvenlik gereksinimlerine göre yapılandırmanız önerilir.

Bu yazıya tepkinizi paylaşın:
Selin Demir

Sürdürülebilir yaşam ve kişisel verimlilik üzerine odaklanan bir içerik üreticisiyim. Zaman yönetimi ve organizasyonel ipuçları konusunda okuyuculara yol gösteriyorum.

Yorumlar (0)

Yorum Yaz