不會點SQLite,都不好意思說自己是開發的

silencezwm發表於2019-03-04


一、為什麼要會點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…又被你看穿了“



相關文章