在Android 开发中,SQLite是用于本地存储的一个重要手段,在项目中经常大量使用,比如QQ、微信等即时通讯应用中通讯录等,本地存储的好处就是即使在没有网络的情况下不影响用户的体验感,如微信即使在无网络的状态下也不影响用户查看通讯录,回话列表等。
- SQLiteOpenHelper的应用:
需要注意的一点是,对于SQLite数据库,多个线程可以对其进行操作,但是同时只能有一个线程对其进行访问,如果多个线程对其访问的话有时会出现异常:
android.database.sqlite.SQLiteException: database is locked,导致的根本原因是由于我们当前的线程对数据库操作完成后将数据库关闭,导致其他线程来进行访问时数据库已经关闭,解决办法就是保持单个SqliteOpenHelper实例,同时对所有数据库操作的方法添加synchronized关键字。Android给我们提供的SQLiteOpenHelper,QLiteOpenHelper对数据库创建、连接管理、版本更新进行了封装SQLiteDataBase提拱了丰富的增、删、改、查的方法,也就是继承后方便我们使用的一个类,我们需要去实现QLiteOpenHelper的这几个方法:
构造函数:
/**
* SQLiteOpenHelper的构造函数,用来创建,打开,操作SQLite数据库.
* 这个方法会被很快返回.因为这个方法只是参数赋值,并没有真正的创建SQLite数据库.
* 只有当getWritableDatabase或者getReadableDatabase被调用时,SQLite数据库才会被真正的创建或打开.
* @param context 进程上下文
* @param name 文件系统存储的数据库文件名称
* @param factory to use for creating cursor objects, or null for the default
* @param version 数据库版本号,初始版本为1
* @param errorHandler 处理Sqlite异常类,默认为null.
*/
public KtwlDBOpenHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
onCreate方法:
在onCreate()方法中主要是对数据库进行一些初始化的工作(数据表的创建)
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
createTables(db);
}
public void createTables(SQLiteDatabase db) {
synchronized (instance) {
// 执行创建表语句
for (String str : DBConstact.CREATE_TABLES) {
db.execSQL(str);
}
}
}
onUpgrade方法:
在onUpgrade()方法中主要是对数据库的一些更新操作,比如我们在数据库在建表之初可能会出现字段不够用的情况,我们在后续的版本中想要添加一些字段而又不需要从新创建一张数据表,就可以在这个方法中执行对数据表的更新
/** @param db The database.
* @param oldVersion The old database version.
* @param newVersion The new database version.
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
- 数据库的具体操作工具Dao,主要就是通过SQLiteOpenHelper对数据库进行初始化工作和一些基本操作(比如打开和关闭数据库),这个管理工具类将在对数据表进行每一步操作(增、删、查、改)时都需要用
package com.gyfccs.easemob.ktwldao;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import ktwl.gyfccs.webclient.account.UserHelper;
import ktwl.gyfccs.webclient.util.LogUtils;
import android.R.bool;
import android.R.interpolator;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.util.Log;
import com.gyfccs.easemob.ktwldb.BaseDao;
/**
* 联系人数据访问对象
* @author Administrator
*
*/
public class ContactDao extends BaseDao {
private static final String TAG = "UserContactDao";
public static String TABLE_NAME_CONTACT = "contact";
public static String COLUMN_CURRENT_USERID = "current_user_id";
public static final String COLUMN_ID = "friend_id";
public static final String COLUMN_NICKNAME = "nickname";
public static final String COLUMN_ICON = "icon";
public static final String COLUMN_TAG = "tag";
public static final String COLUMN_REMARKNAME = "remarkname";
@Override
protected boolean isDBOpen() {
// TODO Auto-generated method stub
return dbHelper.database != null;
}
/* 保存联系人信息 */
public synchronized boolean saveContactInfo(Map<String, String> map) {
boolean bResult = false;
dbHelper.openDB();
if (isDBOpen()) {
//此处执行你的保存SQL语句:dbHelper.database.execSQL(sql);
}
dbHelper.closeDB();
return bResult;
}
/* 查询所有的联系人 */
public synchronized List<Map<String, String>> selectAllContact() {
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
dbHelper.openDB(true);
if (isDBOpen()) {
//此处执行你的查询SQL语句:dbHelper.database.execSQL(sql);
}
dbHelper.closeDB();
return list;
}
}
......
//需要注意的是对数据表的操作只有到操作时才打开,操作完毕后及时关闭。
注:文章仅供参考,也许有不合理之处,欢迎拍砖