2012-04-09 11 views
5

I'working su un'applicazione db con ORmlite, il mio modello è simile a questo:È utile avere un DatabaseManager con tutte le funzioni di tutti gli oggetti del modello?

MDL oggetto ..

DatabaseTable(tableName = "UserCars") 
public class CarMDL 
{ 
    @DatabaseField(generatedId = true) 
    private int _id; 

    @DatabaseField(columnName = "name") 
    private String _name; 

//................. etc 
} 

// DB Helper class... 

public class DatabaseHelper extends OrmLiteSqliteOpenHelper 
{ 
    private Dao<CarMDL,Integer> _carDao = null; 

@Override 
    public void onCreate(SQLiteDatabase database,ConnectionSource connectionSource) 
    { 
     try 
     { 
      TableUtils.createTable(connectionSource, CarMDL.class); 

     } catch (SQLException e) 
     { 
      throw new RuntimeException(e); 
     } catch (java.sql.SQLException e) 
     { 
      e.printStackTrace(); 
     } 

    } 

    public Dao<CarMDL, Integer> getCarDao() 
    { 
     if (null == _carDao) 
     { 
      try 
      { 
       _carDao = getDao(CarMDL.class); 

      }catch (java.sql.SQLException e) 
      { 
       e.printStackTrace(); 
      } 
     } 
     return _carDao; 
    } 

} 

// DatabaseManager class... 

public class DatabaseManager 
{ 
    static private DatabaseManager instance; 

    private DatabaseHelper helper; 


    static public void init(Context ctx) 
    { 
     if (null == instance) 
     { 
      instance = new DatabaseManager(ctx); 
     } 
    } 

    static public DatabaseManager getInstance() 
    { 
     return instance; 
    } 

    private DatabaseManager(Context ctx) 
    { 
     helper = new DatabaseHelper(ctx); 
    } 

    private DatabaseHelper getHelper() 
    { 
     return helper; 
    } 

// All the Dao functions of all MDL objects are in this class, for example: 

public List<CarMDL> getAllCars() 
    { 
     List<CarMDL> carLists = null; 
     try 
     { 
      carLists = getHelper().getCarDao().queryForAll(); 
     } catch (SQLException e) 
     { 
      e.printStackTrace(); 
     } 
     return carLists; 
    } 

// This is another MDL object.. 

public List<MarkMDL> getAllMarks() 
    { 
     List<MarkMDL> marks = null; 
     try 
     { 
      marks = getHelper().getMarkDao().queryForAll(); 
     } catch (SQLException e) 
     { 
      e.printStackTrace(); 
     } 
     return marks;  
    } 

} 

Quindi la mia domanda è, è bene avere un DatabaseManager con tutte le funzioni di tutto oggetti del modello, come:

listCarById(int id) 
listPlaneById(int id) 
removeCar(int id) 
removePlane(int id) 

Etc .....

risposta

2

aggiornamento per il commento di Grey.

Fai attenzione alla tua implementazione "singleton". Il tuo metodo init dovrebbe essere synchronized per assicurarti di non finire con più istanze della tua classe DatabaseManager a causa di problemi di concorrenza. Vorrei solo combinare le init e getInstance metodi per il seguente (si noti il ​​synchronized parola chiave aggiunto):

public static synchronized DatabaseManager getInstance(Context c) 
{ 
    if(instance == null) 
     instance = new DatabaseManager(c); 

    return instance; 
} 

Per ulteriori letture, prova anche questi post di blog su Single SQLite Connection e Android Sqlite locking da Kevin Galligan (uno dei contributors a ORMlite).

Aggiornamento:

per rispondere alla tua domanda su come organizzare i metodi di caricamento come getAllCars, desidero innanzitutto suggerire che li rende static, dal momento che non dipendono da altro oltre il metodo per ottenere il vostro Singleton di DatabaseManager, che ovviamente sarebbe anche static. Se si dispone di un numero limitato di questi tipi di metodi, è possibile renderli tutti membri statici di DatabaseManger. Se ne hai molti, potresti creare una classe di supporto per tutti i metodi statici corrispondenti a un tipo.

Se si dispone di un metodo che fa dipendono la struttura interna di una determinata istanza di CarMDL o MarkMDL (come avete bisogno di un metodo per ottenere alcuni riferimenti associati), considerare la possibilità di questi metodi membri della classe CarMDL o MarkMDL.

+0

I in realtà non hanno un problema con le istanze DAO memorizzate nella cache locale. Osservandoli nel DaoManager è necessaria la creazione di un oggetto e non c'è penalità che io possa vedere. Questo è il modello usato da tutti gli oggetti di esempio. – Gray

+0

ok, la combinazione di init e getInstance è molto bella! Ma non sono sicuro di mettere tutte le funzioni dei modelli in una singola classe, sarebbe meglio creare un altro DAO che estenda un'interfaccia con alcuni metodi comuni? ma non sono sicuro di come potrebbe essere ... Sono un po 'confuso – skabo

+0

Vedere la mia risposta aggiornata. – wsanville

0

Ho messo tutto il mio lavoro di una volta per app su Application onCreate e tengo un riferimento all'istanza dell'applicazione stessa, così posso svolgere molte attività senza dover fare confusione con metodi sincronizzati o simili. Quindi cerchiamo di dire che abbiamo un'applicazione (ricordati di aggiungerlo nel manifesto):

public class App extends Application 
{ 
    private static App gInstance = null; 
    // your static globals here 

    @Override 
    public void onCreate() 
    { 
     // according to documentation onCreate is called before any other method 
     super.onCreate(); 
     // assign here all your static stuff 
     gInstance = this; 
    } 

    // doesn't need to be synchronized because of the early onCreate 
    public static App getInstance() 
    { 
     return gInstance; 
    } 
} 

allora la vostra classe di supporto di database, Manifest.class è un array di tutte le classi tipo di dati:

public class DatabaseHelper extends OrmLiteSqliteOpenHelper 
{ 
    // private constructor, singleton pattern, we use 
    // App context so the class is created on static init 
    private static DatabaseHelper gHelper = new DatabaseHelper(App.getInstance()); 

    private DatabaseHelper(Context context) 
    { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION, R.raw.ormlite_config); 

     // cache your dao here 
     for (Class<?> cls: Manifest.classes) 
     { 
      try 
      { 
       DaoManager.createDao(getConnectionSource(), cls); 
      } catch (SQLException e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    } 

    // if you need the instance, you don't need synchronized because of static init 
    public static DatabaseHelper getHelper() 
    { 
     return gHelper; 
    } 

    // lookup from cache 
    public static <D extends Dao<T, ?>, T> D getTypeDao(Class<T> cls) 
    { 
     return DaoManager.lookupDao(gHelper.getConnectionSource(), cls); 
    } 

    // we leak this class here since android doesn't provide Application onDestroy 
    // it's not really a big deal if we need the orm mapping for all application lifetime 
    // Q: should I keep the instance closeable? the android finalyzer calls somehow close here? I was unable to reproduce, to be sure you can call the super.close() and print a warning 
    @Override 
    public void close() 
    { 
     throw new RuntimeException("DatabaseHelper Singleton is ethernal"); 
    } 
} 
Problemi correlati