[教育]移動編程課件第8章數(shù)據(jù)存儲與訪問_第1頁
已閱讀1頁,還剩157頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、第8章 數(shù)據(jù)存儲和訪問,,,,本章學(xué)習(xí)目標:,掌握SharedPreferences的使用方法掌握各種文件存儲的區(qū)別與適用情況了解SQLite數(shù)據(jù)庫的特點和體系結(jié)構(gòu)掌握SQLite數(shù)據(jù)庫的建立和操作方法理解ContentProvider的用途和原理掌握ContentProvider的創(chuàng)建與使用方法,8.1 簡單存儲,8.1.1 SharedPreferencesSharedPreferences是一種輕量級的數(shù)據(jù)

2、保存方式通過SharedPreferences可以將NVP(Name/Value Pair,名稱/值對)保存在Android的文件系統(tǒng)中,而且SharedPreferences完全屏蔽的對文件系統(tǒng)的操作過程開發(fā)人員僅是通過調(diào)用SharedPreferences對NVP進行保存和讀取,8.1 簡單存儲,8.1.1 SharedPreferencesSharedPreferences不僅能夠保存數(shù)據(jù),還能夠?qū)崿F(xiàn)不同應(yīng)用程序間的數(shù)據(jù)共享

3、SharedPreferences支持三種訪問模式私有(MODE_PRIVATE):僅有創(chuàng)建程序有權(quán)限對其進行讀取或?qū)懭肴肿x(MODE_WORLD_READABLE):不僅創(chuàng)建程序可以對其進行讀取或?qū)懭耄渌麘?yīng)用程序也讀取操作的權(quán)限,但沒有寫入操作的權(quán)限全局寫(MODE_WORLD_WRITEABLE):創(chuàng)建程序和其他程序都可以對其進行寫入操作,但沒有讀取的權(quán)限,8.1 簡單存儲,8.1.1 SharedPreferences

4、在使用SharedPreferences前,先定義SharedPreferences的訪問模式下面的代碼將訪問模式定義為私有模式有的時候需要將SharedPreferences的訪問模式設(shè)定為即可以全局讀,也可以全局寫,這樣就需要將兩種模式寫成下面的方式,8.1 簡單存儲,8.1.1 SharedPreferences定義SharedPreferences的名稱,這個名稱與在Android文件系統(tǒng)中保存的文件同名。因此,只要具

5、有相同的SharedPreferences名稱的NVP內(nèi)容,都會保存在同一個文件中為了可以使用SharedPreferences,需要將訪問模式和SharedPreferences名稱作為參數(shù),傳遞到getSharedPreferences()函數(shù),并獲取到SharedPreferences對象,8.1 簡單存儲,8.1.1 SharedPreferences在獲取到SharedPreferences對象后,則可以通過Shared

6、Preferences.Editor類對SharedPreferences進行修改,最后調(diào)用commit()函數(shù)保存修改內(nèi)容SharedPreferences廣泛支持各種基本數(shù)據(jù)類型,包括整型、布爾型、浮點型和長型等等,8.1 簡單存儲,8.1.1 SharedPreferences如果需要從已經(jīng)保存的SharedPreferences中讀取數(shù)據(jù),同樣是調(diào)用getSharedPreferences()函數(shù),并在函數(shù)的第1個參數(shù)中指明

7、需要訪問的SharedPreferences名稱,最后通過get()函數(shù)獲取保存在SharedPreferences中的NVPget()函數(shù)的第1個參數(shù)是NVP的名稱第2個參數(shù)是在無法獲取到數(shù)值的時候使用的缺省值,8.1 簡單存儲,8.1.2 示例通過SimplePreferenceDemo示例介紹具體說明SharedPreferences的文件保存位置和保存格式下圖是SimplePreferenceDemo示例的用戶界

8、面用戶在界面上的輸入的信息,將通過SharedPreferences在Activity關(guān)閉時進行保存。當應(yīng)用程序重新開啟時,保存在SharedPreferences的信息將被讀取出來,并重新呈現(xiàn)在用戶界面上,8.1 簡單存儲,8.1.2 示例SimplePreferenceDemo示例運行后,通過FileExplorer查看/data/data下的數(shù)據(jù),Android為每個應(yīng)用程序建立了與包同名的目錄,用來保存應(yīng)用程序產(chǎn)生的數(shù)據(jù),這

9、些數(shù)據(jù)包括文件、SharedPreferences文件和數(shù)據(jù)庫等SharedPreferences文件就保存在/data/data//shared_prefs目錄下,8.1 簡單存儲,8.1.2 示例在本示例中,shared_prefs目錄下生成了一個名為SaveSetting.xml的文件這個文件就是保存SharedPreferences的文件,文件大小為170字節(jié),在Linux下的權(quán)限為“-rw-rw-rw”,8.1

10、簡單存儲,8.1.2 示例在Linux系統(tǒng)中,文件權(quán)限分別描述了創(chuàng)建者、同組用戶和其他用戶對文件的操作限制。x表示可執(zhí)行,r表示可讀,w表示可寫,d表示目錄,-表示普通文件。因此,“-rw-rw-rw”表示SaveSetting.xml可以被創(chuàng)建者、同組用戶和其他用戶進行讀取和寫入操作,但不可執(zhí)行產(chǎn)生這樣的文件權(quán)限與程序人員設(shè)定的SharedPreferences的訪問模式有關(guān),“-rw-rw-rw”的權(quán)限是“全局讀+全局寫”的結(jié)果

