Android數據庫使用指南(上)


前言
Android上的數據庫是sqlite,雖然這個數據庫是輕量級的,但是儲存的東西可不少,sqlite官方表示理論存儲容量為140TB,目前應該沒有那么大容量的手機,存儲能力太強了。

關於如何使用SQLite,老實說,都在android.database.sqlite這個包里面。
這里首先先提一下,Android中的SQLite,支持的存儲的數據類型一共有9種:

1 Byte
2 Long
3 Short
4 Integer
5 Float
6 Double
7 String
8 Boolean
9 byte[]

相信這些數據已經完全滿足你的日常需求了吧,因為支持保存byte[]所以,幾乎支持保存任何東西了吧,因為任何東西都能轉化為byte[]啊。

SQLiteOpenHelper
既然是數據庫的增刪改查,我們首先需要一個數據庫,數據庫怎么生成呢,數據庫要通過SQLiteOpenHelper的子類生成,所以我們需要建一個類來繼承SQLiteOpenHelper。由於這個類是一個抽象類,我們需要實現他的構造方法和抽象方法。所以:

public class DBHelper extends SQLiteOpenHelper {

    // 數據庫默認名字
    public static final String db_name = "test.db";

    public DBHelper(Context context, int version) {
        super(context, db_name, null, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }

}

這里存在2個抽象方法,onCreate和onUpgrade。
onCreate:創建表啊啥的,可以在這里面寫。
onUpgrade:數據庫需要更新的時候使用,前提是已經存在了一個相同的數據庫,需要新加表,或者原來的表字段要修改啥的,就在這里面寫。

現在我們創建一個名為table1的表:

public class DBHelper extends SQLiteOpenHelper {

    public static final String db_name = "test.db";

