1.什么是SQLite數(shù)據(jù)庫
-SQLite是一個(gè)輕量級(jí)的關(guān)系型數(shù)據(jù)庫,運(yùn)算速度快,占用資源少,很適合在移動(dòng)設(shè)備上使用, 不僅支持標(biāo)準(zhǔn)SQL語法,還遵循ACID(數(shù)據(jù)庫事務(wù))原則,無需賬號(hào),使用起來非常方便!
1.1特色:輕量級(jí)、獨(dú)立、隔離、跨平臺(tái)、多語言接口、安全性
小結(jié):Qlite通過文件來保存數(shù)據(jù)庫,一個(gè)文件就是一個(gè)數(shù)據(jù)庫,數(shù)據(jù)庫中又包含多個(gè)表格,表格里又有多條記錄,每個(gè)記錄由多個(gè)字段構(gòu)成,每個(gè)字段有對(duì)應(yīng)的值,每個(gè)值我們可以指定類型,也可以不指定 類型(主鍵除外)
1.2如何和數(shù)據(jù)庫打交道
1.2.1 如何設(shè)計(jì)數(shù)據(jù)庫與表
使用SQL Helper創(chuàng)建DB
public class FeedReaderDbHelper extends SQLiteOpenHelper
{
// If you change the database schema, you must increment the database version.
public static final int DATABASE_VERSION =1;
public static final String DATABASE_NAME ="FeedReader.db";
public FeedReaderDbHelper(Context context){
super(context, DATABASE_NAME,null, DATABASE_VERSION);? ? }
public void onCreate(SQLiteDatabase db){?
?? ? ? db.execSQL(SQL_CREATE_ENTRIES);
? ? }
public void onUpgrade(SQLiteDatabase db,intoldVersion,intnewVersion){
// This database is only a cache for online data, so its upgrade policy is
// to simply to discard the data and start over
db.execSQL(SQL_DELETE_ENTRIES);? ?
?? ? onCreate(db);?
?? }
public void onDowngrade(SQLiteDatabase db,intoldVersion,intnewVersion)
{? ? ? ?
?onUpgrade(db, oldVersion, newVersion);?
?? }
}
1.2.2 對(duì)數(shù)據(jù)庫進(jìn)行增刪查改
添加信息到DB
通過傳遞一個(gè) ContentValues 對(duì)象到insert()方法:
// 獲取數(shù)據(jù)存儲(chǔ)庫以寫模式
SQLiteDatabase db = mDbHelper.getWritableDatabase();
// 創(chuàng)建一個(gè)新的映射的值,key-value形式
ContentValues values = new ContentValues();
values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_ENTRY_ID, id);
values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_TITLE, title);
values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_CONTENT, content);
// 插入新行,返回主鍵值的新行,插入若失敗返回的值為-1
long newRowId;
newRowId = db.insert(FeedReaderContract.FeedEntry.TABLE_NAME,? ? ? ? FeedReaderContract.FeedEntry.COLUMN_NAME_NULLABLE,values);
解釋:insert()方法的第一個(gè)參數(shù)是table名,第二個(gè)參數(shù)會(huì)使得系統(tǒng)自動(dòng)對(duì)那些ContentValues沒有提供數(shù)據(jù)的列填充數(shù)據(jù)為null,如果第二個(gè)參數(shù)傳遞的是null,那么系統(tǒng)則不會(huì)對(duì)那些沒有提供數(shù)據(jù)的列進(jìn)行填充。
從DB中讀取信息
為了從DB中讀取數(shù)據(jù),需要使用query()方法,傳遞需要查詢的條件。查詢后會(huì)返回一個(gè) Cursor 對(duì)象。
SQLiteDatabase db = mDbHelper.getReadableDatabase();
// 定義一個(gè)從數(shù)據(jù)庫中指定的列projection?
// 將在query方法里使用
String[] projection = {? ? FeedReaderContract.FeedEntry._ID,? ? FeedReaderContract.FeedEntry.COLUMN_NAME_TITLE,? ? FeedReaderContract.FeedEntry.COLUMN_NAME_UPDATED,? ? ...? ? };
//如何你想要的結(jié)果排序結(jié)果光標(biāo)
String sortOrder = FeedReaderContract.FeedEntry.COLUMN_NAME_UPDATED + " DESC";
Cursor c = db.query(FeedReaderContract.FeedEntry.TABLE_NAME,? // table_name
projection,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // The columns to return? ?
selection,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // WHERE子句的列--制定哪列即哪個(gè)key
selectionArgs,? ? ? ? ? ? ? ? ? ? ? ? ? ? // 值的字符串?dāng)?shù)組
?null,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // don't group the rows? ??
null,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // don't filter by row groups??
?sortOrder? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // The sort order? ? );
要查詢?cè)赾ursor中的行,使用cursor的其中一個(gè)move方法,但必須在讀取值之前調(diào)用。一般來說應(yīng)該先調(diào)用moveToFirst()函數(shù),將讀取位置置于結(jié)果集最開始的位置。對(duì)每一行,我們可以使用cursor的其中一個(gè)get方法如getString()或getLong()獲取列的值。對(duì)于每一個(gè)get方法必須傳遞想要獲取的列的索引位置(index position),索引位置可以通過調(diào)用getColumnIndex()或getColumnIndexOrThrow()獲得。
下面演示如何從course對(duì)象中讀取數(shù)據(jù)信息:
cursor.moveToFirst();longitemId = cursor.getLong(? ? cursor.getColumnIndexOrThrow(FeedReaderContract.FeedEntry._ID));
刪除DB中的信息
和查詢信息一樣,刪除數(shù)據(jù)同樣需要提供一些刪除標(biāo)準(zhǔn)。DB的API提供了一個(gè)防止SQL注入的機(jī)制來創(chuàng)建查詢與刪除標(biāo)準(zhǔn)。
SQL Injection:(隨著B/S模式應(yīng)用開發(fā)的發(fā)展,使用這種模式編寫應(yīng)用程序的程序員也越來越多。但由于程序員的水平及經(jīng)驗(yàn)也參差不齊,相當(dāng)大一部分程序員在編寫代碼時(shí)沒有對(duì)用戶輸入數(shù)據(jù)的合法性進(jìn)行判斷,使應(yīng)用程序存在安全隱患。用戶可以提交一段數(shù)據(jù)庫查詢代碼,根據(jù)程序返回的結(jié)果,獲得某些他想得知的數(shù)據(jù),這就是所謂的SQL Injection,即SQL注入)
該機(jī)制把查詢語句劃分為選項(xiàng)條件與選項(xiàng)參數(shù)兩部分。條件定義了查詢的列的特征,參數(shù)用于測(cè)試是否符合前面的條款。由于處理的結(jié)果不同于通常的SQL語句,這樣可以避免SQL注入問題。
// Define 'where' part of query.
String selection = FeedReaderContract.FeedEntry.COLUMN_NAME_ENTRY_ID +" LIKE ?";
// Specify arguments in placeholder order.
String[] selelectionArgs = { String.valueOf(rowId) };
// Issue SQL statement.
db.delete(table_name, mySelection, selectionArgs);
更新數(shù)據(jù)
當(dāng)需要修改DB中的某些數(shù)據(jù)時(shí),使用 update() 方法。
update結(jié)合了插入與刪除的語法。
SQLiteDatabase db = mDbHelper.getReadableDatabase();
// New value for one column
ContentValues values=newContentValues();values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_TITLE, title);
// Which row to update, based on the ID
String selection = FeedReaderContract.FeedEntry.COLUMN_NAME_ENTRY_ID +" LIKE ?";
String[] selectionArgs = { String.valueOf(rowId) };
int count = db.update( FeedReaderDbHelper.FeedEntry.TABLE_NAME,values,selection,selectionArgs);
1.3優(yōu)化
1.3.1如何設(shè)計(jì)數(shù)據(jù)庫與表
上萬條數(shù)據(jù)如何建表,比如300個(gè)城市,每個(gè)城市600條信息
1.3.2對(duì)數(shù)據(jù)庫進(jìn)行增刪查改
原始SQL語句執(zhí)行效率更高 rawQuery execSQL
只檢索有用的列、有用的行,越少越好
是否排序
是否創(chuàng)建索引
1.3.3事務(wù)
1.3.4對(duì)象關(guān)系映射ORM
2.Content Provider
2.1什么是Content Provider

2.2Google是怎么定義Content Provider的?
內(nèi)容提供者將一些特定的應(yīng)用程序數(shù)據(jù)供給其他應(yīng)用程序使用
數(shù)據(jù)可以存儲(chǔ)于文件系統(tǒng)、SQLite數(shù)據(jù)庫或其他方式。
內(nèi)容提供者繼承于ContentProvider基類,為其他應(yīng)用程序取用和存儲(chǔ)它管理的數(shù)據(jù)實(shí)現(xiàn)了一套標(biāo)準(zhǔn)方法。
應(yīng)用程序不直接調(diào)用這些方法,而是使用ContentResolver對(duì)象,調(diào)用它的方法作為替代。
ContentResolver可以與任意內(nèi)容提供者進(jìn)行會(huì)話,與其合作來對(duì)所有相關(guān)交互通訊進(jìn)行管理
2.3ContentResolver類(通過它對(duì)Content Provider里的數(shù)據(jù)進(jìn)行CRUD)
ContentResolver
onCreate();
insert()
delete()
query()
update()
getType()
2.4ContentProvider的實(shí)現(xiàn)過程
