不会点SQLite,都不好意思说自己是开发的



一、为什么要会点SQLite?

SQLite作为一款轻量级的关系型数据库,占用的资源特别少,所以其应用场景也是特别的多。在移动开发中,我们经常会有将数据存储在本地的需求,此时SQLite将是我们最佳的选择。
可喜的是,SQLite已经被完美的集成在Android系统中,所以对于开发者而言,上手SQLite的难度又降低了不少。

二、开始玩玩SQLite

首先来说说在Android中操作SQLite数据库的整体思路:

1、自定义数据库操作辅助类,并继承自SQLiteOpenHelper类;
2、在Application中初始化SQLiteOpenHelper对象,并公开一个方法供其他类调用获取该对象;
3、根据SQLiteOpenHelper对象实例化SQLiteDatabase对象;
4、最后,我们拿SQLiteDatabase对象即可进行SQLite数据库的常规操作了。

其实整个流程并不复杂,稍微来点耐心,动动手指头,再回头瞧瞧SQLite,“哇哦,操作你如此简单!”

1、自定义数据库操作辅助类,并继承自SQLiteOpenHelper类

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
  * author:silencezwm on 16/6/20 06:43
  * email:silencezwm@gmail.com
  * description:数据库操作辅助类
  */
public class DBHelper extends SQLiteOpenHelper {

    //数据库名称
    private static final String DBName = "study.db";
    //数据库版本号
    private static final int DBVersion = 1;

    //构造方法
    public DBHelper(Context context) {
        super(context, DBName, null, DBVersion);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建表---study
        db.execSQL("CREATE TABLE study ( _id integer PRIMARY KEY AUTOINCREMENT NOT NULL, bookName varchar, bookDesc varchar)");
    }

    /**
      * 数据库版本更新
      * @param db            数据库实例
      * @param oldVersion    旧版本号
      * @param newVersion    新版本号
      */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS study");
        onCreate(db);
    }
}

该类继承了SQLiteOpenHelper,并实现了三个方法,其中onCreate()在数据库初始化时会调用,onUpgrade()方法只有在数据库新版本号大于旧版本号时才会调用,即进行数据库的更新操作。其中涉及到了常用SQL语句的书写,看不懂的童鞋得抽空脑补一下这方面的知识哦。

SQLiteOpenHelper有什么用?

该SQLiteOpenHelper是Android平台提供给我们的数据库辅助类,用于创建或打开数据库。

2、在Application中初始化SQLiteOpenHelper对象,并公开一个方法供其他类调用获取该对象

考虑到整个应用中的不同地方都有可能涉及到数据库的操作,所以我们有必要将该类的初始化放在我们自定义的Application类中。就像该下:

public class MyApp extends Application {

    //数据库辅助类实例
    private static DBHelper mDBHelper;

    @Override
    public void onCreate() {
        super.onCreate();
        mDBHelper = new DBHelper(getApplicationContext());
    }

    //返回DBHelper实例,
    public static DBHelper getmDBHelper(){
        return mDBHelper;
    }
}

我们来看看初始化SQLiteOpenHelper类源码的实现方式

public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {
    this(context, name, factory, version, null);
}

参数含义解析:

context:上下文对象,这里我们传入了ApplicationContext;
name:数据库名称,这里我们定义为"study.db";
factory:操作数据库后返回的默认Cursor对象,这里我们默认为null,后续需要保存返回的Cursor对象时,自己再进行构造;
version:数据库的版本号,初始版本号必须大于1,否则系统会抛IllegalArgumentException("Version must be >= 1, was " + version)异常。

3、根据SQLiteOpenHelper对象实例化SQLiteDatabase对象

该操作将会让我们得到SQLiteDatabase对象,而一旦有了该对象,我们就可以进行数据库的增删改查操作了。该操作我们可以单独封装在某个类,同样也可以直接在某个Activity中实现。
核心代码如下:

//获取的数据库对象
//其中 getWritableDatabase() 和 getReadableDatabase() 区别???
SQLiteDatabase db = MyApp.getmDBHelper().getWritableDatabase();
//SQLiteDatabase db = MyApp.getmDBHelper(). getReadableDatabase();

得到SQLiteDatabase实例有以上两种方法,两种方法的主要区别在于:

在数据库仅开放只读权限或磁盘已满时,getReadableDatabase只会返回一个只读的数据库对象。

另外在我们每次初始化SQLiteDatabase对象时,系统都会进行数据库版本号的判断,该判断的核心代码如下(有兴趣的童鞋可以研究下getWritableDatabase()、getReadableDatabase()的源码实现):