11、如果將SharedPreferences的訪問模式設(shè)置為私有,則文件權(quán)限將成為“-rw-rw ---”,表示僅有創(chuàng)建者和同組用戶具有讀寫文件的權(quán)限,8.1 簡單存儲,8.1.2 示例SaveSetting.xml文件是以XML格式保存的信息,內(nèi)容如圖如下,8.1 簡單存儲,8.1.2 示例SimplePreferenceDemo示例在onStart()函數(shù)中調(diào)用loadSharedPreferences()函數(shù),讀取保存在Shar

12、edPreferences中的姓名、年齡和身高信息,并顯示在用戶界面上當Activity關(guān)閉時,在onStop()函數(shù)調(diào)用saveSharedPreferences(),保存界面上的信息SimplePreferenceDemo.java的完整代碼,8.1 簡單存儲,8.1.2 示例,8.1 簡單存儲,8.1.2 示例,8.1 簡單存儲,8.1.2 示例,8.1 簡單存儲,8.1.2 示例示例SharePreferenceDemo將

13、說明如何讀取其他應(yīng)用程序保存的SharedPreferences數(shù)據(jù)下圖是SharePreferenceDemo示例的用戶界面示例將讀取SimplePreferenceDemo示例保存的信息,并在程序啟動時顯示在用戶界面上,8.1 簡單存儲,8.1.2 示例下面給出SharePreferenceDemo示例的核心代碼,8.1 簡單存儲,8.1.2 示例第8行代碼調(diào)用了createPackageContext()獲取到了S

14、implePreferenceDemo示例的Context第8行代碼第1個參數(shù)是SimplePreferenceDemo的包名稱,在代碼第1行進行了定義第2個參數(shù)Context.CONTEXT_IGNORE_SECURIT表示忽略所有可能產(chǎn)生的安全問題。這段代碼可能引發(fā)異常,因此必須防止在try/catch中,8.1 簡單存儲,8.1.2 示例在代碼第12行,通過Context得到了SimplePreferenceDemo示例的S

15、haredPreferences對象,同樣在getSharedPreferences()函數(shù)中,需要將正確的SharedPreferences名稱傳遞給函數(shù)訪問其他應(yīng)用程序的SharedPreferences必須滿足三個條件共享者需要將SharedPreferences的訪問模式設(shè)置為全局讀或全局寫訪問者需要知道共享者的包名稱和SharedPreferences的名稱,以通過Context獲得SharedPreferences對象

16、訪問者需要確切知道每個數(shù)據(jù)的名稱和數(shù)據(jù)類型,用以正確讀取數(shù)據(jù),8.2 文件存儲,Android使用的是基于Linux的文件系統(tǒng),程序開發(fā)人員可以建立和訪問程序自身的私有文件,也可以訪問保存在資源目錄中的原始文件和XML文件,還可以在SD卡等外部存儲設(shè)備中保存文件,8.2 文件存儲,8.2.1 內(nèi)部存儲 Android系統(tǒng)允許應(yīng)用程序創(chuàng)建僅能夠自身訪問的私有文件,文件保存在設(shè)備的內(nèi)部存儲器上,在Linux系統(tǒng)下的/data/data/

17、/files目錄中Android系統(tǒng)不僅支持標準Java的IO類和方法,還提供了能夠簡化讀寫流式文件過程的函數(shù)主要介紹的兩個函數(shù)openFileOutput()openFileInput(),8.2 文件存儲,8.2.1 內(nèi)部存儲openFileOutput()函數(shù)openFileOutput()函數(shù)為寫入數(shù)據(jù)做準備而打開的應(yīng)用程序私文件,如果指定的文件不存在,則創(chuàng)建一個新的文件openFileOutput()函數(shù)的語法格

18、式如下第1個參數(shù)是文件名稱,這個參數(shù)不可以包含描述路徑的斜杠第2個參數(shù)是操作模式函數(shù)的返回值是FileOutputStream類型,8.2 文件存儲,8.2.1 內(nèi)部存儲openFileOutput()函數(shù)Android系統(tǒng)支持四種文件操作模式,8.2 文件存儲,8.2.1 內(nèi)部存儲openFileOutput()函數(shù)使用openFileOutput()函數(shù)建立新文件的示例代碼如下第1行代碼定義了建立文件的名稱

19、fileDemo.txt第2行代碼使用openFileOutput()函數(shù)以私有模式建立文件第4行代碼調(diào)用write()函數(shù)將數(shù)據(jù)寫入文件第5行代碼調(diào)用flush()函數(shù)將所有剩余的數(shù)據(jù)寫入文件第6行代碼調(diào)用close()函數(shù)關(guān)閉FileOutputStream,8.2 文件存儲,8.2.1 內(nèi)部存儲openFileOutput()函數(shù)為了提高文件系統(tǒng)的性能,一般調(diào)用write()函數(shù)時,如果寫入的數(shù)據(jù)量較小,系統(tǒng)會把數(shù)據(jù)保

