欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Android學(xué)習筆記36:使用SQLite方式存儲數據

  在A(yíng)ndroid中一共提供了5種數據存儲方式,分別為:

 ?。?)Files:通過(guò)FileInputStream和FileOutputStream對文件進(jìn)行操作。具體使用方法可以參閱博文《Android學(xué)習筆記34:使用文件存儲數據》。

 ?。?)Shared Preferences:常用來(lái)存儲鍵值對形式的數據,對系統配置信息進(jìn)行保存。具體使用方法可以參閱博文《Android學(xué)習筆記35:使用Shared Preferences方式存儲數據》。

 ?。?)Content Providers:數據共享,用于應用程序之間數據的訪(fǎng)問(wèn)。

 ?。?)SQLite:Android自帶的輕量級關(guān)系型數據庫,支持SQL語(yǔ)言,用來(lái)存儲大量的數據,并且能夠對數據進(jìn)行使用、更新、維護等操作。

 ?。?)Network:通過(guò)網(wǎng)絡(luò )來(lái)存儲和獲取數據。

  本篇博文介紹第四種方式,通過(guò)Android自帶的SQLite數據庫存儲數據。

1.SQLite簡(jiǎn)介

  SQLite是一款開(kāi)源的、嵌入式關(guān)系型數據庫,第一個(gè)版本Alpha發(fā)布于2000年。SQLite在便攜性、易用性、緊湊性、高效性和可靠性方面有著(zhù)突出的表現。

  SQLite和C/S模式的數據庫軟件不同,它是一款嵌入式數據庫,沒(méi)有獨立運行的進(jìn)程,與所服務(wù)的應用程序在應用程序進(jìn)程空間內共生共存。它的代碼與應用程序代碼也是在一起的,或者說(shuō)嵌入其中,作為托管它的程序的一部分。因此不存在數據庫的客戶(hù)端和服務(wù)器,使用SQLite一般只需要帶上它的一個(gè)動(dòng)態(tài)庫,就可以享受它的全部功能。

  數據庫服務(wù)器在程序中的好處是不需要網(wǎng)絡(luò )配置或管理。將數據庫客戶(hù)端與服務(wù)器運行在同一個(gè)進(jìn)程中,可以省去不少的操作及麻煩:不用擔心防火墻或者地址解析;不用浪費時(shí)間管理復雜的授權和權限;可以減少網(wǎng)絡(luò )調用相關(guān)的消耗;可以簡(jiǎn)化數據庫管理并使程序更容易部署。

  SQLite數據庫通過(guò)數據庫級上的獨占性和共享鎖來(lái)實(shí)現獨立事務(wù)處理。這意味著(zhù)多個(gè)進(jìn)程可以在同一時(shí)間從同一數據庫讀取數據,但是只有一個(gè)可以寫(xiě)入數據。在某個(gè)進(jìn)程向數據庫執行寫(xiě)操作之前,必須獲得獨占鎖定。在發(fā)出獨占鎖定后,其他的讀寫(xiě)操作將不會(huì )再發(fā)生。

  此外,SQLite數據庫中的所有信息(比如表、視圖、觸發(fā)器等)都包含在一個(gè)文件內,方便管理和維護。SQLite數據庫還支持大部分操作系統,除電腦上使用的操作系統之外,很多手機上使用的操作系統同樣可以運行。同時(shí),SQLite數據庫還提供了多語(yǔ)言的編程接口,供開(kāi)發(fā)者使用。

2.SQL基本命令

  SQL是與關(guān)系型數據庫通信的唯一方式。它專(zhuān)注于信息處理,是為構建、讀取、寫(xiě)入、排序、過(guò)濾、映射、分組、聚集和通常的管理信息而設計的聲明式語(yǔ)言。

  在講解SQL基本命令之前,有必要先了解一下SQLite所支持的數據類(lèi)型都有哪些。

2.1 SQLite支持的數據類(lèi)型

  SQLite采用動(dòng)態(tài)數據存儲類(lèi)型,會(huì )根據存入的值自動(dòng)進(jìn)行判斷。SQLite支持以下5種數據類(lèi)型:

 ?。?)NULL:空值

 ?。?)INTEGER:帶符號的整型

 ?。?)REAL:浮點(diǎn)型

 ?。?)TEXT:字符串文本

 ?。?)BLOB:二進(jìn)制對象

