2012-04-09 32 views
5

I'working trên một ứng dụng db với ORmlite, mô hình của tôi là như thế này:Có tốt một DatabaseManager với tất cả các chức năng từ tất cả các đối tượng mô hình không?

MDL đối tượng ..

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

} 

Vì vậy, câu hỏi của tôi là, là nó tốt có một DatabaseManager với tất cả các chức năng từ khắp nơi các đối tượng mô hình, như:

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

Etc .....

Trả lời

2

cập nhật mỗi comment Gray.

Hãy cẩn thận với việc triển khai "singleton" của bạn. Phương thức init của bạn phải là synchronized để đảm bảo rằng bạn không kết thúc với nhiều phiên bản của lớp DatabaseManager do các vấn đề tương tranh. Tôi sẽ chỉ kết hợp các phương pháp initgetInstance như sau (chú ý thêm synchronized từ khóa):

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

    return instance; 
} 

Để đọc thêm, hãy kiểm tra các bài đăng trên blog về Single SQLite ConnectionAndroid Sqlite locking bởi Kevin Galligan (một trong những contributors để ORMlite).

Cập nhật:

Để trả lời câu hỏi của bạn về làm thế nào để tổ chức phương pháp tải của bạn như getAllCars, đầu tiên tôi sẽ đề nghị làm cho chúng static, vì chúng không phụ thuộc vào bất cứ điều gì khác ngoài phương pháp của bạn để có được singleton lại DatabaseManager, tất nhiên, cũng sẽ là static. Nếu bạn có một số lượng nhỏ các loại phương thức này, bạn có thể biến chúng thành tất cả các thành viên tĩnh của DatabaseManger. Nếu bạn có nhiều, bạn có thể tạo một lớp trợ giúp cho tất cả các phương thức tĩnh tương ứng với một kiểu.

Nếu bạn có một phương pháp mà không phụ thuộc vào bên trong của một trường hợp nhất định CarMDL hoặc MarkMDL (giống như bạn cần một phương pháp để có được một số tài liệu tham khảo liên quan), hãy xem xét đưa ra những phương pháp thành viên của lớp CarMDL hoặc MarkMDL.

+0

tôi thực sự không có vấn đề với các phiên bản DAO được lưu trong bộ nhớ cache cục bộ. Tìm kiếm chúng trong DaoManager đòi hỏi một đối tượng sáng tạo và không có hình phạt mà tôi có thể nhìn thấy. Đó là mẫu mà tất cả các đối tượng ví dụ sử dụng. – Gray

+0

ok, kết hợp init và getInstance có vẻ đẹp! Nhưng tôi không chắc chắn để đặt tất cả các mô hình chức năng trong một lớp duy nhất, sẽ là tốt hơn để tạo ra một DAO khác mà mở rộng một giao diện với một số phương pháp phổ biến? nhưng tôi không chắc làm thế nào điều này có thể được ... Tôi là một chút bối rối – skabo

+0

Xem câu trả lời cập nhật của tôi. – wsanville

0

Tôi đặt tất cả công việc một lần cho mỗi ứng dụng của mình trong ứng dụng onCreate và tôi giữ một tham chiếu về cá thể ứng dụng, vì vậy tôi có thể thực hiện nhiều tác vụ mà không phải gây nhầm lẫn với các phương thức được đồng bộ hóa hoặc tương tự. Vì vậy, giả sử chúng ta có một ứng dụng (nhớ để thêm nó vào manifest):

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

sau đó lớp helper cơ sở dữ liệu của bạn, Manifest.class là một mảng của tất cả các lớp datatype của bạn:

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"); 
    } 
} 
Các vấn đề liên quan