20、存在數(shù)據(jù)緩沖區(qū)中,等數(shù)據(jù)量累積到一定程度時再一次性的寫入文件中由上可知,在調(diào)用close()函數(shù)關(guān)閉文件前,務(wù)必要調(diào)用flush()函數(shù),將緩沖區(qū)內(nèi)所有的數(shù)據(jù)寫入文件,8.2 文件存儲,8.2.1 內(nèi)部存儲openFileInput()函數(shù)openFileInput()函數(shù)為讀取數(shù)據(jù)做準備而打開應(yīng)用程序私文件openFileInput()函數(shù)的語法格式如下第1個參數(shù)也是文件名稱,同樣不允許包含描述路徑的斜杠,8.2 文件存

21、儲,8.2.1 內(nèi)部存儲openFileInput()函數(shù)使用openFileInput ()函數(shù)打開已有文件的示例代碼如下上面的兩部分代碼在實際使用過程中會遇到錯誤提示,因為文件操作可能會遇到各種問題而最終導(dǎo)致操作失敗,因此代碼應(yīng)該使用try/catch捕獲可能產(chǎn)生的異常,8.2 文件存儲,8.2.1 內(nèi)部存儲InternalFileDemo示例用來演示在內(nèi)部存儲器上進行文件寫入和讀取InternalFileDem

22、o示例用戶界面如圖,8.2 文件存儲,8.2.1 內(nèi)部存儲InternalFileDemo示例的核心代碼,8.2 文件存儲,8.2.1 內(nèi)部存儲,8.2 文件存儲,8.2.1 內(nèi)部存儲,8.2 文件存儲,8.2.1 內(nèi)部存儲程序運行后,在/data/data/edu.hrbeu.InternalFileDemo/files/目錄下,找到了新建立的fileDemo.txt文件,8.2 文件存儲,8.2.1 內(nèi)部存儲file

23、Demo.txt文件fileDemo.txt從文件權(quán)限上進行分析,“-rw-rw---”表明文件僅允許文件創(chuàng)建者和同組用戶讀寫,其他用戶無權(quán)使用文件的大小為9個字節(jié),保存的數(shù)據(jù)為“Some data”,8.2 文件存儲,8.2.2 外部存儲Android的外部存儲設(shè)備指的是SD卡(Secure Digital Memory Card),是一種廣泛使用于數(shù)碼設(shè)備上的記憶卡不是所有的Android手機都有SD卡,但A

24、ndroid系統(tǒng)提供了對SD卡的便捷的訪問方法,8.2 文件存儲,8.2.2 外部存儲SD卡適用于保存大尺寸的文件或者是一些無需設(shè)置訪問權(quán)限的文件,可以保存錄制的大容量的視頻文件和音頻文件等SD卡使用的是FAT(File Allocation Table)的文件系統(tǒng),不支持訪問模式和權(quán)限控制,但可以通過Linux文件系統(tǒng)的文件訪問權(quán)限的控制保證文件的私密性Android模擬器支持SD卡,但模擬器中沒有缺省的SD卡,開發(fā)人員須在模擬

25、器中手工添加SD卡的映像文件,8.2 文件存儲,8.2.2 外部存儲使用/tools目錄下的mksdcard工具創(chuàng)建SD卡映像文件,命令如下第1個參數(shù)-1表示后面的字符串是SD卡的標簽,這個新建立的SD卡的標簽是SDCARD第2個參數(shù)256M表示SD卡的容量是256兆最后一個參數(shù)表示SD卡映像文件的保存位置,上面的命令將映像保存在E:\android目錄下sdcard_file文件中。在CMD中執(zhí)行該命令后,則可在所指定的目

26、錄中找到生產(chǎn)的SD卡映像文件,8.2 文件存儲,8.2.2 外部存儲如果希望Android模擬器啟動時能夠自動加載指定的SD卡,還需要在模擬器的“運行設(shè)置”(Run Configurations)中添加SD卡加載命令SD卡加載命令中只要指明映像文件位置即可SD卡加載命令,8.2 文件存儲,8.2.2 外部存儲測試SD卡映像是否正確加載在模擬器啟動后,使用FileExplorer向SD卡中隨意上傳一個文件,如果文件上傳成功,則表

27、明SD卡映像已經(jīng)成功加載向SD卡中成功上傳了一個測試文件test.txt,文件顯示在/sdcard目錄下,8.2 文件存儲,8.2.2 外部存儲編程訪問SD卡首先需要檢測系統(tǒng)的/sdcard目錄是否可用如果不可用,則說明設(shè)備中的SD卡已經(jīng)被移除,在Android模擬器則表明SD卡映像沒有被正確加載如果可用,則直接通過使用標準的Java.io.File類進行訪問將數(shù)據(jù)保存在SD卡通過“生產(chǎn)隨機數(shù)列”按鈕生產(chǎn)10個隨機小數(shù)通

28、過“寫入SD卡”按鈕將生產(chǎn)的數(shù)據(jù)保存在SD卡的目錄下SDcardFileDemo示例說明了如何將數(shù)據(jù)保存在SD卡,8.2 文件存儲,8.2.2 外部存儲下圖是SDcardFileDemo示例的用戶界面,8.2 文件存儲,8.2.2 外部存儲SDcardFileDemo示例運行后,在每次點擊“寫入SD卡”按鈕后,都會在SD卡中生產(chǎn)一個新文件,文件名各不相同SD卡中生產(chǎn)的文件,8.2 文件存儲,8.2.2 外部存儲SDcardFi

