正确的方式来打开/关闭数据库?

时间:2016-04-19 22:52:57

标签: java android database sqlite

现在我正在使用SQLOpenHelper类的静态实例,如下所示:

public class DatabaseHelper extends SQLiteOpenHelper {
    private static DatabaseHelper mInstance = null;
    private final Context mContext;

    //...

    public static synchronized DatabaseHelper getInstance(Context context) {
        /**
         * use the application context as suggested by CommonsWare.
         * this will ensure that you don't accidentally leak an Activity's
         * context (see this article for more information:
         * http://android-developers.blogspot.nl/2009/01/avoiding-memory-leaks.html)
         */
        if (mInstance == null) {
            mInstance = new DatabaseHelper(context.getApplicationContext());
        }
        return mInstance;
    }

    private DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
        mContext = context;
    }

    //...
}

然后是DatabaseProcessor类,如此:

public class DatabaseProcessor {

    private SQLiteDatabase mDatabase;
    private DatabaseHelper mSQLHelper;
    private Context mContext;

    public DatabaseProcessor(Context context) {
        mContext = context;
        mSQLHelper = DatabaseHelper.getInstance(mContext);
    }

    public void open() throws SQLException {
        mDatabase = mSQLHelper.getWritableDatabase();
    }

    public void close() {
        mDatabase.close();
    }

   //...
}

因此,如果我想访问我的数据库,我会这样做:

DatabaseProcessor mDatabaseProcessor = new DatabaseProcessor(this);
mDatabaseProcessor.open();
mSomeList = mDatabaseProcessor.doSomeQueryAndReturnResults();
mDatabaseProcessor.close();

这是正确的方法吗?或者更好的是在基础Activity onResume()方法中打开数据库并在onPause()期间关闭它?在尝试运行查询时,如何在数据库未打开的情况下正确抛出错误?

编辑重构版本:

public class DatabaseHelper extends SQLiteOpenHelper {
    private static SQLiteDatabase mDatabase;
    private static DatabaseHelper mInstance = null;
    private static Context mContext;

    // ...

    public static synchronized DatabaseHelper getInstance(Context context) {
        /**
         * use the application context as suggested by CommonsWare.
         * this will ensure that you don't accidentally leak an Activity's
         * context (see this article for more information:
         * http://android-developers.blogspot.nl/2009/01/avoiding-memory-leaks.html)
         */
        if (mInstance == null) {
            mInstance = new DatabaseHelper(context.getApplicationContext());
        }
        return mInstance;
    }

    private DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
        mContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(DB_CREATE_SOME_TABLE); //some SQL expression
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
        db.execSQL(DB_ALTER);
    }

    public void open() throws SQLException {
        mDatabase = getWritableDatabase();
    }

    public void close() {
        mDatabase.close();
    }

    public boolean isOpen() {
        return mDatabase.isOpen();
    }

    //below this would be various CRUD functions operating on mDatabase
    // ...
    // ...
}

1 个答案:

答案 0 :(得分:0)

最好的方法是将您的查询/交易语句放在try-catch中,然后释放所有资源并关闭finally块中的连接。

try{
      mSomeList = mDatabaseProcessor.doSomeQueryAndReturnResults();
} catch(Exception exc){
    //Catch exceptions here
} 
finally{
    if(mDatabaseProcessor != null)
         mDatabaseProcessor.close();
}