    public DBHelper(Context context, int version) {
        super(context, db_name, null, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table table1 (" +
                " _byte byte," +
                " _long long," +
                " _text text," +
                " _short short," +
                " _int int," +
                " _float float," +
                " _double double," +
                " _boolean boolean," +
                " _blob blob" +
                ")");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

}

創建表其實就是利用SQLiteDatabase對象的execSQL方法執行sql語句。

接下來我們做一些簡單的增刪改查,為了便於管理,我們將增刪改查寫在另一個類中好了。

增刪改查
我們新建一個DBManger類作為增刪改查管理類好了,該類就定義為一個單例,作為專門管理這個test.db數據庫的工具好了。

public class DBManger {

    private Context context;
    private static DBManger instance;
    // 操作表的對象,進行增刪改查
    private SQLiteDatabase writableDatabase;

    private DBManger(Context context) {
        this.context = context;
        DBHelper dbHelper = new DBHelper(context, 1);
        writableDatabase = dbHelper.getWritableDatabase();
    }

    public static DBManger getInstance(Context context) {
        if (instance == null) {
            synchronized (DBManger.class) {
                if (instance == null) {
                    instance = new DBManger(context);
                }
            }
        }
        return instance;
    }

}

我們通過DBHelpergetWritableDatabase方法得到SQLiteDatabase對象,SQLiteDatabase可以對數據庫表進行操作,比如我們要新增數據:

public void add() {

        ContentValues contentValues = new ContentValues();

        byte _byte = Byte.MAX_VALUE;
        contentValues.put("_byte", _byte);

        long _long = Long.MAX_VALUE;
        contentValues.put("_long", _long);

        String _text = "字符串";
        contentValues.put("_text", _text);

        short _short = Short.MAX_VALUE;
        contentValues.put("_short", _short);

        int _int = Integer.MAX_VALUE;
        contentValues.put("_int", _int);

        float _float = Float.MAX_VALUE;
        contentValues.put("_float", _float);

        double _double = Double.MAX_VALUE;
        contentValues.put("_double", _double);

        boolean _boolean = true;
        contentValues.put("_boolean", _boolean);

        byte[] _byteArr = {Byte.MIN_VALUE, Byte.MAX_VALUE};
        contentValues.put("_blob", _byteArr);

        writableDatabase.insert("table1", null, contentValues);

    }

其實主要就是用到了SQLiteDatabase的insert方法,傳入表名,null,和contentValues。
第一個參數:表名
其中第二個參數大概說一下,老實說,目前為止,第2個參數的意義就我個人而言,我覺得意義不大,因為只有當我們沒有向表中寫入任何數據的時候,這個才會出效果,所以直接寫null就行了,因為我們調用這個方法的目的就是為了寫數據啊。
第三個參數:Android提供了一個ContentValues,有點類似map集合的方式,可以理解成一個包裹,將數據打包成一個包裹,然后將這個包裹丟進去。put的第一個參數是列名,第二個是值。


那么如何刪除數據呢:

public void del() {
        writableDatabase.delete("table1", "_int = ?", new String[]{Integer.MAX_VALUE + ""});
}

使用delete方法
參數1:表名
參數2:刪數據的條件
參數3:對應參數2中的問號”?”
比如這里就是刪除_int = Integer.MAX_VALUE的值,好像所有數據都刪除完了哈。。。

這里都條件篩選很靈活,不僅僅可以是 XX = ?,還可以是XX > ?,XX < ?,甚至是XX > ? and YY = ?,不過這樣,第三個參數里面,就需要2個值了。


如果了解了增和刪的方法,那么理解修改的方法就會變得很容易。

public void update() {
        ContentValues contentValues = new ContentValues();
        contentValues.put("_text", "修改后的字符串");
        writableDatabase.update("table1", contentValues, "_text = ?", new String[]{"字符串"});
 }

調用update方法,參數依次:表名、包裹、條件、條件的值 
不用細說了吧?修改滿足某些條件的數據

增刪改我們都看了,我們現在來看看稍微有點復雜的查詢。

    public String select() {

        Cursor cursor = writableDatabase.query("table1", null, null, null, null, null, null, null);

        int position = cursor.getPosition();
        Log.e(TAG, "select: 游標默認位置:" + position);

        String result = "";

        while (cursor.moveToNext()) {

            byte _byte = (byte) cursor.getShort(cursor.getColumnIndex("_byte"));
            long _long = cursor.getLong(cursor.getColumnIndex("_long"));
            String _text = cursor.getString(cursor.getColumnIndex("_text"));
            short _short = cursor.getShort(cursor.getColumnIndex("_short"));
            int _int = cursor.getInt(cursor.getColumnIndex("_int"));
            float _float = cursor.getFloat(cursor.getColumnIndex("_float"));
            double _double = cursor.getDouble(cursor.getColumnIndex("_double"));
            boolean _boolean = cursor.getInt(cursor.getColumnIndex("_boolean")) == 1 ? true : false;
            byte[] _byteArr = cursor.getBlob(cursor.getColumnIndex("_blob"));

            result += String.format("_byte = %s, _long = %s, _text = %s, _short = %s, _int = %s, _float = %s, _double = %s, _boolean = %s, _byteArr = %s",
                    _byte, _long, _text, _short, _int, _float, _double, _boolean, _byteArr) + "\n";

        }

        return result;

    }

是不是有種突然變復雜的感覺,老實說我們一點一點的看,其實是沒有問題的,這里我們調用了query方法,參數真是多的不得了啊,不過我們只傳了一個參數,就是表名這個參數,也就是第一個,那么其他參數是干嘛的呢,由於這是個查詢方法嘛,所以其他參數當然是跟查詢有關的啦,比如查詢條件,排序什么的,這么我們下面慢慢說。

首先query方法返回了一個Cursor對象,這個對象是干嘛的呢,中文翻譯“光標“,也就是我們在打字的時候,那個一閃一閃的豎線,我們也叫他游標。這個東西是定位用的,數據庫中的表大概長這個樣子:

 

 

游標默認指定-1的位置,也就是沒有數據,當我們調用cursor.moveToNext()的時候,游標就會指向下一個位置,如果是以上圖為例,那就是指向第一個位置,然后這里的while循環就會遍歷完所有的數據了。
我們可以獲取到cursor指定的位置的數據,獲取方式如上代碼,這里挑一個例子說一下,其他相似:

byte _byte = (byte) cursor.getShort(cursor.getColumnIndex("_byte"));

首先說明一下,cursor沒有getByte的方法,所以用getShort接收下。。。

比如這個,cursor.getShort()是得到short類型的數據,里面傳的參數其實是int類型的數據,代表第幾個字段,也就是那一列的數據,如cursor.getShort(4),因為cursor本身就代表某個具體的一行了,所以這里就是,第已知行的第4列數據。至於這個方法參數本來應該傳一個int,為什么傳的是cursor.getColumnIndex("_byte"),這個方法,其實就是告訴你列名為“_byte“的字段是第幾行,然后就可以得到數據啦!

這里我們講一下query的參數,8個參數:

1 String table
2 String[] columns
3 String selection
4 String[] selectionArgs
5 String groupBy
6 String having
7 String orderBy
8 String limit

table:表名

columns:需要被查詢的列名,比如說,可以這樣傳:new String[]{"_byte", "_long"},那么查詢的結果就只有兩列了,如:

 


selection和selectionArgs就一起說了,這兩個就是條件查詢,跟前面的修改表的條件同理,舉個例子可以這樣傳:
"_byte = ?", new String[]{"127"}

groupBy:將相同值划分為一組。舉個例子,假設有個水果表

 

 

然后使用groupBy以后:

 

 

有沒有發現,本來重復的蘋果,使用groupby以后,沒有了,groupby就是去掉重復的內容,是不是跟set集合相似。

別感覺這玩意兒沒啥用啊,舉個例子,你在一張表里記錄了無數用戶的無數操作,這時候使用groupby,你就可以很方便的查到某一個人做了哪些操作了,是不是很方便,或者查詢到哪些人做了某個操作。在學到groupby之前,你是不是想着每個用戶的操作都建一個表記錄下來,不要害臊,最開始我也是這樣打算的,哈哈!

having:這個也是個條件判斷的參數,不過這個要跟groupby這個參數同時存在,也就是要同時使用。也就是說,在groupby篩選后的數據中,再使用這個所謂的having再篩選一次。傳遞格式可以這樣:字段 > 20
舉個例子吧,比如我們有這樣一張表:

 

 

然后配合groupBy使用having后

有人就提出問題了,第2個數據的蘋果不也大於20嗎,為什么沒有這個數據,因為第2個數據不大於20,groupBy代表分組,蘋果現在就是以一個組為單位行動,這時候不能呈個人英雄,這樣理解沒毛病!

orderBy:代表排序,可以傳某個字段,比如_byte,這就代表按照這個字段排序,默認是升序,也就是從小到大排序,我們可以這樣傳遞參數,讓其降序排列_byte desc,如果是_byte asc就是升序,由於默認升序,所以這個asc也就省略了。

limit:代表只查多少條數據,比如只查10條數據,就直接傳遞一個10就行了。

結語
本文主要講解內容:

如何創建數據庫
如何創建表
對表的增刪改查
其實主要還是講解了對表中數據的修改。
關於查詢數據,講的很詳細,主要是query這個方法的參數實在是太多了,像我平時基本就只用傳一個參數,其他全部為null,哈哈。

下一章節我們會講解對數據庫中的表的修改,以及如何升級數據庫之類的,拭目以待吧!
---------------------
版權聲明:本文為CSDN博主「你缺少想象力」的原創文章,遵循CC 4.0 by-sa版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/IT_XF/article/details/82591770

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM