就当前的Android开发环境而言,做Android开发似乎变得越来越简单,的确,Android很容易上手,但是要深入理解并学好,却并不简单。从事Android开发一年来,本人最大的忧虑就是基础不扎实。尽管能胜任目前的工作。但是想要进阶,发现前路迷茫。
人最怕的就是不知道自己想要什么,从而徘徊不前。
额,好像扯远了,下面开始今天的重头戏,Android的小型数据库SQLite。
Android的封装使得我们使用数据库变得方便快捷,尽管目前有很多开源的数据库框架供我们去使用,但是理解并使用原生Android系统所提供的API去构建数据库也是必不可少的。
1、创建数据库,必不可少的需要一些固定的字段,表名,已经数据库名的一些常量的定义,在Android开发文档中,定义这些变量,推荐开发者自己创建一个标准的FeedEntry类,这是一个抽象的静态内部类,这个类implements BaseColumns类,在BaseColumms类中有定义两个字段,一个是_id以及_count,通常我们在创建数据库时都会定义一个自增的_id主键,因此,这样的方式,这显得更高逼格了。这里以创建一个评论数据表为例:
public class FeedEntry {
public FeedEntry() {
}
public abstract static class FeedEntryColumn implements BaseColumns {
//表名
public final static String TABLE_NAME = "kcomment";
//昵称
public final static String KEY_NAME = "name";
//评论内容
public final static String KEY_CONTENT = "content";
//是否是回复
public final static String KEY_REPLY = "reply";
//时间
public final static String KEY_TIME = "time";
//回复的内容
public final static String KEY_REPLY_CONTENT = "reply_content";
//头像
public final static String KEY_AVATAR = "avatar";
//信息
public final static String KEY_INFO = "info";
}
}
2、Android中使用SQLite我们需要创建一个class去继承SQLiteOpenHelper类,并实现SQLiteOpenHelper中的两个抽象方法onCreate()和onUpgrad()。
public class KDataBase extends SQLiteOpenHelper {
private final static String DATABASE_NAME = "kcrason.db";
private final static String SQL_CREATE_COMMENT_TABLE = "CREATE TABLE IF NOT EXISTS " +
FeedEntry.FeedEntryColumn.TABLE_NAME +
" (" + FeedEntry.FeedEntryColumn._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
FeedEntry.FeedEntryColumn.KEY_NAME + " VARCHAR(20), " +
FeedEntry.FeedEntryColumn.KEY_AVATAR + " TEXT, " +
FeedEntry.FeedEntryColumn.KEY_CONTENT + " TEXT, " +
FeedEntry.FeedEntryColumn.KEY_TIME + " VARCHAR, " +
FeedEntry.FeedEntryColumn.KEY_REPLY + " INTEGER, " +
FeedEntry.FeedEntryColumn.KEY_REPLY_CONTENT + " TEXT, " +
FeedEntry.FeedEntryColumn.KEY_INFO + " TEXT)";
public KDataBase() {
super(KApplication.getContext(), DATABASE_NAME, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_COMMENT_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// String sql = "alter table " + TABLE_COMMENT + " add column info text";
// db.execSQL(sql);
}
}
这里很有必要说一下,在首次使用数据库时,其会执行onCreate()方法,而onUpgrade()方法只有在更改onCreate()中的version参数时才会执行。数据库的版本对我们进行数据库的升级很重要。
当
version=1时创建了一个table_name为Table1的表。
version=2我们需要在表中添加一个字段或者新增一张表(假设为Table2)。
version=3时我们依然是新增一张表。(假设为Table3)
那么
onUpgrade()中就需要好好设计。我们注意到在onUpgrade()中返回了oldVersion和newVersion,起初我并不清楚其这样设计的意义。但是如果我们得数据库版本到了version=3的时候,我们就会知道oldVersion的作用了。下面我们详细分析:
当我们数据库的version=3时,而使用version=1/version=2的用户依然存在。
- 完全新用户,执行onCreate()方法,创建最新的数据库及表,没有什么问题。
- version=1的用户,此时apk升级后执行onUpgrade()方法,而这时,通过对比oldVersion我们知道,version=1的用户需要创建两个表,即Table2,Table3。
- version=2的用户,其只需要创建一张表就够了,我们同样可以根据其oldViersion去选择执行哪一段代码。
不容忽视,不容小觑,这就是oldVersion
3、创建好了数据库类之后,我们还需要一个帮助类,来完成数据的存储,更新,删除等一列列操作。
public class KDataBaseHelper {
private static KDataBaseHelper sKDataBaseHelper;
private SQLiteDatabase mSQLiteDatabase;
private KDataBase mKDataBase;
public static KDataBaseHelper form() {
synchronized (KDataBaseHelper.class) {
if (sKDataBaseHelper == null) {
sKDataBaseHelper = new KDataBaseHelper();
}
}
return sKDataBaseHelper;
}
public KDataBaseHelper() {
mKDataBase = new KDataBase();
}
}
- 数据插入
public void insertComment(CommentBean commentBean) {
mSQLiteDatabase = getSQLDataBase();
ContentValues contentValues = new ContentValues();
contentValues.put(FeedEntry.FeedEntryColumn.KEY_NAME, commentBean.name);
contentValues.put(FeedEntry.FeedEntryColumn.KEY_AVATAR, commentBean.avatar);
contentValues.put(FeedEntry.FeedEntryColumn.KEY_CONTENT, commentBean.content);
contentValues.put(FeedEntry.FeedEntryColumn.KEY_REPLY, commentBean.replay);
contentValues.put(FeedEntry.FeedEntryColumn.KEY_REPLY_CONTENT, commentBean.reply_content);
contentValues.put(FeedEntry.FeedEntryColumn.KEY_TIME, commentBean.time);
contentValues.put(FeedEntry.FeedEntryColumn.KEY_INFO, commentBean.info);
mSQLiteDatabase.insert(FeedEntry.FeedEntryColumn.TABLE_NAME, null, contentValues);
close(null);
}
- 数据更新(此处描述的是更新对应_id值等于id的那一行数据的time的值,如果一次想更新多行数据,则循环即可。想要更新哪些值,就使用ContentValues对象put哪些值)
public void updataCommentData(CommentBean commentBean, String id) {
mSQLiteDatabase = getSQLDataBase();
ContentValues contentValues = new ContentValues();
contentValues.put(FeedEntry.FeedEntryColumn.KEY_TIME, commentBean.time);
mSQLiteDatabase.update(FeedEntry.FeedEntryColumn.TABLE_NAME, contentValues, "_id=?", new String[]{id});
close(null);
}
- 分页获取数据(curPage:当前页,从0开始计算;limit:每一页的数量)
public List<CommentBean> getCommentListLimit(int curPage, int limit) {
String startPosition = String.valueOf(curPage * limit);
List<CommentBean> commentBeanList = new ArrayList<>();
mSQLiteDatabase = getSQLDataBase();
if (mSQLiteDatabase != null) {
Cursor cursor = mSQLiteDatabase.query(FeedEntry.FeedEntryColumn.TABLE_NAME,
new String[]{FeedEntry.FeedEntryColumn._ID,
FeedEntry.FeedEntryColumn.KEY_NAME, FeedEntry.FeedEntryColumn.KEY_AVATAR,
FeedEntry.FeedEntryColumn.KEY_CONTENT, FeedEntry.FeedEntryColumn.KEY_REPLY,
FeedEntry.FeedEntryColumn.KEY_REPLY_CONTENT, FeedEntry.FeedEntryColumn.KEY_TIME,
FeedEntry.FeedEntryColumn.KEY_INFO},
null, null, null, null, "time DESC", startPosition + "," + limit);
while (cursor.moveToNext()) {
CommentBean commentBean = new CommentBean();
commentBean._id = cursor.getInt(cursor.getColumnIndex(FeedEntry.FeedEntryColumn._ID));
commentBean.name = cursor.getString(cursor.getColumnIndex(FeedEntry.FeedEntryColumn.KEY_NAME));
commentBean.avatar = cursor.getString(cursor.getColumnIndex(FeedEntry.FeedEntryColumn.KEY_AVATAR));
commentBean.content = cursor.getString(cursor.getColumnIndex(FeedEntry.FeedEntryColumn.KEY_CONTENT));
commentBean.replay = cursor.getInt(cursor.getColumnIndex(FeedEntry.FeedEntryColumn.KEY_REPLY));
commentBean.reply_content = cursor.getString(cursor.getColumnIndex(FeedEntry.FeedEntryColumn.KEY_REPLY_CONTENT));
commentBean.time = cursor.getString(cursor.getColumnIndex(FeedEntry.FeedEntryColumn.KEY_TIME));
commentBean.info = cursor.getString(cursor.getColumnIndex(FeedEntry.FeedEntryColumn.KEY_INFO));
commentBeanList.add(commentBean);
}
close(cursor);
}
return commentBeanList;
}
- 删除数据库所有数据
public void deleteAllComment() {
mSQLiteDatabase = getSQLDataBase();
mSQLiteDatabase.delete(FeedEntry.FeedEntryColumn.TABLE_NAME, null, null);
close(null);
}
- 获取数据库所有记录数
public int getCommentCount() {
mSQLiteDatabase = getSQLDataBase();
Cursor cursor = mSQLiteDatabase.rawQuery("select count(*) from " + FeedEntry.FeedEntryColumn.TABLE_NAME, null);
//cursor.moveToFirst()将cursor移动到第一条数据
cursor.moveToFirst();
int count = cursor.getInt(0);
close(cursor);
return count;
}
- 关闭数据库及Cursor
private void close(Cursor cursor) {
if (cursor != null) {
cursor.close();
}
if (mSQLiteDatabase != null) {
mSQLiteDatabase.close();
}
}