在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ iOS/ Android 中的 SQLite 數(shù)據(jù)庫支持
與四軸無人機(jī)的通訊
在沙盒中編寫腳本
結(jié)構(gòu)體和值類型
深入理解 CocoaPods
UICollectionView + UIKit 力學(xué)
NSString 與 Unicode
代碼簽名探析
測(cè)試
架構(gòu)
第二期-并發(fā)編程
Metal
自定義控件
iOS 中的行為
行為驅(qū)動(dòng)開發(fā)
Collection View 動(dòng)畫
截圖測(cè)試
MVVM 介紹
使 Mac 應(yīng)用數(shù)據(jù)腳本化
一個(gè)完整的 Core Data 應(yīng)用
插件
字符串
為 iOS 建立 Travis CI
先進(jìn)的自動(dòng)布局工具箱
動(dòng)畫
為 iOS 7 重新設(shè)計(jì) App
XPC
從 NSURLConnection 到 NSURLSession
Core Data 網(wǎng)絡(luò)應(yīng)用實(shí)例
GPU 加速下的圖像處理
自定義 Core Data 遷移
子類
與調(diào)試器共舞 - LLDB 的華爾茲
圖片格式
并發(fā)編程:API 及挑戰(zhàn)
IP,TCP 和 HTTP
動(dòng)畫解釋
響應(yīng)式 Android 應(yīng)用
初識(shí) TextKit
客戶端
View-Layer 協(xié)作
回到 Mac
Android
Core Image 介紹
自定義 Formatters
Scene Kit
調(diào)試
項(xiàng)目介紹
Swift 的強(qiáng)大之處
測(cè)試并發(fā)程序
Android 通知中心
調(diào)試:案例學(xué)習(xí)
從 UIKit 到 AppKit
iOS 7 : 隱藏技巧和變通之道
安全
底層并發(fā) API
消息傳遞機(jī)制
更輕量的 View Controllers
用 SQLite 和 FMDB 替代 Core Data
字符串解析
終身學(xué)習(xí)的一代人
視頻
Playground 快速原型制作
Omni 內(nèi)部
同步數(shù)據(jù)
設(shè)計(jì)優(yōu)雅的移動(dòng)游戲
繪制像素到屏幕上
相機(jī)與照片
音頻 API 一覽
交互式動(dòng)畫
常見的后臺(tái)實(shí)踐
糟糕的測(cè)試
避免濫用單例
數(shù)據(jù)模型和模型對(duì)象
Core Data
字符串本地化
View Controller 轉(zhuǎn)場(chǎng)
照片框架
響應(yīng)式視圖
Square Register 中的擴(kuò)張
DTrace
基礎(chǔ)集合類
視頻工具箱和硬件加速
字符串渲染
讓東西變得不那么糟
游戲中的多點(diǎn)互聯(lián)
iCloud 和 Core Data
Views
虛擬音域 - 聲音設(shè)計(jì)的藝術(shù)
導(dǎo)航應(yīng)用
線程安全類的設(shè)計(jì)
置換測(cè)試: Mock, Stub 和其他
Build 工具
KVC 和 KVO
Core Image 和視頻
Android Intents
在 iOS 上捕獲視頻
四軸無人機(jī)項(xiàng)目
Mach-O 可執(zhí)行文件
UI 測(cè)試
值對(duì)象
活動(dòng)追蹤
依賴注入
Swift
項(xiàng)目管理
整潔的 Table View 代碼
Swift 方法的多面性
為什么今天安全仍然重要
Core Data 概述
Foundation
Swift 的函數(shù)式 API
iOS 7 的多任務(wù)
自定義 Collection View 布局
測(cè)試 View Controllers
訪談
收據(jù)驗(yàn)證
數(shù)據(jù)同步
自定義 ViewController 容器轉(zhuǎn)場(chǎng)
游戲
調(diào)試核對(duì)清單
View Controller 容器
學(xué)無止境
XCTest 測(cè)試實(shí)戰(zhàn)
iOS 7
Layer 中自定義屬性的動(dòng)畫
第一期-更輕量的 View Controllers
精通 iCloud 文檔存儲(chǔ)
代碼審查的藝術(shù):Dropbox 的故事
GPU 加速下的圖像視覺
Artsy
照片擴(kuò)展
理解 Scroll Views
使用 VIPER 構(gòu)建 iOS 應(yīng)用
Android 中的 SQLite 數(shù)據(jù)庫支持
Fetch 請(qǐng)求
導(dǎo)入大數(shù)據(jù)集
iOS 開發(fā)者的 Android 第一課
iOS 上的相機(jī)捕捉
語言標(biāo)簽
同步案例學(xué)習(xí)
依賴注入和注解,為什么 Java 比你想象的要好
編譯器
基于 OpenCV 的人臉識(shí)別
玩轉(zhuǎn)字符串
相機(jī)工作原理
Build 過程

