2011-02-27 21 views
5

Bazı Android proje var ve bunların çoğu SQLite veritabanları ile bağlanır. İlgilendiğim, "DatabaseHelper.class" gibi bir statik sınıf kullanmak için iyi bir programlama uygulaması (ya da kötü bir habbit), veritabanı manipülasyonu ile ilgili tüm statik yöntemlere sahip olacağım. ÖrneğinStatik "veritabanı yardımcı" sınıfını kullanmak tamam mı?

public static int getId(Context context, String name) { 
    dbInit(context); 

    Cursor result = db.rawQuery("SELECT some_id FROM table WHERE some_name = '" + name + "'", null); 
    result.moveToFirst(); 
    int id = result.getInt(result.getColumnIndex("some_id")); 
    result.close(); 

    return id; 
} 

nerede dbinit (bağlam) Ben kolayca bu yöntem çağırabilir şeye ihtiyacım olduğunda Sonra

private static void dbInit(Context context) { 
    if (db == null) { 
     db = context.openOrCreateDatabase(DATABASE_NAME, Context.MODE_PRIVATE, null); 
    } 
} 

olduğu (veritabanı manipluation için tüm statik yöntemlerde kullanılır)örneğin

int id = DatabaseHelper.getId(this, "Abc"); 

EDIT'e (ler): Her bağlantıda dbClose kullanmalı mıyım yoksa etkinlik başına açık mı bırakmalı ve aktiviteyi kapatmalı mıyım? Öyleyse üst kodun böyle bir şeye değiştiğini mi?

... 
    dbClose(); 

    return id; 
} 

private static void dbClose() { 
    if (db != null) { 
     db.close(); 
    } 
} 

cevap

6

Ben bir veritabanı bağlantınızın bir gerekir her zaman almak ve onunla bittiğinde geri bırakmadan alışkanlığı içine almak öneririz. Böyle bir tesisin genel adı "veritabanı bağlantı havuzu" dır.

Bu gerçek kod dışarı ve havuza bağlantı mantığı taşır ve gereksinim duyduğunuzda daha sonra birçok şey yapmak için izin verir. Basit bir şey, havuzun bir bağlantı nesnesinin ne kadar süre kullanıldığını günlüğe kaydeder, böylece veritabanının kullanımı hakkında bilgi alabilirsiniz.

Sadece tek bir bağlantıya ihtiyacınız varsa, ilk havuzunuz çok basit olabilir. Eğer a tek kullanmaya gidiyoruz

+3

bir havuz, yalnızca 0.2ms'lik bir maliyete sahip olduğu gibi sadece bir sqlite bağlantısı için overkill'tir, bu yüzden bunu yapın ama –

+0

@ Dan havuzunu atlayın, dolayısıyla "başlangıç ​​havuzu çok basit" olabilir ... –

0

çok minimum gereksinim bunu vatansız/ÅŸan yapmalarıdır. bu haliyle size getId yöntemi kullanırsanız eşzamanlı çağrılarında potansiyel garip hatalar her şekilde ...

dbInit(context); 

sonra sorgu deyimi isabet önce işlemeyi durdurur Konu A çağrısında Olabilir neden olabilir. Ardından B iş parçacığı getId yürütür ve aynı zamanda dbInit'i birlikte farklı bir bağlamda iletir. Ardından A iş parçacığı yeniden başlayacak ve B bağlamında sorguyu yürütmeye çalışacaktır.

Belki bu uygulamada bir sorun değil ama bu getId yöntemine senkronize bir değiştirici yapışmasını öneriyoruz!

5

Kesinlikle veritabanı ayrı bir sınıfta kodu ile ilgili olurdu, ama gerçekten statik bir sınıf veya Singleton kullanılmamasını öneriyoruz. İlk etapta rahatlıktan dolayı iyi görünebilir, ama maalesef sınıflarınızı sıkı sıkıya birleştirir, bağımlılıklarını gizler ve ünite testini daha da zorlaştırır.

wikipedia drawbacks bölümde başka tekniklerini keşfetmek isteyebilirsiniz neden küçük bir bakış sağlar. Ayrıca, bir veritabanı erişim singletonunu kullanan bir sınıfın somut örneklerini verdikleri over here veya over there'a da yönelebilirsiniz ve bağımlılık enjeksiyonunun kullanılmasından bahsettiğim bazı sorunları çözebilirim.

İlk adım olarak, ben ex, yapıcınızdan içinde örneğini normal bir sınıf kullanarak öneriyoruz:

public class MyActivity extends Activity {  
    private DBAccess dbAccess; 
    public MyActivity() { 
    dbAccess = new DBAccess(this); 
    }  
} 

ikinci adım olarak, sert kırmaya RoboGuice gibi çerçeveler araştırmak isteyebilirsiniz bağımlılık. You kodu aşağıdaki gibi olacaktır:

public class MyActivity extends Activity {  
    @Inject private DBAccess dbAccess; 
    public MyActivity() { 
    }  
} 

daha fazla ayrıntı istiyorsanız bize iletin!

İlgili konular