2012-04-09 97 views
5

I'working與ORmlite一個數據庫應用程序,我的模式是這樣的:是否有一個DatabaseManager包含所有模型對象的所有功能?

MDL對象..

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

} 

所以我的問題是,它的好處是有一個的DatabaseManager與所有所有功能模型對象,如:

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

等.....

回答

2

每灰色的評論更新。

小心你的「單身」的實施。您的init方法應該是​​,以確保您不會由於併發問題而終止多個DatabaseManager類的實例。我只想在initgetInstance方法結合以下(注意添加synchronized關鍵字):

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

    return instance; 
} 

如要進一步瞭解,由凱文·加利根看看這些博客文章約Single SQLite ConnectionAndroid Sqlite locking(該contributors之一ORMlite )。

更新:

要獲得關於如何組織像getAllCars您的加載方法的問題,我會先建議使他們static,因爲它們不依賴於其他任何東西,除了你的方法,讓您的單身DatabaseManager,當然這也是static。如果您只有少數這些類型的方法,則可以使它們全部爲靜態成員DatabaseManger。如果你有很多,你可以爲一個類型的所有靜態方法創建一個輔助類。

如果您有確實取決於CarMDLMarkMDL給定實例的內部(像你需要一個方法來獲得一些相關參考)的方法,考慮使CarMDLMarkMDL類的這些方法的成員。

+0

我實際上對本地緩存的DAO實例沒有問題。在DaoManager中查找它們需要創建一個對象,並且我不能看到任何懲罰。這是所有示例對象使用的模式。 – Gray 2012-04-09 23:07:07

+0

好吧,結合初始化和getInstance看起來不錯!但我不知道把所有的模型功能在一個類中,會更好地創建一個擴展一些常見方法的接口另一個DAO的?但我不確定這怎麼會是......我有點困惑 – skabo 2012-04-10 13:17:32

+0

看到我更新的答案。 – wsanville 2012-04-10 13:39:54

0

我把應用程序的onCreate我所有的一次性每個應用的工作和我保持應用程序實例本身的引用,所以我可以做很多的任務,而不必亂用synchronized方法或相似。所以我們可以說,我們有一個應用程序(記得把它添加在清單):

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

那麼你的數據庫的輔助類,Manifest.class是你所有的數據類型類的數組:

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"); 
    } 
} 
相關問題