Android 中的 SQLite 數(shù)據(jù)庫支持

開袋即食

我們大多數(shù)人都至少熟悉某些 Core Data 提供給我們的直接可用的持久化特性。然而不幸的是,它們中的很多在 Android 平臺(tái)上并不是自動(dòng)化的。 例如,Core Data 抽象出大部分?jǐn)?shù)據(jù)庫的 SQL 語法和數(shù)據(jù)庫標(biāo)準(zhǔn),這些語法和標(biāo)準(zhǔn)都是數(shù)據(jù)庫工程師們每天面對(duì)的問題。 因?yàn)?Android 僅提供一個(gè)簡(jiǎn)單的 SQLite 客戶端,所以你扔需要寫 SQL 并且確保你的數(shù)據(jù)庫表被適當(dāng)?shù)臉?biāo)準(zhǔn)化了。

Core Data 允許我們?cè)趯?duì)象方面考慮。 實(shí)際上,它能自動(dòng)處理列集和散集對(duì)象。 得益于其提供了記錄層的緩存,所以它在移動(dòng)設(shè)備上的性能很好。每次從存儲(chǔ)中請(qǐng)求同樣的數(shù)據(jù)段時(shí),它不用再創(chuàng)建另外一個(gè)的對(duì)象實(shí)例。當(dāng)觀察一個(gè)對(duì)象的變化時(shí),我們甚至不需要刷新那個(gè)被觀察對(duì)象就能做到。

Android 上可不是這種情況。你要完全負(fù)責(zé)將對(duì)象寫入數(shù)據(jù)庫或者從中將它們讀取。這意味著你要自己實(shí)現(xiàn)對(duì)象緩存(如果需要的話),管理對(duì)象實(shí)例化,以及手動(dòng)對(duì)任何已存在對(duì)象進(jìn)行是否需要變更的檢測(cè)。

在 Android 中,你需要注意版本特定的功能。不同版本的 Android 使用不同的 SQLite 實(shí)現(xiàn)。這意味著同一個(gè)數(shù)據(jù)庫指令可能在其他平臺(tái)版本上產(chǎn)生完全不同的結(jié)果。根據(jù)你執(zhí)行的 SQLite 版本不同,一個(gè)查詢語句也會(huì)執(zhí)行得各不相同。

填缺補(bǔ)空

許多Android開發(fā)者來自企業(yè)。許多年來,對(duì)象關(guān)系型映射庫一直在服務(wù)器平臺(tái)上用于減輕與數(shù)據(jù)庫的交互的難度。然而,這些庫因?yàn)樾阅軉栴}而導(dǎo)致無法在移動(dòng)端直接使用。意識(shí)到這一點(diǎn),一些開發(fā)者組織起來制作了面向移動(dòng)端的 ORM 庫來解決這一問題。

在 Android 上給 SQLite 添加 ORM 支持的其中一個(gè)使用廣泛的的方法是 OrmLite。OrmLite 提供對(duì)持久化對(duì)象的自動(dòng)列集和散集化。它不用寫大量的 SQL,并且提供程序接口來查詢,更新,刪除對(duì)象。在 ORM 中另一個(gè)競(jìng)爭(zhēng)者是 greenDAO。它提供許多與 OrmLite 類似的功能,但是承諾具有更好的性能(根據(jù)它的網(wǎng)站上說),例如基于注解的設(shè)置。