29、leDemo示例與InternalFileDemo示例的核心代碼比較相似SDcardFileDemo示例與InternalFileDemo示例的不同之處第7行代碼中添加了/sdcard目錄存在性檢查第8行代碼使用“絕對目錄+文件名”的形式表示新建立的文件第12行代碼寫入文件前對文件存在性和可寫入性進行檢查第5行代碼為了保證在SD卡中多次寫入時文件名不會重復(fù),在文件名中使用了唯一且不重復(fù)的標識,這個標識通過調(diào)用System.cu

30、rrentTimeMillis()函數(shù)獲得,表示從1970年00:00:00到當前所經(jīng)過的毫秒數(shù),8.2 文件存儲,8.2.2 外部存儲下面是SDcardFileDemo示例的核心代碼,8.2 文件存儲,8.2.2 外部存儲,8.2 文件存儲,8.2.3 資源文件程序開發(fā)人員可以將程序開發(fā)階段已經(jīng)準備好的原始格式文件和XML文件分別存放在/res/raw和/res/xml目錄下,供應(yīng)用程序在運行時進行訪問原始格式文件可以是任何格式

31、的文件,例如視頻格式文件、音頻格式文件、圖像文件和數(shù)據(jù)文件等等,在應(yīng)用程序編譯和打包時,/res/raw目錄下的所有文件都會保留原有格式不變/res/xml目錄下的XML文件,一般用來保存格式化的數(shù)據(jù),在應(yīng)用程序編譯和打包時會將XML文件轉(zhuǎn)換為高效的二進制格式,應(yīng)用程序運行時會以特殊的方式進行訪問,8.2 文件存儲,8.2.3 資源文件ResourceFileDemo示例演示了如何在程序運行時訪問資源文件當用戶點擊“讀取原始文件”

32、按鈕時,程序?qū)⒆x取/res/raw/raw_file.txt文件,并將內(nèi)容顯示在界面上,8.2 文件存儲,8.2.3 資源文件當用戶點擊“讀取XML文件”按鈕時,程序?qū)⒆x取/res/xml/people.xml文件,并將內(nèi)容顯示在界面上,8.2 文件存儲,8.2.3 資源文件讀取原始格式文件,首先需要調(diào)用getResource()函數(shù)獲得資源對象,然后通過調(diào)用資源對象的openRawResource()函數(shù),以二進制流的形式打開指定

33、的原始格式文件。在讀取文件結(jié)束后,調(diào)用close()函數(shù)關(guān)閉文件流ResourceFileDemo示例中關(guān)于讀取原始格式文件的核心代碼如下,8.2 文件存儲,8.2.3 資源文件代碼第8行的new String(reader,"utf-8"),表示以UTF-8的編碼方式,從字節(jié)數(shù)組中實例化一個字符串程序開發(fā)人員需要確定/res/raw/raw_file.txt文件使用的是UTF-8編碼方式,否則程

34、序運行時會產(chǎn)生亂碼,8.2 文件存儲,8.2.3 資源文件確認的方法右擊raw_file.txt文件選擇“Properties”打開raw_file.txt文件的屬性設(shè)置框在Resource欄下的Text file encoding中,選擇“Other:UTF-8”,8.2 文件存儲,8.2.3 資源文件/res/xml目錄下的XML文件會轉(zhuǎn)換為一種高效的二進制格式說明如何在程序運行時讀取/res/xml目錄下的XML文件

35、首先在/res/xml目錄下創(chuàng)建一個名為people.xml的文件XML文件定義了多個元素,每個元素都包含三個屬性name、age和height,分別表示姓名、年齡和身高/res/xml/people.xml文件代碼如下,8.2 文件存儲,8.2.3 資源文件讀取XML格式文件首先通過調(diào)用資源對象的getXml()函數(shù),獲取到XML解析器XmlPullParserXmlPullParser是Android平臺標準的XML解析器

36、,這項技術(shù)來自一個開源的XML解析API項目XMLPULLResourceFileDemo示例中關(guān)于讀取XML文件的核心代碼如下,8.2 文件存儲,8.2.3 資源文件,8.2 文件存儲,8.2.3 資源文件第1行代碼通過資源對象的getXml()函數(shù)獲取到XML解析器第4行代碼的parser.next()方法可以獲取到高等級的解析事件,并通過對比確定事件類型第5行代碼使用getName()函數(shù)獲得元素的名稱第10行

37、代碼使用getAttributeCount()函數(shù)獲取元素的屬性數(shù)量,8.2 文件存儲,8.2.3 資源文件第12行代碼通過getAttributeName()函數(shù)得到屬性名稱第14行到第19行代碼通過分析屬性名獲取到正確的屬性值第23行代碼將屬性值整理成需要顯示的信息XmlPullParser的XML事件類型,8.3 數(shù)據(jù)庫存儲,8.3.1 SQLite數(shù)據(jù)庫SQLite是一個開源的嵌入式關(guān)系數(shù)據(jù)庫,在2000年由D. Ri

38、chard Hipp發(fā)布SQLite數(shù)據(jù)庫特點更加適用于嵌入式系統(tǒng),嵌入到使用它的應(yīng)用程序中占用非常少,運行高效可靠,可移植性好提供了零配置(zero-configuration)運行模式SQLite數(shù)據(jù)庫不僅提高了運行效率,而且屏蔽了數(shù)據(jù)庫使用和管理的復(fù)雜性,程序僅需要進行最基本的數(shù)據(jù)操作,其他操作可以交給進程內(nèi)部的數(shù)據(jù)庫引擎完成,8.3 數(shù)據(jù)庫存儲,8.3.1 SQLite數(shù)據(jù)庫SQLite數(shù)據(jù)庫采用了模塊化設(shè)計,由8個

