前言
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; } }
我們通過DBHelper
的getWritableDatabase
方法得到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