软件设计:数据库打开和关闭的位置

时间:2012-04-19 09:59:10

标签: android database design-patterns architecture software-design

我正在开发一个Android 3.1应用程序。

这个问题不是针对Android的,而是关于如何设计访问数据库的类。我在这里问,因为我的代码适用于Android。

我有一个类DBManager,可以使用 Sqlite数据库。这是其实施的一部分:

public class DBManager
{
    // Variable to hold the database instance
    private SQLiteDatabase db;
    // Database open/upgrade helper
    private DatabaseHelper dbHelper;

    public DBManager(Context _context)
    {
        Log.v("DBManager", "constructor");
        dbHelper = new DatabaseHelper(_context, SqlConstants.DATABASE_NAME, null, SqlConstants.DATABASE_VERSION);
    }

    public DBManager open() throws SQLException
    {
        Log.v("DBManager", "open");
        db = dbHelper.getWritableDatabase();
        return this;
    }

    public void close()
    {
        Log.v("DBManager", "close");
        db.close();
    }

        ...

        /**
     * Query all forms available locally.
     * @return A list with all forms (form.name and form.FormId) available on local db
     * or null if there was a problem.
     */
    public ArrayList<Form> getAllForms()
    {
        Log.v("DBManager", "getAllForms");
        ArrayList<Form> list = null;
        Cursor c = null;

        try
        {
            c = this.getAllFormsCursor();
            if (c != null)
            {
                int formNameIndex = c.getColumnIndex(SqlConstants.COLUMN_FORM_NAME);
                int formIdIndex = c.getColumnIndex(SqlConstants.COLUMN_FORM_ID);

                c.moveToFirst();
                if (c.getCount() > 0)
                {
                    list = new ArrayList<Form>(c.getCount());
                    do
                    {
                        Form f = new Form();
                        f.Name = c.getString(formNameIndex);
                        f.FormId = c.getString(formIdIndex);
                        list.add(f);
                    }
                    while (c.moveToNext());
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            list = null;
        }
        finally
        {
            if (c != null)
                c.close();
        }
        return list;
    }

    private Cursor getAllFormsCursor()
    {
        Log.v("DBManager", "getAllFormsCursor");

        return db.query(SqlConstants.TABLE_FORM,
                new String[] {
                SqlConstants.COLUMN_FORM_ID,
                SqlConstants.COLUMN_FORM_NAME}, null, null, null, null, null);
    }
}

这是一个使用DBManager

的AsyncTask
private class DbFormListAsyncTask extends AsyncTask<Void, Void, ArrayList<Form>>
{
    private Context mContext;
    private ProgressDialog loadingDialog;
    private DBManager dbMan;

    DbFormListAsyncTask(Context context)
    {
        this.mContext = context;
        loadingDialog = new ProgressDialog(mContext);
        loadingDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        loadingDialog.setMessage("Retriving forms. Please wait...");
        loadingDialog.setCancelable(false);
        loadingDialog.show();
    }

    @Override
    protected ArrayList<Form> doInBackground(Void... arg0)
    {
        dbMan = new DBManager(mContext);
        dbMan.open();

        return dbMan.getAllForms();
    }

    protected void onPostExecute(ArrayList<Form> forms)
    {
        if (forms != null)
        {
            ListActivity act = (ListActivity) mContext;
            act.setListAdapter(new AvaFormAdapter(act, R.layout.ava_list_item, forms));
        }
        else
        {
            TextView errorMsg = (TextView)
                    ((FormsListActivity) mContext).findViewById(R.id.formErrorMsg);
            errorMsg.setText("Problem getting forms. Please try again later.");
        }
        loadingDialog.dismiss();
        if (dbMan != null)
            dbMan.close();
    }
}

如你所见,我必须:

  1. 创建DBManager实例。
  2. 使用dbMan.open()
  3. 打开数据库
  4. 致电dbMan.getAllForms()
  5. dbMan.close()上使用onPostExecute关闭数据库。
  6. 我认为我可以在dbMan.getAllForms()上添加db.open()和db.close(),以避免每次使用dbMan.getAllForms()时都调用它。

    您如何看待这个?什么是最好的方法?

2 个答案:

答案 0 :(得分:0)

我会把它放在getAllForms()里面或做那样的事情

protected ArrayList<Form> doInBackground(Void... arg0)
{
    dbMan = new DBManager(mContext);
    dbMan.open();
    ArrayList<Form> resutl = dbMan.getAllForms();
    dbMan.close();
    return result;
}

由于在获得结果后不需要db连接,因此可以立即关闭它。

编辑:如果你多次运行AsyncTask,那么打开/关闭会带来不必要的开销。在这种情况下,您可能希望从您的Activity实例化dbManager(可能在DbManager的构造函数中打开())并在您离开活动后关闭它。然后将Dbmanager传递给AsyncTask。

答案 1 :(得分:0)

使您的数据库帮助程序类成为单例,并且不要显式关闭SQLiteDatabase。当您的应用程序进程退出时,它将被关闭并刷新。