2012-04-09 1 views
5

I'working sur une application db avec ORmlite, mon modèle est comme ceci:Est-il bon d'avoir un DatabaseManager avec toutes les fonctions de tous les objets du modèle?

objet .. LDM

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

} 

Ma question est, est-il bon avoir un DatabaseManager avec toutes les fonctions de tous les objets modèle, comme:

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

Etc .....

Répondre

2

Mis à jour par le commentaire de Gray.

Soyez prudent avec votre implémentation "singleton". Votre méthode init doit être synchronized pour vous assurer que vous ne vous retrouverez pas avec plusieurs instances de votre classe DatabaseManager en raison de problèmes de simultanéité. Je voudrais juste combiner les méthodes pour les éléments suivants (notez la valeur ajoutée synchronized mot-clé) init et getInstance:

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

    return instance; 
} 

Pour en savoir plus, consultez ces messages de blog à propos Single SQLite Connection et Android Sqlite locking par Kevin Galligan (un des contributors à ORMlite).

Mise à jour:

Pour répondre à votre question sur la façon d'organiser vos méthodes de chargement comme getAllCars, je voudrais tout d'abord suggérer les faire static, car ils ne dépendent pas de quoi que ce soit d'autre que votre méthode pour obtenir votre singleton DatabaseManager, ce qui bien sûr, serait également static. Si vous avez un petit nombre de ces types de méthodes, vous pouvez les rendre tous membres statiques de DatabaseManger. Si vous en avez plusieurs, vous pouvez créer une classe auxiliaire pour toutes les méthodes statiques correspondant à un type.

Si vous avez une méthode qui -t dépendent de la structure interne d'une instance donnée de CarMDL ou MarkMDL (comme vous avez besoin d'une méthode pour obtenir des références associées), pensez à faire ces membres des méthodes de la classe CarMDL ou MarkMDL.

+0

I En fait, vous n'avez pas de problème avec les instances DAO mises en cache localement. Les regarder dans le DaoManager nécessite une création d'objet et il n'y a pas de pénalité que je puisse voir. C'est le modèle que tous les exemples d'objets utilisent. – Gray

+0

ok, en combinant init et getInstance semble agréable! Mais je ne suis pas sûr de mettre toutes les fonctions des modèles dans une seule classe, serait préférable de créer un autre DAO qui étend une interface avec des méthodes communes? mais je ne suis pas sûr comment cela pourrait être ... Je suis un peu confus – skabo

+0

Voir ma mise à jour de réponse. – wsanville

0

Je mets tout mon travail ponctuel par application dans Application onCreate et je garde une référence de l'instance d'application elle-même, donc je peux faire beaucoup de tâches sans avoir à jouer avec des méthodes synchronisées ou similaires. Alors disons que nous avons une demande (souvenez-vous de l'ajouter dans le manifeste):

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

alors votre classe d'aide de base de données, Manifest.class est un tableau de toutes vos classes de types de données:

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"); 
    } 
} 
Questions connexes