Android原生SQL接口
简单示例
定义Schema
通过定义Scheme
来声明表的表名,表头等信息。
public class CrimeDbSchema {
public static final class CrimeTable {
public static final String NAME = "crimes";
public static final class Cols {
public static final String UUID = "uuid";
public static final String TITLE = "title";
public static final String DATE = "date";
public static final String SOLVED = "solved";
}
}
}
实现SQLiteOpenHelper
SQLiteOpenHelper
类管理数据库的创建、升级、版本号等。
public class CrimeBaseHelper extends SQLiteOpenHelper {
private static final int VERSION = 1;
private static final String DATABASE_NAME = "crimeBase.db";
public CrimeBaseHelper(Context context) {
super(context, DATABASE_NAME, null, VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + CrimeTable.NAME + "(" +
" _id integer primary key autoincrement, " +
CrimeTable.Cols.UUID + ", " +
CrimeTable.Cols.TITLE + ", " +
CrimeTable.Cols.DATE + ", " +
CrimeTable.Cols.SOLVED +
")"
);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }
}
使用SQLiteOpenHelper
打开数据库
- 数据库的生命周期与应用一样,所以应该
getApplicationContext()
来作为数据库的Context
。 - 调用
getWritableDatabase()
时的流程:- 确认目标数据库存在。
- 如果不存在就创建数据库,然后初始化数据(调用
onCreate()
)。 - 如果存在就打开并确认
CrimeDbSchema
是否是最新版本。 - 如果是旧版就升级到新版(调用
onUpgrade()
)。
// ...
private final Context mContext;
private final SQLiteDatabase mDatabase;
// ...
mContext = context.getApplicationContext();
mDatabase = new CrimeBaseHelper(mContext).getWritableDatabase();
// ...
创建ContentValues
类对象
ContentValues values = new ContentValues();
values.put(CrimeTable.Cols.UUID, crime.getId().toString());
values.put(CrimeTable.Cols.TITLE, crime.getTitle());
values.put(CrimeTable.Cols.DATE, crime.getDate().getTime());
values.put(CrimeTable.Cols.SOLVED, crime.isSolved() ? 1 : 0);
增
insert()
第二的参数是String
类型,名为nullColumnHack
,当values
是一个空ContentValues
类型对象时,若不给出第二个参数,可能会SQLite
会说无法插入,如果给出一个String
作为uuid
,可以使SQLite
能插入空ContentValues
类型对象。
// ...
private final SQLiteDatabase mDatabase;
// ...
ContentValues values = getContentValues(c);
mDatabase.insert(CrimeTable.NAME, null, values);
改
// ...
private final SQLiteDatabase mDatabase;
// ...
String uuidString = crime.getId().toString();
ContentValues values = getContentValues(crime);
mDatabase.update(CrimeTable.NAME, values, CrimeTable.Cols.UUID + " = ?", new String[]{uuidString});
查
使用query()
查询,返回类似迭代器的Cursor
类对象。
// ...
private final SQLiteDatabase mDatabase;
// ...
Cursor cursor = mDatabase.query(CrimeTable.NAME, null, whereClause, whereArgs, null, null, null);
删
// ...
private final SQLiteDatabase mDatabase;
// ...
String uuidString = crime.getId().toString();
ContentValues values = getContentValues(crime);
mDatabase.delete(CrimeTable.NAME, whereClause, whereArgs);
CursorWrapper类
创建
用CursorWrapper
类包装Cursor
,使之变得易用。
public class CrimeCursorWrapper extends CursorWrapper {
public CrimeCursorWrapper(Cursor cursor) {
super(cursor);
}
public Crime getCrime() {
String uuidString = getString(getColumnIndex(CrimeTable.Cols.UUID));
String title = getString(getColumnIndex(CrimeTable.Cols.TITLE));
long date = getLong(getColumnIndex(CrimeTable.Cols.DATE));
int isSolved = getInt(getColumnIndex(CrimeTable.Cols.SOLVED));
Crime crime = new Crime(UUID.fromString(uuidString));
crime.setTitle(title);
crime.setDate(new Date(date));
crime.setSolved(isSolved != 0);
return crime;
}
}
使用示例1
CrimeCursorWrapper cursor = /* 获取cursor */;
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
crimes.add(cursor.getCrime());
cursor.moveToNext();
}
cursor.close();
使用示例2
CrimeCursorWrapper cursor = /* 获取cursor */;
try {
if (cursor.getCount() == 0) {
return null;
}
cursor.moveToFirst();
return cursor.getCrime();
}
finally {
cursor.close();
}
注意事项
-
Cursor
类对象或CursorWrapper
类对象用完要close()
。