2.2 SQL基本命令

  表是探索SQLite中SQL的起點(diǎn),也是關(guān)系型數據庫中信息的標準單位,所有的操作都是以表為中心的。那么如何使用SQL命令創(chuàng )建一張表呢?

2.2.1創(chuàng )建表

  表是由行和列組成的,列稱(chēng)為字段,行稱(chēng)為記錄。

  使用CREATE命令可以創(chuàng )建表,CREATE命令的一般格式為:

  CREATE [TEMP/TEMPORARY] TABLE table_name (column_definitions [, constraints]);

  其中,[]中的內容是可選的,用TEMP或TEMPORARY關(guān)鍵字聲明的表是臨時(shí)表,這種表只存活于當前會(huì )話(huà),一旦連接斷開(kāi),就會(huì )被自動(dòng)銷(xiāo)毀。如果沒(méi)有明確指出創(chuàng )建的表是臨時(shí)表,則創(chuàng )建的是基本表,將會(huì )在數據庫中持久存在,這也是數據庫中最常見(jiàn)的表。

  CREATE TABLE命令至少需要一個(gè)表名和一個(gè)字段名,上述命令中的table_name表示表名,表名必須與其他標識符不同。column_definitions由用逗號分隔的字段列表組成,每個(gè)字段定義包括一個(gè)名稱(chēng)、一個(gè)域(類(lèi)型)和一個(gè)逗號分隔的字段約束。其中,域是指存儲在該列的信息的類(lèi)型,約束用來(lái)控制什么樣的值可以存儲在表中或特定的字段中。

  一條創(chuàng )建表的命令示例如下:

1   CREATE TABLE tab_student (studentId INTEGER PRIMARY KEY AUTOINCREMENT, 2                             studentName VARCHAR(20), 3                             studentAge INTEGER);

  如上,我們創(chuàng )建了一個(gè)名為tab_student的表,該表包含3個(gè)字段:studentId、 studentName和studentAge,其數據類(lèi)型分別為:INTEGER、VARCHAR和INTEGER。

  此外,通過(guò)使用關(guān)鍵字PRIMARY KEY,我們指定了字段studentId所在的列是主鍵。主鍵確保了每一行記錄在某種方式上與表中的其他行記錄是不同的(唯一的),進(jìn)而確保了表中的所有字段都是可尋址的。

  SQLite為主鍵提供自增長(cháng)功能,當定義字段類(lèi)型為INTEGER PRIMARY KEY時(shí),SQLite將為該字段創(chuàng )建默認值,該默認值確保整數值是唯一的。SQLite使用64-bit單符號整數主鍵,因此,該字段的最大值是9,223,372,036,854,775,807。當達到最大值時(shí),SQLite會(huì )自動(dòng)搜索該字段還未使用的值,并作為要插入的值。從表中刪除記錄時(shí),rowid可能被回收并在后面的插入中使用。因此,新創(chuàng )建的rowid不一定是按照嚴格順序增長(cháng)的。如果想要SQLite使用唯一的自動(dòng)主鍵值,而不是填補空白,可以在主鍵定義INTEGER PRIMARY KEY中加入關(guān)鍵字AUTOINCREMENT。AUTOINCREMENT關(guān)鍵字阻止rowid回收,它將為新插入的記錄產(chǎn)生新的(不是回收的)rowid。

2.2.2插入記錄

  使用INSERT命令可以一次插入一條記錄,INSERT命令的一般格式為:

  INSERT INTO tab_name (column_list) VALUES (value_list);

  其中,tab_name指明將數據插入到哪個(gè)表中,column_list是用逗號分隔的字段名稱(chēng),這些字段必須是表中存在的,value_list是用逗號分隔的值列表,這些值是與column_list中的字段一一對應的。

  比如,向剛才創(chuàng )建的tab_student表中插入一條記錄,便可以使用如下的語(yǔ)句完成:


  INSERT
INTO tab_student (studentId, studentName, studentAge) VALUES (1, “jack”, 23);

  通過(guò)以上的語(yǔ)句,便插入了一條studentName=”jack”, studentAge=”23”的記錄,該記錄的主鍵為studentId=1。

2.2.3更新記錄

  使用UPDATE命令可以更新表中的記錄,該命令可以修改一個(gè)表中一行或者多行中的一個(gè)或多個(gè)字段。UPDATE命令的一般格式為:

  UPDATE tab_name SET update_list WHERE predicate;

  其中,update_list是一個(gè)或多個(gè)字段賦值的列表,字段賦值的格式為column_name=value。WHERE子句使用斷言識別要修改的行,然后將更新列應用到這些行。

  比如,要更新剛才插入到tab_student表中的記錄,便可以使用如下的語(yǔ)句完成:


  UPDATE
