Android数据存储-数据库-SQLite
SQLite是一个轻量级的数据库,内置于Android系统中,在Android中使用SQLite的API位于android.database.sqlit。
适用场景
这里讨论的使用场景并不是说SQLite的场景,或者说是在讨论Android中数据库的使用场景(即什么时候该适用数据库来存储数据,而不是使用文件)。
对于重复和结构化的数据适合使用数据库来存储。
使用
契约类
契约类是用于定义 URI、表格和列名称的常数的容器。
契约,从词本身的意义来说是指一方与另一方的约定,这里的一方是指建立此数据库的人,另一方是指想要使用此数据库的人(或者说一方是数据库本身,一方是使用此数据库的人)。建立契约类似乎就像建立了一个对此数据库的说明书(比如它会告诉你数据库的地址是-URI,这个数据库有哪些表,表里有哪些字段),方便使用此数据库的人进行查看。
建立契约类的维度是什么?
个人认为将某一类业务建立一个契约类,而不是每一个表都建立一个契约类。在契约类中创建多个内部类,每个内部类中为一个表。契约类是final的,更多的像是一个常量类。
以笔记为例,示例代码:
public final class NoteContract {
private NoteContract(){}
public static class NoteEntry implements BaseColumns{
public static final String TABLE_NAME = "note";
public static final String COLUMN_NAME_TITLE = "title";
public static final String COLUMN_NAME_DESCRIPTION = "description";
public static final String COLUMN_NAME_TIME="time";
public static final String COLUMN_NAME_USERID="userid";
public static final String COLUMN_NAME_DIRECTORYNAME="directoryname";
}
public static class DirectoryEntry implements BaseColumns{
public static final String TABLE_NAME="directory";
public static final String COLUMN_NAME_DIRECTORY_NAME="directoryname";
public static final String COLUMN_NAME_TIME="time";
}
}
注意:实现BaseColumn接口会默认添加一个唯一的自动增量的ID,这个ID在你的数据是私有数据的时候不是必须的,如果你实现了一个ContentProvider程序,那么这个ID就是必须的。
使用SQLiteOpenHelper创建数据库
使用Android原生相关API创建数据库需要创建一个类实现SQLiteOpenHelper。要创建数据库我们需要建表语句,一般情况下我们也会写上删除表的语句。
示例代码:
public class NoteDbHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = ;
public static final String DATABASE_NAME = "Note.db";
private static final String TEXT_TYPE = " TEXT";
private static final String COMMA_SEP = ",";
private static final String SQL_CREATE_NOTE =
"CREATE TABLE " + NoteContract.NoteEntry.TABLE_NAME + " (" +
NoteContract.NoteEntry._ID + " INTEGER PRIMARY KEY," +
NoteContract.NoteEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
NoteContract.NoteEntry.COLUMN_NAME_DESCRIPTION + TEXT_TYPE + COMMA_SEP +
NoteContract.NoteEntry.COLUMN_NAME_USERID+ TEXT_TYPE + COMMA_SEP +
NoteContract.NoteEntry.COLUMN_NAME_TIME+ TEXT_TYPE + COMMA_SEP +
NoteContract.NoteEntry.COLUMN_NAME_DIRECTORYNAME + TEXT_TYPE + " )";
private static final String SQL_CREATE_DIRECTORY =
"CREATE TABLE " + NoteContract.DirectoryEntry.TABLE_NAME + " (" +
NoteContract.DirectoryEntry._ID + " INTEGER PRIMARY KEY," +
NoteContract.DirectoryEntry.COLUMN_NAME_DIRECTORY_NAME + TEXT_TYPE + COMMA_SEP +
NoteContract.DirectoryEntry.COLUMN_NAME_TIME + TEXT_TYPE + " )";
private static final String SQL_DELETE_NOTE =
"DROP TABLE IF EXISTS " + NoteContract.NoteEntry.TABLE_NAME;
private static final String SQL_DELETE_DIRECTORY=
"DROP TABLE IF EXISTS " + NoteContract.DirectoryEntry.TABLE_NAME;
public NoteDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_NOTE);
db.execSQL(SQL_CREATE_DIRECTORY);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//做数据库升级需要做的事,当newVersion>oldVersion才会被调用
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//做数据库降级(回退)需要做的事,当newVersion<oldVersion才会被调用
}
}
数据库操作-CRUD
要操作Android中SQlite数据库,首先需要获得SQLiteOpenHelper对象,我们一般在应用的Application中初始化并存储这个对象,当程序用到时直接从Application中取。
示例代码:
public class MainApplication extends Application {
private NoteDbHelper noteDbHelper;
@Override
public void onCreate() {
super.onCreate();
initDbHelper();
}
private void initDbHelper(){
noteDbHelper=new NoteDbHelper(this);
}
public NoteDbHelper getNoteDbHelper(){
return noteDbHelper;
}
}
C(CREATE)-插入
像数据库中插入数据,这里我们像Note表中插入一些数据,示例代码:
NoteDbHelper noteDbHelper = ((MainApplication) activity.getApplication()).getNoteDbHelper();
SQLiteDatabase db = noteDbHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(NoteContract.NoteEntry.COLUMN_NAME_TITLE, "title");
contentValues.put(NoteContract.NoteEntry.COLUMN_NAME_USERID, "123456");
contentValues.put(NoteContract.NoteEntry.COLUMN_NAME_TIME, new Date().getTime());
long newRowId = db.insert(NoteContract.NoteEntry.TABLE_NAME, null, contentValues);
R(READ)-查询
从Note表中查询标题为title的数据,示例代码:
NoteDbHelper noteDbHelper = ((MainApplication) activity.getApplication()).getNoteDbHelper();
SQLiteDatabase db = noteDbHelper.getWritableDatabase();
String[] projection = {
NoteContract.NoteEntry.COLUMN_NAME_TITLE,
NoteContract.NoteEntry.COLUMN_NAME_DESCRIPTION,
NoteContract.NoteEntry.COLUMN_NAME_USERID,
NoteContract.NoteEntry.COLUMN_NAME_TIME,
};
String selection = NoteContract.NoteEntry.COLUMN_NAME_TITLE + " = ?";
String[] selectionArgs = {"title"};
Cursor c = db.query(
NoteContract.NoteEntry.TABLE_NAME, // The table to query
projection, // The columns to return
selection, // The columns for the WHERE clause
selectionArgs, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
null // The sort order
);
if(cursor.moveToFirst()){
result=cursor.getString();
}
需要注意的是cursor游标默认是在-1的位置,你需要将它移动到0的位置以后才可以取出数据。
U(UPDATE)-更新
将Note表中的标题为title的数据的标题更新为title2,示例代码:
NoteDbHelper noteDbHelper = ((MainApplication) activity.getApplication()).getNoteDbHelper();
SQLiteDatabase db = noteDbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(NoteContract.NoteEntry.COLUMN_NAME_TITLE, "title");
String selection = NoteContract.NoteEntry.COLUMN_NAME_TITLE + " LIKE ?";
String[] selectionArgs = {"title2"};
int count = db.update(
NoteContract.NoteEntry.TABLE_NAME,
values,
selection,
selectionArgs);
D(DELETE)-删除
将Note表中标题为titile的数据删除,示例代码
NoteDbHelper noteDbHelper = ((MainApplication) activity.getApplication()).getNoteDbHelper();
SQLiteDatabase db = noteDbHelper.getWritableDatabase();
String selection = NoteContract.NoteEntry.COLUMN_NAME_TITLE + " LIKE ?";
String[] selectionArgs = {"title"};
int count = db.delete(NoteContract.NoteEntry.TABLE_NAME, selection, selectionArgs);
参考:
https://developer.android.google.cn/training/basics/data-storage/databases.html
https://developer.android.google.cn/guide/topics/data/data-storage.html#db