android SqliteHelper的使用

对android数据的操作,通常情况下,我们使用ContentProvider进行数据库的相关操作

但是,很多情况下我们需要使用多表查询或者大数据的事物处理,对SQLiteDatabase进行直接操作,可以方便的处理很多复杂的情况


我们知道在使用ContentProvider进行数据库操作时,不需要我们进行主动的关闭数据库操作

而自己创建的SQLiteDatabase实例,需要考虑好打开和关闭的时机


1. 创建一个继承自SqliteHelper的子类,一般将SqliteHelper设置为单例模式,通常我们使用Application的Context作为数据库的实例参数


2. 调用getWritableDatabase()或getReadableDatabase()可直接获取到数据库对象


3. 使用SqliteHelper获取的SQLiteDatabase对象,直接对数据库进行sql语句操作(便于多表之间的联合查询等),可方便的使用beginTransaction()等方法进行批量的事物处理,提高大数据操作的效率,查询完成后并不需要主动的关闭数据库


4.在应用的开启时进行数据库打开初始化,应用退出时进行数据库的关闭及资源释放



下面是一些描述说明,包括项目中遇到的一些问题:

问题1:在实际过程中并不能完成保证application何时退出(意外情况包括异常退出或内存不足被系统杀死)并关闭数据库

方案:

在应用开启时(通常在application中进行),先对数据库进行关闭再开启,以保障上次资源的释放


问题2:在进行应用升级操作时,由于多线程的操作,可能在安装新应用的过程中还存在工作线程进行数据的操作,如果此时(即应用退出时关闭数据库)会导致数据操作异常--releaseAndUnlock

方案:

需要对增删改查方法进行同步控制




import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.util.Log;

public class DBHelper {
	private static DBHelper sDBHelper = null;
	private SqliteHelper mSqliteHelper = null;

	private DBHelper() {
	}

	public synchronized static DBHelper instance() {
		if (sDBHelper == null) {
			sDBHelper = new DBHelper();
		}

		return sDBHelper;
	}

	public synchronized void open(Context context, String dbName) {
		close();
		mSqliteHelper = new SqliteHelper(context, dbName, null, 1);
	}

	public synchronized void insert(String sql) {
		if (mSqliteHelper == null) {
			return;
		}
		mSqliteHelper.getWritableDatabase().execSQL(sql);
	}

	public synchronized long insert(String table, ContentValues values) {
		if (mSqliteHelper == null) {
			return -1;
		}
		return mSqliteHelper.getWritableDatabase().insert(table, null, values);
	}

	public synchronized int update(String table, ContentValues values,
			String whereClause, String[] whereArgs) {
		if (mSqliteHelper == null) {
			return -1;
		}
		return mSqliteHelper.getWritableDatabase().update(table, values,
				whereClause, whereArgs);
	}

	public synchronized Cursor query(String table, String[] columns,
			String selection, String[] selectionArgs, String groupBy,
			String having, String orderBy) {
		if (mSqliteHelper == null) {
			return null;
		}
		return mSqliteHelper.getReadableDatabase().query(table, columns,
				selection, selectionArgs, groupBy, having, orderBy);
	}

	public synchronized Cursor query(String sql) {
		if (mSqliteHelper == null) {
			return null;
		}
		return mSqliteHelper.getReadableDatabase().rawQuery(sql, null);
	}

	public synchronized int delete(String table, String whereClause,
			String[] whereArgs) {
		if (mSqliteHelper == null) {
			return -1;
		}
		return mSqliteHelper.getReadableDatabase().delete(table, whereClause,
				whereArgs);
	}

	public synchronized void close() {
		if (mSqliteHelper != null) {
			mSqliteHelper.close();
			mSqliteHelper = null;
		}
	}

}

异常日志:
java.lang.NullPointerException
	at android.database.sqlite.SQLiteStatement.releaseAndUnlock(SQLiteStatement.java:293)
	at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:99)
	at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1900)
	at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1839)
	at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:661)
	at android.database.sqlite.SQLiteDatabase.beginTransactionNonExclusive(SQLiteDatabase.java:576)
	at android.database.sqlite.SQLiteStatement.acquireAndLock(SQLiteStatement.java:250)
	at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:115)
	at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1718)
	at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1591

)

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值