tab_student SET studentName=”tom”, studentAge=25WHERE studentId=1;

  通過(guò)以上的語(yǔ)句,便可以將剛才插入的主鍵為studentId=1的記錄更新為studentName=”tom”, studentAge=”25”了。

2.2.4刪除記錄

  使用DELETE命令可以刪除表中的記錄,DELETE命令的一般格式為:

  DELETE FROM table_name WHERE predicate;

  其中,table_name指明所要刪除的記錄位于哪個(gè)表中。和UPDATE命令一樣,WHERE子句使用斷言識別要刪除的行。

  比如,要刪除剛才插入的記錄,便可以使用如下的語(yǔ)句完成:

  
  DELETE FROM tab_student WHERE studentId=1;

2.2.5查詢(xún)記錄

  SELECT命令是查詢(xún)數據庫的唯一命令。SELECT命令也是SQL命令中最大、最復雜的命令。

  SELECT命令的通用形式如下:

  SELECT [distinct] heading 

  FROM tables 

  WHERE predicate 

  GROUP BY columns 

  HAVING predicate 

  ORDER BY columns 

  LIMIT count,offset;

  其中,每個(gè)關(guān)鍵字(如FROM、WHERE、HAVING等)都是一個(gè)單獨的子句,每個(gè)子句由關(guān)鍵字和跟隨的參數構成。GROUP BY和HAVING一起工作可以對GROUP BY進(jìn)行約束。ORDER BY使記錄集在返回之前按一個(gè)或多個(gè)字段的值進(jìn)行排序,可以指定排序方式為ASC(默認的升序)或DESC(降序)。此外,還可以使用LIMIT限定結果集的大小和范圍,count指定返回記錄的最大數量,offset指定偏移的記錄數。

  在上述的SELECT命令通用形式中,除了SELECT之外,所有的子句都是可選的。目前最常用的SELECT命令由三個(gè)子句組成:SELECT、FROM、WHERE,其基本語(yǔ)法形式如下:

  SELECT heading FROM tables WHERE predicate;

  比如,要查詢(xún)剛才插入的記錄,便可以使用如下的語(yǔ)句完成:

  
  SELECT
studentId, studentName, studentAge FROM tab_student WHERE studentId=1;

  至此,我們介紹了SQL中最基本和最常用的CREATE、INSERT、UPDATE、DELETE和SELECT命令。當然了,這里只是對其進(jìn)行了簡(jiǎn)單的介紹,有關(guān)SQLite中SQL命令的詳細使用方法,可以參閱《SQLite權威指南》一書(shū)的第三章和第四章。

 

3.數據庫操作輔助類(lèi)SQLiteOpenHelper

  Android提供了一個(gè)重要的類(lèi)SQLiteOpenHelper,用于輔助用戶(hù)對SQLite數據庫進(jìn)行操作。

  SQLiteOpenHelper的構造函數原型如下:

  public SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version);

  其中,參數context表示應用程序運行的環(huán)境,包含應用程序所需的共享資源。參數name表示Android的數據庫名字。參數factory是SQLiteDatabase.CursorFactory類(lèi)對象,用于存儲查詢(xún)Android SQLite數據庫的結果集。參數version表示應用程序所用的數據庫的版本,該版本并非SQLite的真正版本,而是指定應用程序中的SQLite數據庫的版本,當該版本號發(fā)生變化時(shí),將會(huì )觸發(fā)SQLiteOpenHelper類(lèi)中的onUpgrade()或onDowngrade()方法。

  SQLiteOpenHelper類(lèi)的所有方法如圖1所示。

圖1 SQLiteOpenHelper類(lèi)的方法

  其中,close()方法用于關(guān)閉SQLiteOpenHelper對象中的SQLite數據庫;getReadableDatabase()方法和getWriteableDatabase()方法類(lèi)似,getReadableDatabase()方法以只讀狀態(tài)打開(kāi)SQLiteOpenHelper對象中指定的SQLite數據庫,任何想要修改數據庫的操作都是不允許的;getWriteableDatabase()方法也是打開(kāi)數據庫,但是允許數據庫正常的讀/寫(xiě)操作;在一個(gè)不存在的數據庫上調用任何方法時(shí),都會(huì )隱式的調用SQLiteOpenHelper對象的onCreate()方法;當應用程序第一次訪(fǎng)問(wèn)數據庫時(shí),則會(huì )調用onOpen()方法,但是,如果版本號發(fā)生了變化的話(huà),則會(huì )調用onUpgrade()或onDowngrade()方法。

 