39、獨立的模塊構(gòu)成,這些獨立模塊又構(gòu)成了三個主要的子系統(tǒng),模塊將復(fù)雜的查詢過程分解為細小的工作進行處理,,8.3 數(shù)據(jù)庫存儲,8.3.1 SQLite數(shù)據(jù)庫接口由SQLite C API組成,因此無論是應(yīng)用程序、腳本,還是庫文件,最終都是通過接口與SQLite交互編譯器由分詞器和分析器組成分詞器和分析器對SQL語句進行語法檢查,然后把SQL語句轉(zhuǎn)化為底層能更方便處理的分層的數(shù)據(jù)結(jié)構(gòu),這種分層的數(shù)據(jù)結(jié)構(gòu)稱為“語法樹”把語法樹傳給代碼

40、生成器進行處理,生成一種針對SQLite的匯編代碼最后由虛擬機執(zhí)行,8.3 數(shù)據(jù)庫存儲,8.3.1 SQLite數(shù)據(jù)庫虛擬機SQLite數(shù)據(jù)庫體系結(jié)構(gòu)中最核心的部分是虛擬機,也稱為虛擬數(shù)據(jù)庫引擎(Virtual Database Engine,VDBE)與Java虛擬機相似,虛擬數(shù)據(jù)庫引擎用來解釋執(zhí)行字節(jié)代碼虛擬數(shù)據(jù)庫引擎的字節(jié)代碼由128個操作碼構(gòu)成,這些操作碼主要用以對數(shù)據(jù)庫進行操作,每一條指令都可以完成特定的數(shù)據(jù)庫操作,

41、或以特定的方式處理棧的內(nèi)容,8.3 數(shù)據(jù)庫存儲,8.3.1 SQLite數(shù)據(jù)庫后端后端由B-樹、頁緩存和操作系統(tǒng)接口構(gòu)成B-樹的主要功能就是索引,它維護著各個頁面之間的復(fù)雜的關(guān)系,便于快速找到所需數(shù)據(jù)頁緩存的主要作用就是通過操作系統(tǒng)接口在B-樹和磁盤之間傳遞頁面B-樹和頁緩存共同對數(shù)據(jù)進行管理,8.3 數(shù)據(jù)庫存儲,8.3.1 SQLite數(shù)據(jù)庫SQLite數(shù)據(jù)庫具有很強的移植性,可以運行在Windows,Linux,BSD,

42、Mac OS X和一些商用Unix系統(tǒng),比如Sun的Solaris,IBM的AIXSQLite數(shù)據(jù)庫也可以工作在許多嵌入式操作系統(tǒng)下,例如QNX,VxWorks,Palm OS,Symbin和Windows CESQLite的核心大約有3萬行標準C代碼,模塊化的設(shè)計使這些代碼更加易于理解,8.3 數(shù)據(jù)庫存儲,8.3.2 手動建庫手動建立數(shù)據(jù)庫指的是使用sqlite3工具,通過手工輸入命令行完成數(shù)據(jù)庫的建立過程sqlite3是SQ

43、Lite數(shù)據(jù)庫自帶的一個基于命令行的SQL命令執(zhí)行工具,并可以顯示命令執(zhí)行結(jié)果sqlite3工具被集成在Android系統(tǒng)中,用戶在Linux的命令行界面中輸入sqlite3可啟動sqlite3工具,并得到工具的版本信息,如下面的代碼所示啟動Linux的命令行界面的方法是在CMD中輸入adb shell命令,8.3 數(shù)據(jù)庫存儲,8.3.2 手動建庫在啟動sqlite3工具后,提示符從“#”變?yōu)椤皊qlite>”,表示命令行界

44、面進入與SQLite數(shù)據(jù)庫的交互模式,此時可以輸入命令建立、刪除或修改數(shù)據(jù)庫的內(nèi)容正確退出sqlite3工具的方法是使用.exit命令原則上,每個應(yīng)用程序的數(shù)據(jù)庫都保存在各自的/data/data//databases目錄下,但如果使用手工方式建立數(shù)據(jù)庫,則必須手工建立數(shù)據(jù)庫目錄,目前版本無須修改數(shù)據(jù)庫目錄的權(quán)限,8.3 數(shù)據(jù)庫存儲,8.3.2 手動建庫在SQLite數(shù)據(jù)庫中,每個數(shù)據(jù)庫保存在一個獨立的文件中,使用sqlite3

45、工具后加文件名的方式打開數(shù)據(jù)庫文件,如果指定文件不存在,sqlite3工具則自動創(chuàng)建新文件下面的代碼將創(chuàng)建名為people的數(shù)據(jù)庫,在文件系統(tǒng)中將產(chǎn)生一個名為people.db的數(shù)據(jù)庫文件,8.3 數(shù)據(jù)庫存儲,8.3.2 手動建庫下面的代碼在新創(chuàng)建的數(shù)據(jù)庫中,構(gòu)造了一個名為peopleinfo的表,使用create table命令,關(guān)系模式為peopleinfo ( _id, name, age, height)表包含四個屬性,_

