【Android学习】使用SQLite进行数据持久化的实战笔
前一个段时间,在做一个简单的备忘录APP的实战项目,其中我第一次用到了SQLite来进行数据持久化,在此把我的一些理解分享给大家也同时提醒我自己,同时也是为了给自己巩固知识
一、为什么要进行数据持久化
就如同备忘录一样,我们希望每次打开关闭APP后,我们在APP中写的东西能够被存储下来而不是随着APP的关闭而丢失有点类似于,我们要将数据储存在外部硬盘中而不是内存中的感觉
二、简单使用SQLIte所需要使用或者定义的类
1、数据模型:用来保存从数据库中读取或者写入数据库的数据
以备忘录为例,数据模型就是
每一条备忘录的id
每一条备忘录的内容(content)
每一条备忘录的重要程度(重要为1,不重要为0)
2、数据库代理类:用于把来自APP的简单调用转化为对于SQLite数据库的API的调用
相当于把对数据库的基本操作进行封装,使其变得易于使用
3、CursorAdapter类:将继承以抽象方式处理数据访问的标准Android类
我的理解是它提供PP中控件的数据获取与数据库的数据获取之间的桥梁
三、代码实现,以我当时练习的这个实战项目为例
首先是数据模型
省略了各个成员变量的getter和setter方法
public class Reminder { private int mId; private String mContent; private int mImportent; public Reminder(int id, String content, int importent) { mId = id; mContent = content; mImportent = importent; }
然后是数据库代理类 RemindersDbAdapter
首先是对一些数据库常量的定义,比如库名,表名,版本号等等
public static final String COL_ID = "_id"; public static final String COL_CONTENT = "content"; public static final String COL_IMPORTENT = "importent"; // 字段名索引 public static final int INDEX_ID = 0; public static final int INDEX_CONTENT = INDEX_ID + 1; public static final int INDEX_IMPORTENT = INDEX_ID + 2; // 用于日志的TAG public static final String TAG = "RemindersDbAdapter"; // 两个数据库API对象,前者用于打开和关闭数据库,是一个助手类 private DatabaseHelper mDbHelper; private SQLiteDatabase mDb; //库名,表名,版本名 public static final String DATABASE_NAME = "dba_remdrs"; public static final String TABLE_NAME = "tbl_remdrs"; public static final int DATABASE_VERSION = 1; //上下文对象,提供对Android系统的访问 private final Context mCtx; // SQL语句,用于创建数据库 public static final String DATABASE_CREATE = "CREATE TABLE if not exists " + TABLE_NAME + " ( " + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COL_CONTENT + " TEXT, " + COL_IMPORTENT + " INTEGER );";
关于这个SQL语句的说明
一般的CREATE语句没有if not exists,如果不在此加入if not exists那么第二次运行APP时将会报错,因为正在试图以相同的表明创建一个新表,而加上这句之后,只会显示一个warning,提示你该表已存在,而不会报错
另外一个时参数中的 INTEGER PRIMARY KEY AUTOINCREMENT,因为在SQLite中,他会为每个表加上一个rowid,这个可以作为一个隐藏的字段来使用,而且由于每一行的rowid是唯一的,因此可以拿来作为表的id主键, 将字段COL_ID的数据类型指定为INTEGER PRIMARY KEY AUTOINCREMENT,则表示INTEGER PRIMARY KEY AUTOINCREMENT为rowid的别名,在插入数据时,只需要将该字段的值指定为null,则会由引擎自动设定值
另外语句中的TEXT数据类型在SQLite指的是文本或者文本与数字的组合,最多2^16个字符(Access中是255个字符)
数据库的打开与关闭
// open public void open() throws SQLException{ mDbHelper = new DatabaseHelper(mCtx); mDb = mDbHelper.getWritableDatabase(); } // close public void close(){ if (mDbHelper != null){ mDbHelper.close(); } }
然后是关于CURD(创建、读取、更新、删除)操作的实现
// 通过数据来直接写入数据库 public void createReminder(String name,boolean importent){ ContentValues values = new ContentValues(); values.put(COL_CONTENT,name); values.put(COL_IMPORTENT,importent); mDb.insert(TABLE_NAME,null,values); } // 通过数据模型来进行写入 public long createReminder(Reminder reminder){ ContentValues values = new ContentValues(); values.put(COL_CONTENT,reminder.getContent());//Contact name values.put(COL_IMPORTENT,reminder.getImportent());//Contact Phone Number // inseting row return mDb.insert(TABLE_NAME,null,values); } // 从数据库读取内容 public Reminder fetchReminderById(int id){ Cursor cursor = mDb.query(TABLE_NAME,new String[]{COL_ID, COL_CONTENT,COL_IMPORTENT},COL_ID + "=?", new String[]{String.valueOf(id)},null,null,null,null); if (cursor != null) cursor.moveToFirst(); return new Reminder( cursor.getInt(INDEX_ID), cursor.getString(INDEX_CONTENT), cursor.getInt(INDEX_IMPORTENT)); } public Cursor fetchAllReminders(){ Cursor mCursor = mDb.query(TABLE_NAME,new String[]{COL_ID, COL_CONTENT,COL_IMPORTENT}, null,null,null,null,null); if (mCursor != null){ mCursor.moveToFirst(); } return mCursor; } // 更新数据库 public void updataReminder(Reminder reminder){ ContentValues values = new ContentValues(); values.put(COL_CONTENT,reminder.getContent()); values.put(COL_IMPORTENT,reminder.getImportent()); mDb.update(TABLE_NAME,values, COL_ID +"=?",new String[]{String.valueOf(reminder.getId())}); } //删除数据 public void deleteReminderById(int nId){ mDb.delete(TABLE_NAME,COL_ID + "=?",new String[]{String.valueOf(nId)}); } public void deleteAllReminders(){ mDb.delete(TABLE_NAME,null,null); }
关于ContentValues的说明
它是一种数据梭,类似于哈希表,都是储存键值对,不过ContentValues 的Key为String类型,而Value则为基本类型(int等),通过它的put()来放入键值对
关于Cursor
Cursor是每行的集合,它使用moveToFirst()来定位到第一行,定义时需要用到一个数据库中的query函数,这个函数参数有点多
| 数据类型 | 形参名称 | 作用 |
| Boolean | distinct | 为true时,表示每一份数据是唯一的,反之亦然 |
| String | table | 表名 |
| String[] | columns | 要返回的列的名字数组(字段名),为null时返回所有列 |
| String | selection | 用于行的筛选,类似于SQL中的WHERE |
| String[] | selectionArg | 用于替换selection中出现的 ? |
| String | groupby | 设定返回行的分组方式,为null则不分组 |
| String | having | 决定哪一行被放到Cursor的过滤器中(没搞懂) |
| String | orderby | 排序,为null则按默认排序 |
| String | limit | 限制返回的行数 |
| CancellationSignal | cancellationsignal | 取消操作时的信号,没有则为null,有则会在取消操作时抛出operationCanceledException |
其中共有四个参数不同的query函数,10个参数的包含以上所有参数,9个参数的不包含 cancellationsignal ,8个参数的不包含distinct和 cancellationsignal ,7个参数的不包含distinct、limit和 cancellationsignal
我感觉只要理解了query这个函数,上述关于CRUD操作的代码就非常容易理解了
CursorAdapter类
这部分我还需要在多消化一下,后续更新

浙公网安备 33010602011771号