Android: ¿puedo usar una clase SQLiteOpenHelper para varios archivos de base de datos?

Mi aplicación utiliza dos bases de datos (archivos separados). Para manejar estas bases de datos he creado dos clases de ayuda que amplían SQLiteOpenHelper, una para cada base de datos.

Ahora voy a añadir una tercera base de datos y me pregunto si necesito crear otra clase de Helper (y si usé una base de datos 4 y 5 necesitaría incluso más clases de Helper), o puedo usar la misma clase Helper para múltiples Bases de datos

El problema que veo con intentar utilizar sólo una clase de ayuda es que no puedo ver cómo pasar el nombre de los archivos de base de datos individuales al ayudante. En la actualidad el nombre de la base de datos está codificado como un campo estático de cada una de las clases de ayudante, pero si tuviera sólo una clase de Ayudante necesitaría poder pasar los diferentes nombres al Constructor al crear el Ayudante separado objetos; El problema es que el constructor SQLiteOpenHelper parece ser llamado por Android con sólo un parámetro: el Contexto.

Por supuesto que puede. Es sólo una cuestión de su diseño de clase de ayudante. Simplemente puede pasar el nombre de DB a su constructor de clase Helper (junto con la instancia de Context requerida) en lugar de hardcoding:

 public class DBOpenHelper extends SQLiteOpenHelper { public DBOpenHelper(Context context, String dbName, int dbVersion) { super(context, dbName, null, dbVersion); } ... } 

Necesita una clase abstracta que implemente el proceso de actualización descrito aquí. A continuación, amplíe esta clase abstracta para cada una de sus tablas. En su clase abstracta usted debe almacenar las tablas de una manera (lista, hardcoded) así que cuando el onUpgrade dispara usted itera sobre los artículos de la tabla y para cada artículo de la tabla usted hace los pasos descritos. Ellos serán auto actualizados, manteniendo todos sus detalles existentes. Tenga en cuenta que el evento onUpgrade se activa sólo una vez por base de datos, es por eso que necesita iterar sobre todas sus tablas para realizar la actualización de todas ellas. Sólo mantiene un número de versión en toda la base de datos.

  • BeginTransaction
  • Ejecutar una creación de la tabla con if not exists (estamos haciendo una actualización, por lo que la tabla no puede existir todavía, va a fallar alter y drop)
  • Poner en una lista las columnas existentes List<String> columns = DBUtils.GetColumns(db, TableName);
  • Tabla de respaldo (tabla ALTER table " + TableName + " RENAME TO 'temp_" + TableName )
  • Create new table (el esquema de creación de tablas más reciente)
  • Obtener la intersección con las nuevas columnas, esta vez las columnas tomadas de la tabla actualizada ( columns.retainAll(DBUtils.GetColumns(db, TableName)); )
  • Restaurar datos ( String cols = StringUtils.join(columns, ","); db.execSQL(String.format( "INSERT INTO %s (%s) SELECT %s from temp_%s", TableName, cols, cols, TableName)); )
  • Quitar la tabla de respaldo ( DROP table 'temp_" + TableName )
  • SetTransactionSuccessful

(Esto no controla la degradación de la tabla, si cambia el nombre de una columna, no obtiene los datos existentes transferidos como los nombres de columna no coinciden).

.

 public static List<String> GetColumns(SQLiteDatabase db, String tableName) { List<String> ar = null; Cursor c = null; try { c = db.rawQuery("select * from " + tableName + " limit 1", null); if (c != null) { ar = new ArrayList<String>(Arrays.asList(c.getColumnNames())); } } catch (Exception e) { Log.v(tableName, e.getMessage(), e); e.printStackTrace(); } finally { if (c != null) c.close(); } return ar; } public static String join(List<String> list, String delim) { StringBuilder buf = new StringBuilder(); int num = list.size(); for (int i = 0; i < num; i++) { if (i != 0) buf.append(delim); buf.append((String) list.get(i)); } return buf.toString(); } 

Simplemente puede pasar el nombre de DB a su constructor de clase Helper (junto con la instancia de Context requerida) en lugar de la codificación

Aquí está el código:

 /* database helper class */ public class DatabaseOpenHelper extends SQLiteAssetHelper { public DatabaseOpenHelper(Context context,String DATABASE_NAME,int DATABASE_VERSION) { super(context, DATABASE_NAME , null, DATABASE_VERSION); } } /* database access class */ private DatabaseAccess(Context context) { this.openHelper_Anatomy = new DatabaseOpenHelper(context,"Anatomy_hotdata.db",1);//Name of the database 1 this.openHelper_Biochemistry = new DatabaseOpenHelper(context,"Biochemistry_hotdata.db",1); //Name of the database 2 } //instance for database 1 public static DatabaseAccess getInstance_Anatomy(Context context) { if (instance_Anatomy == null) { instance_Anatomy = new DatabaseAccess(context); } return instance_Anatomy; } //instance for database 2 public static DatabaseAccess getInstance_Biochemistry(Context context) { if (instance_Biochemistry == null) { instance_Biochemistry = new DatabaseAccess(context); } return instance_Biochemistry; } /** * Open the database1 connection. */ public void open_Anatomy() { try { this.database_Anatomy = openHelper_Anatomy.getWritableDatabase(); } catch (Exception e) { return; } } /** * Open the database2 connection. */ public void open_Biochemistry() { try { // this.database = openHelper.getWritableDatabase(); this.database_Biochemistry = openHelper_Biochemistry.getWritableDatabase(); } catch (Exception e) { return; } } /** * Close the database connection. */ public void close_Anatomy() { if (this.database_Anatomy != null) { this.database_Anatomy.close(); } } /** * Close the database connection. */ public void close_Biochemistry() { if (this.database_Biochemistry != null) { this.database_Biochemistry.close(); } } 
  • Longitud máxima de Android Sqlite String?
  • SQLite de Android CursorIndexOutOfBounds
  • Multiple OrderBy en el método SQLiteDatabase.Query
  • Uso de la palabra clave IN en android sqlite
  • Base de datos SQLite para aplicaciones de Android con múltiples usuarios potenciales
  • SQLiteException no se captura
  • ¿Por qué algunos métodos SQLite esperan argumentos como un objeto , mientras que otros necesitan una cadena ?
  • Obteniendo la última fila de la base de datos sqlite
  • Devolver datos de AsyncTask Android
  • Android: Cómo sumar todas las columnas de una base de datos SQLite y devolver 1 variable única
  • ¿Cómo acceder a Android a una base de datos sqlite incluida en la carpeta de activos?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.