46、id是整型的主鍵;name表示姓名,字符型,not null表示這個屬性一定要填寫,不可以為空值;age表示年齡,整數(shù)型;height表示身高,浮點型,8.3 數(shù)據(jù)庫存儲,8.3.2 手動建庫為了確認數(shù)據(jù)表是否創(chuàng)建成功,可以使用.tables命令,顯示當前數(shù)據(jù)庫中的所有表從下面的代碼中可以觀察到,當前數(shù)據(jù)庫僅有一個名為peopleinfo的表當然,也可以使用.schema命令查看建立表時使用的SQL命令。如果當前數(shù)據(jù)庫中包含多

47、個表,則可以使用[.schema 表名]的形式,顯示指定表的建立命令,8.3 數(shù)據(jù)庫存儲,8.3.2 手動建庫向peopleinfo表中添加數(shù)據(jù),使用insert into … values命令代碼運行成功后,數(shù)據(jù)庫的peopleinfo表將有三條數(shù)據(jù)。因為_id是自增加的主鍵,因此在輸入null后,SQLite數(shù)據(jù)庫會自動填寫該項的內(nèi)容,8.3 數(shù)據(jù)庫存儲,8.3.2 手動建庫在數(shù)據(jù)添加完畢后,使用select命令,顯示指定

48、數(shù)據(jù)表中的所有數(shù)據(jù)信息,命令格式為[select 屬性 from 表名]下面的代碼用來顯示peopleinfo表的所有數(shù)據(jù),8.3 數(shù)據(jù)庫存儲,8.3.2 手動建庫上面的查詢結(jié)果看起來不是非常直觀,可以使用mode命令將結(jié)果輸出格式更改為“表格”方式mode命令除了支持常見的column格式為,還支持csv格式、html格式、insert格式、line格式、list格式、tabs格式和tcl格式,8.3 數(shù)據(jù)庫存儲,8.3.2 手

49、動建庫更新數(shù)據(jù)可以使用update命令,命令格式為[update 表名 set 屬性=“新值” where 條件]更新數(shù)據(jù)后,同樣使用select命令顯示數(shù)據(jù),則可以確定數(shù)據(jù)是否正確更新下面的代碼將姓名為Lily數(shù)據(jù)中的高度值更新為1.88,8.3 數(shù)據(jù)庫存儲,8.3.2 手動建庫刪除數(shù)據(jù)可以使用delete命令,命令格式為[delete from 表名where 條件]下面的代碼將_id為3數(shù)據(jù)從表peopleinfo中刪除

50、,8.3 數(shù)據(jù)庫存儲,8.3.2 手動建庫sqlite3工具還支持大量的命令,可以使用.help命令查詢sqlite3的命令列表,8.3 數(shù)據(jù)庫存儲,8.3.2 手動建庫,8.3 數(shù)據(jù)庫存儲,8.3.2 手動建庫,8.3 數(shù)據(jù)庫存儲,8.3.3 代碼建庫在代碼中動態(tài)建立數(shù)據(jù)庫是比較常用的方法在程序運行過程中,當需要進行數(shù)據(jù)庫操作時,應(yīng)用程序會首先嘗試打開數(shù)據(jù)庫,此時如果數(shù)據(jù)庫并不存在,程序則會自動建立數(shù)據(jù)庫,然后再打開數(shù)據(jù)庫在編

51、程實現(xiàn)時,一般將所有對數(shù)據(jù)庫的操作都封裝在一個類中,因此只要調(diào)用這個類,就可以完成對數(shù)據(jù)庫的添加、更新、刪除和查詢等操作,8.3 數(shù)據(jù)庫存儲,8.3.3 代碼建庫下面內(nèi)容是DBAdapter類的部分代碼,封裝了數(shù)據(jù)庫的建立、打開和關(guān)閉等操作,8.3 數(shù)據(jù)庫存儲,8.3.3 代碼建庫,8.3 數(shù)據(jù)庫存儲,8.3.3 代碼建庫從代碼的第2行到第9行可以看出,在DBAdapter類中首先聲明了數(shù)據(jù)庫的基本信息,包括數(shù)據(jù)庫文件的名

52、稱、數(shù)據(jù)庫表格名稱和數(shù)據(jù)庫版本,以及數(shù)據(jù)庫表中的屬性名稱從這些基本信息上不難發(fā)現(xiàn),這個數(shù)據(jù)庫與前一小節(jié)手動建立的數(shù)據(jù)庫是完全相同的,8.3 數(shù)據(jù)庫存儲,8.3.3 代碼建庫第11行代碼聲明了SQLiteDatabase對象db。SQLiteDatabase類封裝了非常多的方法,用以建立、刪除數(shù)據(jù)庫,執(zhí)行SQL命令,對數(shù)據(jù)進行管理等工作第13行代碼聲明了一個非常重要的幫助類SQLiteOpenHelper,這個幫助類可以輔助建立、更

53、新和打開數(shù)據(jù)庫第21行代碼定義了open()函數(shù)用來打開數(shù)據(jù)庫,但open()函數(shù)中并沒有任何對數(shù)據(jù)庫進行實際操作的代碼,而是調(diào)用了SQLiteOpenHelper類的getWritableDatabase()函數(shù)和getReadableDatabase()函數(shù)。這個兩個函數(shù)會根據(jù)數(shù)據(jù)庫是否存在、版本號和是否可寫等情況,決定在返回數(shù)據(jù)庫對象前,是否需要建立數(shù)據(jù)庫,8.3 數(shù)據(jù)庫存儲,8.3.3 代碼建庫在代碼第30行的close()