對(duì)第三方庫通常都是抱怨都是加到項(xiàng)目中以后造成了額外的復(fù)雜度并且使得性能臃腫。有開發(fā)者覺得這實(shí)在很蛋疼,于是他寫了一個(gè)叫 Cupboard 的輕量級(jí) Android SQLite 框架的封裝。它聲稱的目標(biāo)是在不使用 ContentValues 和不解析 Cursors 的情況下為 Java 對(duì)象的提供持久化存儲(chǔ),它將會(huì)簡(jiǎn)單輕量,并整合時(shí)不會(huì)對(duì)核心 Android 類造成任何影響。你仍將需要管理數(shù)據(jù)庫的創(chuàng)建,但是查詢對(duì)象會(huì)變得簡(jiǎn)單很多。

還有開發(fā)者決定完全廢棄 SQLite 并且創(chuàng)建了 Perst。它從開始到接口都是用面向?qū)ο笳Z言設(shè)計(jì)的。它善于列集和散集對(duì)象,并且在性能跑分中表現(xiàn)很好。這種解決方法確實(shí)是完全替換了部分 Android 框架,但是也存在一定風(fēng)險(xiǎn),因?yàn)槟憧赡芎茈y再在以后將其替換成不同方案了。

有這些甚至是更多可用的選擇,為什么大家還都選擇在原始的 Android 數(shù)據(jù)庫框架下開發(fā)呢?這么說吧,框架和封裝相較于它們所解決的問題,有時(shí)候能帶來更多麻煩。例如,在一個(gè)項(xiàng)目中,我們同時(shí)寫入數(shù)據(jù)庫且實(shí)例化很多對(duì)象,這就會(huì)導(dǎo)致我們的 ORM 庫慢得像爬一樣。因?yàn)檫@個(gè)庫不是設(shè)計(jì)用來讓我們以這樣的方式使用的。

在評(píng)估框架和庫的時(shí)候,檢查看看有沒有使用 Java 的反射機(jī)制。反射機(jī)制在 Java 中代價(jià)相對(duì)較大,因此要謹(jǐn)慎使用。另外,如果你的項(xiàng)目是 Ice Cream Sandwich 前的版本,還要看看你的庫是否在使用 Java 最近解決的一個(gè) bug,它會(huì)導(dǎo)致在運(yùn)行時(shí)因?yàn)樽⒔舛鴮?dǎo)致的性能下降。

最后,還要評(píng)估添加框架會(huì)不會(huì)顯著的增加項(xiàng)目的復(fù)雜度。如果你與其他開發(fā)者共同開發(fā),記住,他們也必須花時(shí)間來學(xué)習(xí)該庫。在你決定要不要使用一個(gè)第三方解決方案之前,弄明白 Android 到底是如何處理數(shù)據(jù)存儲(chǔ)的這一問題,是非常重要的。

打開數(shù)據(jù)庫

Android 上創(chuàng)建和打開數(shù)據(jù)庫相對(duì)簡(jiǎn)單。你必須通過子類化 SQLiteOpenHelper 來進(jìn)行實(shí)現(xiàn)。默認(rèn)的構(gòu)造方法中,你要制定數(shù)據(jù)庫名字。如果該數(shù)據(jù)庫已經(jīng)存在,它會(huì)被打開。如果不存在,則會(huì)被創(chuàng)建。應(yīng)用能有許多單獨(dú)的數(shù)據(jù)庫文件。每個(gè)數(shù)據(jù)庫都必須表示為單獨(dú)的 SQLiteOpenHelper 子類。

數(shù)據(jù)庫文件對(duì)你的應(yīng)用來說是私有的,它們存在文件系統(tǒng)中你的應(yīng)用的子文件夾下,并且受Linux文件訪問權(quán)限保護(hù)??上У氖牵瑪?shù)據(jù)庫文件沒有加密。

