拥有所有模型对象的所有函数的DatabaseManager是否合适?

时间:2012-04-09 20:34:59

标签: java android database-design ormlite

我正在使用ORmlite在数据库应用程序上工作,我的模型是这样的:

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)

等.....

3 个答案:

答案 0 :(得分:3)

根据Gray的评论更新。

小心你的“单身”实施。您的init方法应为synchronized,以确保您不会因并发问题而导致DatabaseManager类的多个实例。我只想将initgetInstance方法合并到以下内容中(请注意添加的synchronized关键字):

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

    return instance;
}

如需进一步阅读,请查看Kevin Galligan撰写的关于Single SQLite ConnectionAndroid Sqlite locking的博客文章(contributors至ORMlite之一)。

<强>更新

要回答有关如何整理getAllCars等加载方法的问题,我建议首先制作static,因为除了您的方法之外,他们不依赖于其他任何内容来获取{ {1}},当然也是DatabaseManager。如果您使用少量这些类型的方法,则可以使它们成为static的所有静态成员。如果你有很多,你可以为与类型相对应的所有静态方法创建一个帮助类。

如果您的方法 依赖于DatabaseMangerCarMDL的给定实例的内部(就像您需要一种获取某些相关引用的方法),考虑将这些方法作为MarkMDLCarMDL类的成员。

答案 1 :(得分:0)

我将所有应用程序的一次性工作放在Application onCreate中,并且我保留了应用程序实例本身的引用,因此我可以执行许多任务而无需使用同步方法或类似方法。所以我们假设我们有一个应用程序(记得将它添加到清单中):

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

答案 2 :(得分:0)

将上下文添加到DatabaseManager方法

   @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DatabaseManager.init(this.getContext());
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

带有ormlite的Android应用程序示例 https://github.com/elberthcabrales/cfeMedicion