//获取数据库版本号,默认为0
final int version = db.getVersion();
        //如果老版本号与新版本号不同
        if (version != mNewVersion) {
            //如果数据库为只读,系统则会抛出"SQLiteException"异常
            if (db.isReadOnly()) {
                throw new SQLiteException("Can't upgrade read-only database from version " +
                        db.getVersion() + " to " + mNewVersion + ": " + mName);
        }

        //数据库开启事务
        db.beginTransaction();
        try {
            //表示数据库第一次创建,则会进入我们文章最上面自定义DBHelper类的onCreate()方法
            if (version == 0) {
                onCreate(db);
            } else {
            //如果旧版本号大于新版本号,数据库会”降级“,否则数据库会”升级“
                if (version > mNewVersion) {
                    onDowngrade(db, version, mNewVersion);
                } else {
                    onUpgrade(db, version, mNewVersion);
                }
            }
            //设置数据库的最新版本号
            db.setVersion(mNewVersion);
            //事务成功完成
            db.setTransactionSuccessful();
        } finally {
                //最后结束事务
            db.endTransaction();
        }
    }

4、拿SQLiteDatabase对象进行SQLite数据库的常规操作

该下简略介绍两种操作方法:

1、使用SQL语句
2、使用Android封装好的方法

我们在初始化SQLiteDatabase对象的时候,创建了一个数据库:study.db,并在数据库中创建了一个表:study,表中包含主键自增 _id , 还有两个字段:bookName、bookDesc。
该下代码实现了往数据库中插入、更新、查询、删除四种常用操作,此时你应该亲自动手试试...

    //插入数据
    case R.id.btn_insert:
        //使用SQL语句
        if (useSQL) {
            db.execSQL("insert into study values(null, ?, ?)",
                    new Object[]{et_insert_book_name.getText().toString(), et_insert_book_desc.getText().toString()});

        //使用Android封装的方法
        } else {
            //其中cv为ContentValues的实例
            cv.put("bookName", et_insert_book_name.getText().toString());
            cv.put("bookDesc", et_insert_book_desc.getText().toString());

            long isOK = db.insert("study", null, cv);

            //-1代表操作失败
            if (isOK == -1) {
                Toast.makeText(DBDemoActivity.this, "插入失败", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(DBDemoActivity.this, "插入成功", Toast.LENGTH_SHORT).show();
            }
        }
        break;

    //更新数据
    case R.id.btn_update:

        if (useSQL) {
            db.execSQL("update study set bookName = ? where bookName = ?", new String[]{et_update_new_book_name.getText().toString(), et_update_book_name.getText().toString()});
        } else {
            cv.put("bookName", et_update_new_book_name.getText().toString());

            int updateCount = db.update("study", cv, "bookName = ?", new String[]{et_update_book_name.getText().toString()});

            //更新后更新的个数,"0"表示更新失败
            if (updateCount != 0) {
                Toast.makeText(DBDemoActivity.this, "更新成功,共更新个数:" + updateCount, Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(DBDemoActivity.this, "更新失败", Toast.LENGTH_SHORT).show();
            }
        }
        break;

    //查询操作
    case R.id.btn_query:

        if (useSQL) {
            Cursor cursor = db.rawQuery("select * from study", null);
            StringBuilder sb = new StringBuilder();
            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                sb.append("总数:" + cursor.getCount() + "\\\\n" + "书名:" + cursor.getString(cursor.getColumnIndex("bookName"))
                        + "----该书简介:" + cursor.getString(cursor.getColumnIndex("bookDesc")));
                text_query_result.setText(sb.toString());
            }
            //记得进行关闭哦
            cursor.close();
        } else {
            //查询该表中所有数据
            Cursor c = db.query("study", null, null, null, null, null, null);

            StringBuffer sb = new StringBuffer();
            for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
                sb.append("总数:" + c.getCount() + "\\\\n" + "书名:" + c.getString(c.getColumnIndex("bookName"))
                        + "----该书简介:" + c.getString(c.getColumnIndex("bookDesc")));
                text_query_result.setText(sb.toString());
            }
            //记得进行关闭哦
            c.close();

        }
        break;

    //删除操作
    case R.id.btn_del:

        if (useSQL) {
            db.execSQL("delete from study where bookName = ?", new String[]{et_del_book_name.getText().toString()});
        } else {
            db.delete("study", "bookName = ?", new String[]{et_del_book_name.getText().toString()});
        }

        break;

三、SQLite说

”555...又被你看穿了“



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容