但是創(chuàng)建數(shù)據(jù)庫文件是不夠的,在你的 SQLiteOpenHelper 子類中,你要重寫 onCreate() 方法執(zhí)行SQL語句創(chuàng)建表,視圖以及任何數(shù)據(jù)庫模式(schema)中的東西。你可以重寫例如 onConfigure() 之類的其他方法來啟用或禁用數(shù)據(jù)庫功能,比如預(yù)寫日志或外鍵支持等。

改變數(shù)據(jù)庫模式 (schema)

除了在 SQLiteOpenHelper 子類的構(gòu)造方法中指定數(shù)據(jù)庫名字,你還要指定數(shù)據(jù)庫版本號(hào)。版本號(hào)對(duì)于任意一個(gè)給定的 release 版本必須是不變的,而且根據(jù)框架的要求,這個(gè)數(shù)需要是只增不減的。

SQLiteOpenHelper 使用數(shù)據(jù)庫的版本號(hào)來決定是否需要升級(jí)或降級(jí)。在升級(jí)或降級(jí)的回調(diào)方法中,你將使用提供給你的 oldVersionnewVersion 參數(shù)來決定哪個(gè) ALTER 語句需要執(zhí)行來更新 schema。為每個(gè)新數(shù)據(jù)庫版本提供單獨(dú)的語句是一種很好的方法,這樣就可以處理數(shù)據(jù)庫的跨版本升級(jí)了。

連接到數(shù)據(jù)庫

數(shù)據(jù)庫查詢是由 SQLiteDatabase 類來管理的。 在你的 SQLiteOpenHelper 子類調(diào)用 getReadableDatabase()getWritableDatabase() 時(shí),會(huì)返回一個(gè) SQLiteDatabase 實(shí)例。要注意這些方法通常會(huì)返回同一個(gè)對(duì)象。唯一一個(gè)例外是 getReadableDatabase(),在遇到諸如磁盤空間已滿之類的問題時(shí),它會(huì)返回一個(gè)只讀的數(shù)據(jù)庫,這時(shí)會(huì)阻止寫入數(shù)據(jù)庫。由于磁盤問題其實(shí)很少發(fā)生,許多開發(fā)者開發(fā)過程中只調(diào)用 getWritableDatabase()。

數(shù)據(jù)庫創(chuàng)建和模式改變是在你第一次獲得 SQLiteDatabase 實(shí)例后才會(huì)進(jìn)行的。因此,你不能在主線程請(qǐng)求 SQLiteDatabase 實(shí)例。你的 SQLiteOpenHelper 子類幾乎都會(huì)返回同樣的 SQLiteDatabase 實(shí)例。這意味著在任何線程調(diào)用 SQLiteDatabase.close() 都會(huì)關(guān)閉你應(yīng)用中所有的 SQLiteDatabase 實(shí)例。這就導(dǎo)致一大堆難于查找的 bug。實(shí)際上,有些開發(fā)者選擇只在程序啟動(dòng)時(shí)打開 SQLiteDatabase ,只在程序關(guān)閉調(diào)用 close()。

查詢數(shù)據(jù)

SQLiteDatabase 提供了對(duì)數(shù)據(jù)庫進(jìn)行查詢,插入,更新及刪除的方法。對(duì)于簡(jiǎn)單的查詢,你不用寫任何 SQL。但對(duì)于更高級(jí)的查詢,你還要得自己寫 SQL。SQLiteDatabase 有一個(gè) rawQuery()execSQL() 方法, 這能把整個(gè) SQL 當(dāng)做參數(shù)來執(zhí)行高級(jí)查詢,例如使用 unions 和 joins 命令。你可以使用 SQLiteQueryBuilder 來協(xié)助你完成適當(dāng)?shù)牟樵儭?/p>

query()rawQuery() 都返回 Cursor 對(duì)象。保持 Cursor 對(duì)象的引用并且在應(yīng)用中傳來傳去聽起來十分誘人,但是 Cursor 對(duì)象比 單純的 Java 對(duì)象 (Plain Old Java Object, POJO) 耗費(fèi)更多的系統(tǒng)資源。因此,Cursor 對(duì)象需要盡快散集化到 POJO。在散集化之后你需要調(diào)用 close() 方法釋放資源。