4.數據庫類(lèi)SQLiteDatabase

  SQLiteDatabase類(lèi)用來(lái)完成對數據庫的操作任務(wù),比如表的選擇、插入、更新和刪除語(yǔ)句等。

  SQLiteDatabase類(lèi)中常用的用于執行SQL語(yǔ)句的方法有以下一些。

 ?。?)execSQL()方法:

  public void execSQL (String sql);

  public void execSQL (String sql, Object[] bindArgs);

 ?。?)query()方法:

  public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String  groupBy, String  having,String orderBy, String limit);

  public Cursor query (boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal);

  public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String  having,String orderBy);

  public Cursor query (boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);

 ?。?)queryWithFactory()方法:

  public Cursor queryWithFactory (SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[]columns, String selection, String[] selectionArgs, String groupBy, String having, String  orderBy, String  limit,CancellationSignal cancellationSignal);

  public Cursor queryWithFactory (SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[]columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);

 ?。?)rawQuery()方法:

  public Cursor rawQuery (String sql, String[] selectionArgs, CancellationSignal cancellationSignal);

  public Cursor rawQuery (String sql, String[] selectionArgs);

 ?。?)rawQueryWithFactory()方法:

  public Cursor rawQueryWithFactory (SQLiteDatabase.CursorFactory cursorFactory, String sql, String[]  selectionArgs,String editTable);

  public Cursor rawQueryWithFactory (SQLiteDatabase.CursorFactory cursorFactory, String sql, String[]  selectionArgs,String editTable, CancellationSignal cancellationSignal);

  其中,execSQL()方法都有一個(gè)參數sql,這個(gè)參數是一個(gè)SQL語(yǔ)句。第二個(gè)參數bindArgs接收一個(gè)數組,數組中的每個(gè)成員捆綁了一個(gè)查詢(xún)。execSQL()方法用于運行那些沒(méi)有返回值的查詢(xún)語(yǔ)句,比如創(chuàng )建、插入、更新和修改表。

  query()方法和queryWithFactory()方法是在數據庫中運行一些輕量級的單查詢(xún)語(yǔ)句,參數包括table、columns、groupBy、having、orderBy、limit等SQL語(yǔ)句關(guān)鍵字。這些方法允許將SQL語(yǔ)句傳遞給相關(guān)方法,而不必直接使用SQL語(yǔ)句。

  rawQuery()方法和rawQueryWithFactory()方法也都有一個(gè)參數sql,用于執行SQL查詢(xún)語(yǔ)句,返回值是Cursor對象。這兩個(gè)方法都有一個(gè)版本能夠接收一個(gè)字符串數組selectionArgs作為參數,通過(guò)這個(gè)參數,SQLiteDatabase對象將把捆綁的SQL語(yǔ)句中的問(wèn)號(?)用這個(gè)數組中的值代替,并按照一一對應的位置關(guān)系進(jìn)行取代。

  SQLiteDatabase類(lèi)提供了大約50個(gè)方法,除此之外還有一些用于打開(kāi)數據庫的方法(如openDatabase()、openOrCreateDatabase()等),用于管理SQLite事務(wù)的方法(如beginTransaction()、endTransaction()等),用于測試數據庫是否被鎖住的方法(如isDbLockedByCurrentThread()、isDbLockedByOtherThread()等),以及獲取數據庫基本信息的方法(如getMaximumSiza()、getVersion()等)。這里就不一一介紹了,具體可以參閱SQLiteDatabase類(lèi)的API幫助文檔。

5.游標類(lèi)Cursor

  在A(yíng)ndroid中,查詢(xún)數據是通過(guò)Cursor類(lèi)來(lái)實(shí)現的,當我們使用SQLiteDatabase.query()或SQLiteDatabase.rawQuery()方法時(shí),會(huì )得到一個(gè)Cursor對象,Cursor指向的就是每一條記錄,它提供了很多有關(guān)查詢(xún)的方法,如圖2所示。

圖2 Cursor類(lèi)的常用方法

