- SQLiteOpenHelper
- SQLitDatabase
- SQLitCursor
虽然很久以前就用上 SQLite,但是一直没有整理,在这里做下笔记
不过最后发现来来去去还是同样的东西,在这篇写完之后研究一下用文件来做对数据的持久化
参考并强力推荐 Android SQLite详解
建库建表
SQLiteOpenHelper 类主要用于帮助建数据库和建表
- 继承 SQLiteOpenHelper
public class DatabaseHelper extends SQLiteOpenHelper {
/**
* 数据库的版本,upgrade 可以实现版本的变更
*/
private static final int VERSION = 1;
/**
* 数据库的名字
*/
private static final String DATABASE_NAME = "App";
public DatabaseHelper(Context context){
super(context,DATABASE_NAME,null,VERSION);
}
//数据的类型
private static final String TEXT = "TEXT";
private static final String INTEFER = "INTEFER";
private static final String REAL = "REAL";
//建表语句
private static final String CREATE_NEWS_TABLE
= String.format(Locale.getDefault(),
"create table if not exists %s (" +
"%s %s, "+
"%s %s)",
LocalDatabaseContract.News.NEWS_TABLE_NAME_T,
LocalDatabaseContract.News.NEWS_TITLE,TEXT,
LocalDatabaseContract.News.NEWS_IMGURL,TEXT);
@Override
public void onCreate(SQLiteDatabase db) {
//执行建表语句
db.execSQL(CREATE_NEWS_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//在升级数据库的时候重写该方法
}
}
上面的 LocalDataBaseContract 以枚举的方式来用来保存表的字段 :
public class LocalDatabaseContract {
public enum News{
NEWS_TABLE_NAME,
NEWS_TITLE,
NEWS_IMGURL
}
}
对于数据库的操作
借助 SQLiteOpenHelper 的实例来获取 SQLiteDatabase 类的实例,
mDatabaseHelper = new DatabaseHelper(mContext);
mDatabase = mDatabaseHelper.getWritableDatabase();
一个比较特殊的方法就是
//void execSQL (String sql);
//Execute a single SQL statement that is NOT a SELECT or any other SQL statement that returns data.
mDatabase.execSQL("");
参数里的字符串必须是完整的、标准的 SQL 语句,才可以返回正确的数据。
比如一个插入数据的操作可以这样写:
//往 person 表插入一条 name:UserName,age:18 的数据
mDatabase.execSQL("insert into person(name, age) values('UserName', 18)");
mDatabase.execSQL("insert into person(name, age) values(?,?)", new Object[]{"UserName", 18});
但这种方法比较麻烦,一般还是会使用 SQLiteDatabase 封装好的方法
- 插入数据:
String title = "";
String ImgUrl = "";
//ContentValues 对象,类似一个 map 通过键值对的形式存储值
ContentValues contentValues = new ContentValues();
contentValues.put(LocalDatabaseContract
.News.NEWS_TITLE.toString(),title);
contentValues.put(LocalDatabaseContract
.News.NEWS_IMGURL.toString(),ImgUrl);
//执行插入操作,如果返回值小于 0 代表操作失败
long rowId = mDatabase.insert(
LocalDatabaseContract.News.NEWS_TABLE_NAME.toString()
,null,contentValues);
if (rowId < 0){
//数据库存储失败
}
insert 第一个参数是表名;第二个参数表示如果插入的数据每一个值都为空的话,需要指定此行中某一列的名称,系统将此列设置为NULL,不至于出现错误;第三个数据就是插入的数据。
- 删除数据
//开启事务
mDatabase.beginTransaction();
//删除表内 id 为 7 的数据
mDatabase.delete(LocalDatabaseContract.News.NEWS_TABLE_NAME
, "Id = ?", new String[]{String.valueOf(7)});
//设置事务执行成功
mDatabase.setTransactionSuccessful();
- 更新数据
mDatabase.beginTransaction();
//将 id 为 6 的那条数据的 Long 数据更新为 800
ContentValues contentValues = new ContentValues();
contentValues.put("Long ", 800);
mDatabase.update(LocalDatabaseContract.News.NEWS_TABLE_NAME,
contentValues,
"Id = ?",
new String[]{String.valueOf(6)});
mDatabase.setTransactionSuccessful();
- 查询数据
在数据库的操作中,查询语句向来是最难的,用 SQLite 也不例外。
查询的方法有两个:
public Cursor query(String table,String[] columns,String selection
,String[] selectionArgs,String groupBy,String having,String orderBy,String limit);
另一个其实和 execSQL 差不多
//第二个参数照例是对应 sql 语句里的参数集合
public Cursor rawQuery(String sql, String[] selectionArgs)
在 query 中
table:表名称
columns : 列名称数组
selection : 条件字句,相当于 where
selectionArgs : 条件字句,参数数组
groupBy : 分组列
having : 分组条件
orderBy : 排序列
limit : 分页查询限制
Cursor : 返回值,相当于结果集ResultSet
例如,查询 age 为 18 的用户的数据
mDatabase = ordersDBHelper.getReadableDatabase();
cursor = mDatabase.query(LocalDatabaseContract.News.NEWS_TABLE_NAME,
ORDER_COLUMNS,
"age = ?",
new String[] {"18"},
null, null, null);
if (cursor.getCount() > 0) {
List userList = new ArrayList(cursor.getCount());
while (cursor.moveToNext()) {
User user= parseOrder(cursor);
UserList.add(user);
}
return userList;
}
而这里的返回值是一个 Cursor 类型的数据,这个类是一个游标的作用,可以借助它的方法来遍历查询的结果
getCount();//获取返回结果的总数
isFirst();//是否在第一个
isLast();//是否到了最后
moveToFirst();//移动到第一个
moveToLast();//移动到最后
move(int i);//移动到指定
moveToNext();//移动到下一个
moveToPrevious();//移动到上一个
基本上就这些东西,也不是说很简单,相反查询操作还是很讲究的,但实际上 App 可能更多时候使用文件来缓存数据,只有少数的数据会使用数据库来存储,所以很多时候简单的操作就可以满足要求了。