SQLite 中支持事務(wù) (transactions)。你可以通過調(diào)用 SQLiteDatabase.beginTransaction() 開啟一個(gè)事務(wù)。事務(wù)能通過調(diào)用 beginTransaction() 嵌套。當(dāng)外層事務(wù)結(jié)束后所有在這個(gè)事務(wù)中完成的工作,以及所有嵌套的事務(wù)都需要提交或回滾。所有那些沒有用 setTransactionSuccessful() 方法標(biāo)記為完成的事務(wù)中的變更都會(huì)被回滾。

數(shù)據(jù)訪問對(duì)象 (Data Access Object)

如前面提到的,Android 不提供任何列集和散集對(duì)象的方法。這意味著我們要負(fù)責(zé)管理從 Cursor 中取數(shù)據(jù)到 POJO 中的邏輯。這套邏輯應(yīng)該用 Data Access Object (DAO) 封裝好。

Java 從業(yè)者,順帶上 Android 開發(fā)者,應(yīng)該都對(duì) DAO 模式很熟悉了。它的主要目的是將應(yīng)用的交互從持久化層中抽象出來,而不暴露持久化的實(shí)現(xiàn)細(xì)節(jié)。這可以把應(yīng)用從數(shù)據(jù)模式中隔離出來。這也使得遷移到第三方的數(shù)據(jù)庫實(shí)現(xiàn)時(shí),對(duì)應(yīng)用的核心邏輯造成的風(fēng)險(xiǎn)能更小。你的應(yīng)用中的所有與數(shù)據(jù)庫的交互都應(yīng)該通過 DAO 實(shí)現(xiàn)。

異步加載數(shù)據(jù)

獲取 SQLiteDatabase 的參照是一個(gè)昂貴的操作,因此永遠(yuǎn)不要在主線程執(zhí)行它。擴(kuò)展來說,數(shù)據(jù)庫查詢也不要在主線程執(zhí)行。Android 提供 Loaders 來幫助實(shí)現(xiàn)這一點(diǎn)。它們?cè)试S activity 或 fragment 異步加載數(shù)據(jù)。Loaders 可以解決配置改變時(shí)數(shù)據(jù)持久的問題,也能檢測(cè)數(shù)據(jù)并在內(nèi)容改變的時(shí)候發(fā)送新的結(jié)果。Android 提供 CursorLoader 來從數(shù)據(jù)庫中加載數(shù)據(jù)。

與其他應(yīng)用程序共享數(shù)據(jù)

雖然數(shù)據(jù)庫對(duì)于創(chuàng)建它們的應(yīng)用來說是私有的,但是 Android 也提供與其他應(yīng)用程序共享數(shù)據(jù)的方法。Content Providers 提供一個(gè)結(jié)構(gòu)化的接口,能使其他應(yīng)用讀取甚至可能修改你的數(shù)據(jù)。和 SQLiteDatabase 類似, Content Providers 開放出 query(),insert(),update()delete() 這些方法來操作數(shù)據(jù)。數(shù)據(jù)以 Cursor 的形式返回,而且對(duì) Content Provider 的訪問默認(rèn)是同步的,這樣可以使訪問是線程安全的。

總結(jié)

Android 數(shù)據(jù)庫與 iOS 上類似的功能相比,實(shí)現(xiàn)更加復(fù)雜。但是切記,不要只是為了減少模板代碼而去使用第三方庫。對(duì)于 Android 數(shù)據(jù)庫框架的徹底理解會(huì)讓你知道該不該選擇使用第三方庫,以及使用什么樣的第三方庫。Android Developer 網(wǎng)站 提供了兩個(gè)操作 SQLite 數(shù)據(jù)庫的樣例工程。你可以詳細(xì)看看 NotePadSearchableDictionary 這兩個(gè)項(xiàng)目可以獲得更多信息。