54、函數(shù)中,調(diào)用了SQLiteDatabase對象的close()方法關(guān)閉數(shù)據(jù)庫這是上面的代碼中,唯一的一個地方直接調(diào)用了SQLiteDatabase對象的方法SQLiteDatabase中也封裝了打開數(shù)據(jù)庫的函數(shù)openDatabases()和創(chuàng)建數(shù)據(jù)庫函數(shù)openOrCreateDatabases(),因為代碼中使用了幫助類SQLiteOpenHelper,從而避免直接調(diào)用SQLiteDatabase中的打開和創(chuàng)建數(shù)據(jù)庫的方法,簡化

55、了數(shù)據(jù)庫打開過程中繁瑣的邏輯判斷過程代碼第15行實現(xiàn)了內(nèi)部靜態(tài)類DBOpenHelper,繼承了幫助類SQLiteOpenHelper,8.3 數(shù)據(jù)庫存儲,8.3.3 代碼建庫重載了onCreate()函數(shù)和onUpgrade()函數(shù)的代碼如下,8.3 數(shù)據(jù)庫存儲,8.3.3 代碼建庫第5行到第7行代碼的是創(chuàng)建表的SQL命令第10行和第15行代碼分別重載了onCreate()函數(shù)和onUpgrade()函數(shù),這是繼承

56、SQLiteOpenHelper類必須重載的兩個函數(shù)。onCreate()函數(shù)在數(shù)據(jù)庫第一次建立時被調(diào)用,一般用來用來創(chuàng)建數(shù)據(jù)庫中的表,并做適當?shù)某跏蓟ぷ?8.3 數(shù)據(jù)庫存儲,8.3.3 代碼建庫在代碼第11行中,通過調(diào)用SQLiteDatabase對象的execSQL()方法,執(zhí)行創(chuàng)建表的SQL命令。onUpgrade()函數(shù)在數(shù)據(jù)庫需要升級時被調(diào)用,一般用來刪除舊的數(shù)據(jù)庫表,并將數(shù)據(jù)轉(zhuǎn)移到新版本的數(shù)據(jù)庫表中第16行和第17行代

57、碼中,為了簡單起見,并沒有做任何的的數(shù)據(jù)轉(zhuǎn)移,而僅僅刪除原有的表后建立新的數(shù)據(jù)庫表,8.3 數(shù)據(jù)庫存儲,8.3.3 代碼建庫程序開發(fā)人員不應(yīng)直接調(diào)用onCreate()和onUpgrade()函數(shù),而應(yīng)該由SQLiteOpenHelper類來決定何時調(diào)用這兩個函數(shù)SQLiteOpenHelper類的getWritableDatabase()函數(shù)和getReadableDatabase()函數(shù)是可以直接調(diào)用的函數(shù)getWritabl

58、eDatabase()函數(shù)用來建立或打開可讀寫的數(shù)據(jù)庫對象,一旦函數(shù)調(diào)用成功,數(shù)據(jù)庫對象將被緩存,任何需要使用數(shù)據(jù)庫對象時,都可以調(diào)用這個方法獲取到數(shù)據(jù)庫對象,但一定要在不使用時調(diào)用close()函數(shù)關(guān)閉數(shù)據(jù)庫如果保存數(shù)據(jù)庫文件的磁盤空間已滿,調(diào)用getWritableDatabase()函數(shù)則無法獲得可讀寫的數(shù)據(jù)庫對象,這時可以調(diào)用getReadableDatabase()函數(shù),獲得一個只讀的數(shù)據(jù)庫對象,8.3 數(shù)據(jù)庫存儲,8.3.

59、3 代碼建庫如果程序開發(fā)人員不希望使用SQLiteOpenHelper類,同樣可以直接創(chuàng)建數(shù)據(jù)庫首先調(diào)用openOrCreateDatabases()函數(shù)創(chuàng)建數(shù)據(jù)庫對象然后執(zhí)行SQL命令建立數(shù)據(jù)庫中的表和直接的關(guān)系示例代碼如下,8.3 數(shù)據(jù)庫存儲,8.3.4 數(shù)據(jù)操作數(shù)據(jù)操作是指對數(shù)據(jù)的添加、刪除、查找和更新的操作通過執(zhí)行SQL命名完成數(shù)據(jù)操作,但推薦使用Android提供的專用類和方法,這些類和方法更加簡潔、易用為了使D

60、BAdapter類支持對數(shù)據(jù)的添加、刪除、更新和查找等功能,在DBAdapter類中增加下面的這些函數(shù)insert(People people)用來添加一條數(shù)據(jù)queryAllData()用來獲取全部數(shù)據(jù)queryOneData(long id)根據(jù)id獲取一條數(shù)據(jù)deleteAllData()用來刪除全部數(shù)據(jù)deleteOneData(long id)根據(jù)id刪除一條數(shù)據(jù)updateOneData(long id , Pe

61、ople people)根據(jù)id更新一條數(shù)據(jù),8.3 數(shù)據(jù)庫存儲,8.3.4 數(shù)據(jù)操作ConvertToPeople(Cursor cursor)是私有函數(shù),作用是將查詢結(jié)果轉(zhuǎn)換為用來存儲數(shù)據(jù)自定義的People類對象People類的包含四個公共屬性,分別為ID、Name、Age和Height,對應(yīng)數(shù)據(jù)庫中的四個屬性值重載toString()函數(shù),主要是便于界面顯示的需要,8.3 數(shù)據(jù)庫存儲,8.3.4 數(shù)據(jù)操作P

