【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类
这部分我还需要在多消化一下,后续更新

posted @ 2020-03-09 07:36  小陈啊  阅读(250)  评论(0)    收藏  举报