2011-02-27 16 views
5

Tengo algunos proyectos Android y la mayoría de ellos están conectados con bases de datos SQLite. Me interesa que sea una buena práctica de programación (o un habbit malo) usar alguna clase estática como "DatabaseHelper.class" en la que tendría todo el método estático relacionado para la manipulación de la base de datos. Por ejemplo¿Está bien utilizar la clase estática de "ayudante de base de datos"?

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; 
} 

donde dbinit (contexto)(que se utiliza en todos mis métodos estáticos para manipluation base de datos) es

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

Entonces cuando necesito algo que pueda llamar fácilmente los método (s) con, por ejemplo

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

EDIT: ¿Tengo que usar dbClose en cada conexión o dejarlo abierto por actividad y cerrar por actividad? Entonces, ¿tengo que cambiar ese código superior a algo como esto?

... 
    dbClose(); 

    return id; 
} 

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

Respuesta

6

yo sugeriría que entra en el hábito de conseguir una conexión de base de datos cada vez que lo necesita, y liberar de nuevo cuando haya terminado con él. El nombre habitual para dicha instalación es un "grupo de conexión de base de datos".

Esto mueve la lógica de conexión fuera de su código real y en la piscina, y le permite hacer muchas cosas más adelante cuando los necesite. Una cosa simple, podría ser que el pool registre cuánto tiempo se usó un objeto de conexión para que pueda obtener información sobre el uso de la base de datos.

Su grupo inicial puede ser muy simple si solo necesita una conexión.

+3

un grupo es excesivo para una simple conexión sqlite, ya que solo cuesta 0,2ms abrir, así que haga esto pero omita el grupo –

+0

@Dan, por lo tanto, el "grupo inicial puede ser muy simple" ... –

0

Si va a utilizar un singleton, el requisito mínimo es que lo haga apátrico/sin hilos. Si utiliza el método de getId tal y como está invocaciones concurrentes podrían potencialmente causar toda clase de bichos extraños ...

dbInit(context); 

pueden ser llamados para el hilo A, que luego se detiene el procesamiento antes de llegar a la instrucción de consulta. Posteriormente, el subproceso B ejecuta getId y también llama a dbInit pasando todos juntos en un contexto diferente. El hilo A se reanudará e intentará ejecutar la consulta en el contexto de B.

Tal vez esto no sea un problema en su aplicación, pero yo recomendaría pegar un modificador sincronizado en ese método getId!

5

Definitivamente tendré su código relacionado con la base de datos en una clase separada, pero realmente recomendaría no utilizar una clase estática o Singleton. Puede que se vea bien al principio por la comodidad, pero desafortunadamente combina sus clases, esconde sus dependencias y también dificulta las pruebas unitarias.

La sección drawbacks en wikipedia le ofrece una pequeña descripción de por qué es posible que desee explorar otras técnicas. También puede dirigirse al over here o al over there donde dan ejemplos concretos de una clase que utiliza un singleton de acceso a la base de datos, y cómo el uso de la inyección de dependencia puede resolver algunos de los problemas que mencioné.

Como primer paso, yo recomendaría el uso de una clase normal que se ejemplariza en su constructor, por ejemplo:

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

Como segundo paso, es posible que desee investigar los marcos como RoboGuice para romper el disco dependencia. Su código sería algo así como:

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

Háganos saber si desea más detalles!

Cuestiones relacionadas