1、SQLiteOpenHelper是一个抽象类,是用于实现创建、打开、升级数据库的最佳实践模式。通过SQLiteOpenHelper可以隐藏用于决定在打开一个数据库之前时候需要创建或者升级的逻辑。
2、等到需要数据库是在创建和打开这些数据库是一个良好的做法。SQLiteOpenHelper会在成功打开数据库实例后缓存它们,所以最佳的实践是在刚好要执行查询或事物前请求打开数据库,除非你不在需要使用数据库,否则无需手动关闭它们。
3、数据库操作(特别是打开或者创建数据库的操作)需要很长时间才能完成,因此为了确保这些操作不会影响用户体验,应将所有数据库事务异步执行。
4、操作SQLite数据库最简单的方式是扩展SQLiteOpenHelper这个抽象类,例如
public class MeinvDbHelper extends SQLiteOpenHelper{
// 数据库的基本参数
public static final String DB_NAME = "meinvDB.db";
// --------------------------------------------------------------
// 数据表的基本描述,表名和表中的列名
public static final String DB_TABLE_MEINV_INFO = "tab_meinv_info";
public static final String KEY_ID = "id";
public static final String KEY_HEAD_PATH = "head_path";
public static final String KEY_NAME = "name";
public static final String KEY_BIRTHDAY = "birthday";
public static final String KEY_ADDRESS = "address";
public static final String KEY_STATURE = "stature";
public static final String KEY_WEIGHT = "weight";
public static final String KEY_BUST = "bust";
public static final String KEY_WAISTLINE = "waistline";
public static final String KEY_HIP = "hip";
// --------------------------------------------------------------
// 创建数据库的SQL语句
private static final String DATABASE_CREATE = String.format(
"create table %s (%s integer primary key autoincrement, %s text not null, %s text not null, %s text not null, %s text not null, %s float not null, %s float not null, %s text not null, %s float not null, %s float not null)",
DB_TABLE_MEINV_INFO,
KEY_ID,
KEY_HEAD_PATH,
KEY_NAME,
KEY_BIRTHDAY,
KEY_ADDRESS,
KEY_STATURE,
KEY_WEIGHT,
KEY_BUST,
KEY_WAISTLINE,
KEY_HIP);
// 定义构造函数
public MeinvDbHelper(Context context, int version)
{
// SQLiteOpenHelper(Context context, String name, CursorFactory factory,
// int version)
// 第一个参数:创建数据库的上下文,比如,如果传入的是com.example.meinvliulanqi.ui.MainActivity的实例,那数据库文件在用户手机中的实际存储位置将是:/data/data/com.example.meinvliulanqi.ui/databases
// 第二个参数:欲创建的数据库的名称,比如名称是meinvDB.db,那么在数据库成功创建完成之后/data/data/com.example.meinvliulanqi.ui/databases路径下就会有meinvDB.db、meinvDB.db-journal两个文件,一个是数据库文件,另一个是日志文件
// 第三、第四个参数:CursorFactory用于产生Cursor对象,version为创建数据库的版本
super(context, DB_NAME, null, version);
}
// 重写onCreate函数,当磁盘上不存在数据库时负责创建新数据库
@Override
public void onCreate(SQLiteDatabase arg0)
{
arg0.execSQL(DATABASE_CREATE);
}
// 重写onUpgrade函数,当存在数据库版本不一致时,升级磁盘上的数据库到当前版本,覆盖安装后可能会出现这种情况
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2)
{
arg0.execSQL("DROP TABLE IF EXIST " + DB_TABLE_MEINV_INFO);
onCreate(arg0);
}
}
5、使用SQLiteOpenHelper的时候,需要调用getWritableDatabase或者getReadableDatabase方法分别来获得数据库的可写或可读实例。当数据库不存在时,onCreate将被触发并执行。如果数据库版本发生了变化onUpgrade函数将会被触发并执行。所以在通常情况下getWritableDatabase或者getReadableDatabase方法总会正确地返回已缓存的、最新版的数据库。
6、数据库打开成功之后,SQLiteOpenHelper将缓存它。由于可能的权限问题,getWritableDatabase存在失败的可能,这时应该使用getReadableDatabase作为getWritableDatabase失败的后备措施。大多数情况下getReadableDatabase将返回与getWritableDatabase相同的、已缓存的、可写的数据库实例。注意:在创建或者升级数据库之前必须以可方式打开数据库,因此好的实践是在尝试访问数据库时,先尝试打开可写数据库,如果失败则打开只读数据库。
7、也可以在不使用SQLiteOpenHelper的情况下操作数据库。
可以通过Context对象的openOrcreateDatabase方法类穿件数据库:
SQLiteDatabase db=context.openOrcreateDatabase(DB_NAME,Context.MODE_PRIVATE,null);
用这种方式创建的数据库必须手动处理新建(数据库可能意外丢失,例如用户手动清除应用程序数据)和升级的逻辑。
在需要时再创建和打开数据库,并在成功打开数据库实例之后缓存它们是一种最佳实践。
创建或打开数据库的操作必须异步执行!