6.封裝接口

  有了以上的基礎,我們便可以按照MVC的架構,封裝一個(gè)接口層,在該接口層中實(shí)現對SQLite數據庫的具體操作。

  以下分別以添加數據、更新數據、查詢(xún)數據為例講解其具體的實(shí)現方法。在實(shí)現這些方法之前,我們首先需要創(chuàng )建一張表。這里我創(chuàng )建了一個(gè)名為MySQLiteOpenHelper的類(lèi),讓它繼承自SQLiteOpenHelper類(lèi),并實(shí)現了SQLiteOpenHelper類(lèi)的onCreate()方法,在該方法里實(shí)現創(chuàng )建一張表的操作,具體源代碼如下:

1     /*2      * Function  :    創(chuàng  )建表3      * Author    :    博客園-依舊淡然4      */5     public void onCreate(SQLiteDatabase db) {6         db.execSQL("CREATE TABLE tab_student (studentId INTEGER PRIMARY KEY AUTOINCREMENT, " + 
"studentName VARCHER(20), " +
"studentAge INTEGER)");7 }

  通過(guò)以上的代碼,我們創(chuàng )建了一張名為“tab_student”的表,并在該表中創(chuàng )建了三個(gè)字段,分別為:studentId、studentName和studentAge。并且指定了studentId字段作為該表的主鍵。

6.1添加數據

  添加數據可以使用SQLiteDatabase.execSQL(String sql, Object[] bindArgs)方法來(lái)實(shí)現,具體如下:

1     /*2      * Function  :    添加數據3      * Author    :    博客園-依舊淡然4      */5     public void addStudentInfo(Student student) {6         db = mySQLiteOpenHelper.getWritableDatabase();7         db.execSQL("INSERT INTO tab_student (studentId, studentName, studentAge) values (?, ?, ?)", 8           new Object[] {student.getStudentId(), student.getStudentName(), student.getStudentAge()});9     }

  其中,通過(guò)第二個(gè)參數bindArgs,使SQL語(yǔ)句中的問(wèn)號(?)與這個(gè)數組中的值形成一一對應關(guān)系,從而將值寫(xiě)入到“tab_student”表中的對應字段中。

6.2更新數據

  更新數據的方法與添加數據的方法大致相同,具體如下:

1    /*2     * Function  :    更新數據3     * Author    :    博客園-依舊淡然4     */5    public void updateStudentInfo(Student student) {6        db = mySQLiteOpenHelper.getWritableDatabase();7        db.execSQL("UPDATE tab_student SET studentName = ?, studentAge = ? WHERE studentId = ?",           new Object[] {student.getStudentName(), student.getStudentAge(), student.getStudentId()});8    }

6.3查詢(xún)數據

  查詢(xún)數據時(shí),因為需要返回查詢(xún)的結果,所以需要使用SQLiteDatabase.rawQuery()方法將查詢(xún)的結果返回,具體如下:

 1     /* 2      * Function  :    查詢(xún)數據 3      * Author    :    博客園-依舊淡然 4      */ 5     public Student findStudentInfo(int id) { 6         db = mySQLiteOpenHelper.getWritableDatabase(); 7         String sql = "SELECT studentId, studentName, studentAge FROM tab_student WHERE studentId = ?"; 8         Cursor cursor = db.rawQuery(sql, new String[] {String.valueOf(id)}); 9         if(cursor.moveToNext()) {10             return new Student(cursor.getInt(cursor.getColumnIndex("studentId")),     
cursor.getString(cursor.getColumnIndex("studentName")),11 cursor.getInt(cursor.getColumnIndex("studentAge")));12 }13 return null;14 }

  可以看出,通過(guò)使用SQLiteDatabase.rawQuery()方法可以將查詢(xún)到的結果存入Cursor對象中。然后,我們可以使用Cursor對象的getXXX()方法將查詢(xún)結果從Cursor對象中取出來(lái)。

  當然了,我們還可以根據實(shí)際的需要,去實(shí)現更多的接口方法,比如,刪除數據、獲取數據列表、獲取數據個(gè)數等等。

  封裝好了以上的這些接口方法,便可以很方便的在程序中直接調用這些方法,不必再去關(guān)心底層數據庫的調用,而將精力放在UI界面的設計實(shí)現上。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
ANDROID開(kāi)發(fā)之SQLite詳解
SQLite嵌入式數據庫
6.3.1 數據存儲與訪(fǎng)問(wèn)之
【Android基礎篇】SQLite數據庫的增刪改查基本操作
Android從零開(kāi)始(7)(SQLite數據庫)(新)
android?sqlite?編程
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久