62、eople類的代碼如下,8.3 數(shù)據(jù)庫存儲,8.3.4 數(shù)據(jù)操作SQLiteDatabase類的公共函數(shù)insert()、delete()、update()和query(),封裝了執(zhí)行的添加、刪除、更新和查詢功能的SQL命令下面分別介紹如何使用SQLiteDatabase類的公共函數(shù),完成數(shù)據(jù)的添加、刪除、更新和查詢等操作,8.3 數(shù)據(jù)庫存儲,8.3.4 數(shù)據(jù)操作添加功能首先構(gòu)造一個ContentValues對象,然后調(diào)用Con

63、tentValues對象的put()方法,將每個屬性的值寫入到ContentValues對象中,最后使用SQLiteDatabase對象的insert()函數(shù),將ContentValues對象中的數(shù)據(jù)寫入指定的數(shù)據(jù)庫表中insert()函數(shù)的返回值是新數(shù)據(jù)插入的位置,即ID值。ContentValues類是一個數(shù)據(jù)承載容器,主要用來向數(shù)據(jù)庫表中添加一條數(shù)據(jù),8.3 數(shù)據(jù)庫存儲,8.3.4 數(shù)據(jù)操作第4行代碼向Conte

64、ntValues對象newValues中添加一個名稱/值對,put()函數(shù)的第1個參數(shù)是名稱,第2個參數(shù)是值在第8行代碼的insert()函數(shù)中,第1個參數(shù)是數(shù)據(jù)表的名稱,第2個參數(shù)是在NULL時的替換數(shù)據(jù),第3個參數(shù)是需要向數(shù)據(jù)庫表中添加的數(shù)據(jù),8.3 數(shù)據(jù)庫存儲,8.3.4 數(shù)據(jù)操作刪除功能刪除數(shù)據(jù)比較簡單,只需要調(diào)用當前數(shù)據(jù)庫對象的delete()函數(shù),并指明表名稱和刪除條件即可delete()函數(shù)的第1個參數(shù)是數(shù)

65、據(jù)庫的表名稱,第2個參數(shù)是刪除條件在第2行代碼中,刪除條件為null,表示刪除表中的所有數(shù)據(jù)第6行代碼指明了需要刪除數(shù)據(jù)的id值,因此deleteOneData()函數(shù)僅刪除一條數(shù)據(jù),此時delete()函數(shù)的返回值表示被刪除的數(shù)據(jù)的數(shù)量,8.3 數(shù)據(jù)庫存儲,8.3.4 數(shù)據(jù)操作更新功能更新數(shù)據(jù)同樣要使用ContentValues對象,首先構(gòu)造ContentValues對象,然后調(diào)用put()函數(shù)將屬性的值寫入到ContentV

66、alues對象中,最后使用SQLiteDatabase對象的update()函數(shù),并指定數(shù)據(jù)的更新條件在代碼的第7行中,update()函數(shù)的第1個參數(shù)表示數(shù)據(jù)表的名稱,第2個參數(shù)是更新條件。update()函數(shù)的返回值表示數(shù)據(jù)庫表中被更新的數(shù)據(jù)數(shù)量,8.3 數(shù)據(jù)庫存儲,8.3.4 數(shù)據(jù)操作查詢功能首先介紹Cursor類。在Android系統(tǒng)中,數(shù)據(jù)庫查詢結(jié)果的返回值并不是數(shù)據(jù)集合的完整拷貝,而是返回數(shù)據(jù)集的指針,這個指

67、針就是Cursor類Cursor類支持在查詢的數(shù)據(jù)集合中多種方式移動,并能夠獲取數(shù)據(jù)集合的屬性名稱和序號,8.3 數(shù)據(jù)庫存儲,8.3.4 數(shù)據(jù)操作Cursor類的方法和說明,,8.3 數(shù)據(jù)庫存儲,8.3.4 數(shù)據(jù)操作從Cursor中提取數(shù)據(jù)可以參考ConvertToPeople()函數(shù)的實現(xiàn)方法在提取Cursor數(shù)據(jù)中的數(shù)據(jù)前,推薦測試Cursor中的數(shù)據(jù)數(shù)量,避免在數(shù)據(jù)獲取中產(chǎn)生異常,例如代碼的第3行到第5行從Cursor中

68、提取數(shù)據(jù)使用類型安全的get()函數(shù),函數(shù)的輸入值為屬性的序號,為了獲取屬性的序號,可以使用getColumnIndex()函數(shù)獲取指定屬性的序號,8.3 數(shù)據(jù)庫存儲,8.3.4 數(shù)據(jù)操作,8.3 數(shù)據(jù)庫存儲,8.3.4 數(shù)據(jù)操作要進行數(shù)據(jù)查詢就需要調(diào)用SQLiteDatabase類的query()函數(shù),query()函數(shù)的語法如下query()函數(shù)的參數(shù)說明,8.3 數(shù)據(jù)庫存儲,8.3.4 數(shù)據(jù)操作根據(jù)id查詢數(shù)據(jù)的代碼

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論