最近為了鞏固android基礎(chǔ)卖宠,復(fù)習(xí)了sqlite數(shù)據(jù)庫(kù)這篇孕荠。好記性不如爛筆頭宦搬,操起鍵盤就是干....
sqlite簡(jiǎn)介
SQLite 是一款輕量級(jí)的關(guān)系型數(shù)據(jù)庫(kù)沈自,它的運(yùn)算速度非常快笤喳, 占用資源很少考赛,通常只需要幾百 K 的內(nèi)存就足夠了,因而特別適合在移動(dòng)設(shè)備上使用莉测。SQLite 不僅支持標(biāo)準(zhǔn)的 SQL 語(yǔ)法颜骤,還遵循了數(shù)據(jù)庫(kù)的 ACID 事務(wù),所以只要你以前使用過(guò)其他的 關(guān)系型數(shù)據(jù)庫(kù)捣卤,就可以很快地上手 SQLite忍抽。而 SQLite 又比一般的數(shù)據(jù)庫(kù)要簡(jiǎn)單得多,它甚 至不用設(shè)置用戶名和密碼就可以使用董朝。Android 正是把這個(gè)功能極為強(qiáng)大的數(shù)據(jù)庫(kù)嵌入到了 系統(tǒng)當(dāng)中鸠项,使得本地持久化的功能有了一次質(zhì)的飛躍。
優(yōu)點(diǎn):
1)零配置子姜,無(wú)需安裝和配置
2)儲(chǔ)存在單一磁盤文件中的一個(gè)完整數(shù)據(jù)庫(kù)
3)數(shù)據(jù)庫(kù)文件可以在不同的字節(jié)順序的機(jī)器間自由共享
4)支持?jǐn)?shù)據(jù)庫(kù)大小至2TB
5)足夠小祟绊,全部源代碼大致3萬(wàn)行C代碼,250k
6)比目前流行的大多數(shù)數(shù)據(jù)庫(kù)帶數(shù)據(jù)的操作要快
7)開源
常用的sql基本語(yǔ)句
創(chuàng)建表:
create table 表名 (字段名 數(shù)據(jù)類型,字段名 數(shù)據(jù)類型牧抽,字段名 數(shù)據(jù)類型)
插入數(shù)據(jù):
insert into 表名 values(數(shù)據(jù)值嘉熊,數(shù)據(jù)值,數(shù)據(jù)值)
insert into 表名 (字段1扬舒,字段2阐肤,字段3) values(數(shù)據(jù)值,數(shù)據(jù)值讲坎,數(shù)據(jù)值)
更新數(shù)據(jù):
update 表名 set 字段1 = 數(shù)據(jù)值 where 其他字段 = 數(shù)據(jù)值
刪除數(shù)據(jù):
delete from 表名 where 字段值 = 數(shù)據(jù)值
刪除表:
drop table if exists 表名
增加字段:
alter table 表名 add column 字段 數(shù)據(jù)類型
查詢數(shù)據(jù):
select * from表名 where 查詢的條件表達(dá)式 group by 分組的字段 order by 排序的字段
//select 后面為* 則返回所有的字段孕惜,返回部分字段,只需把*換成需要的字段晨炕,多個(gè)字段有逗號(hào)隔開
創(chuàng)建數(shù)據(jù)庫(kù)
android的為我們提供了SQLiteOpenHelper 衫画,繼承這個(gè)抽象類類,需要復(fù)寫構(gòu)造方法(一般選構(gòu)造參數(shù)少的那個(gè))瓮栗,onCreate()和onUpgrade()
onCreate
這個(gè)方法是用來(lái)創(chuàng)建數(shù)據(jù)庫(kù)用的凯楔;
onUpgrade
這個(gè)方法是用來(lái)升級(jí)數(shù)據(jù)庫(kù)用的灸叼;
例子如下:
創(chuàng)建一個(gè)學(xué)生表
public class MySQLiteHelp extends SQLiteOpenHelper {
public static final int VERSION = 1;
private static final String DB_NAME = "my_db.db";
private static final String CREATE_BOOK = "create table Students (" +
"id integer primary key autoincrement," +
"name text," +
"class text," +
"year integer," +
"grade real)";
private Context mContext;
public MySQLiteHelp(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
this.mContext = context;
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL(CREATE_BOOK);
Toast.makeText(mContext,"創(chuàng)建成功酬核!",Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
然后實(shí)例化MySQLiteHelp這個(gè)類赦肃,并調(diào)用getWritableDatabase()方法丰榴。
//第一個(gè)參數(shù)上下文货邓,第二個(gè)參數(shù)數(shù)據(jù)庫(kù)名字,第三個(gè)參數(shù)允許我們?cè)诓樵償?shù)據(jù)的時(shí)候返回一個(gè)自定義的Cursor,一般傳null四濒,第四個(gè)參數(shù)傳入數(shù)據(jù)庫(kù)版本
mySQLiteHelp = new MySQLiteHelp(this,MySQLiteHelp.DB_NAME,null,1);
//創(chuàng)建或者打開一個(gè)數(shù)據(jù)庫(kù)换况,如果數(shù)據(jù)庫(kù)存在就打開,沒(méi)有就創(chuàng)建
mySQLiteHelp.getWritableDatabase();
打開File Explorer查看數(shù)據(jù)庫(kù)是否創(chuàng)建成功盗蟆;目錄在data/data/[包名]/databases
這里需要講下 SQLite的數(shù)據(jù)類型和getWritableDatabase()與getReadableDatabase()的區(qū)別
SQLite的數(shù)據(jù)類型只有5種:
1戈二,null(數(shù)據(jù)值為空)
2,integer(整型)
3喳资,real(浮點(diǎn)型數(shù)據(jù))
4觉吭,text(字符串,數(shù)據(jù)庫(kù)編碼【utf-8,utf-16be或者utf-16le】存放)
5仆邓,blob(只是一個(gè)數(shù)據(jù)塊鲜滩,完全按照輸入存放)
getWritableDatabase()與getReadableDatabase()的區(qū)別
getWritableDatabase取得的實(shí)例不是僅僅具有寫的功能,而是同時(shí)具有讀和寫的功能同樣的节值;
getReadableDatabase取得的實(shí)例也是具對(duì)數(shù)據(jù)庫(kù)進(jìn)行讀和寫的功能徙硅。
兩者的區(qū)別在于getWritableDatabase取得的實(shí)例是以讀寫的方式打開數(shù)據(jù)庫(kù),如果打開的數(shù)據(jù)庫(kù)磁盤滿了搞疗,此時(shí)只能讀不能寫嗓蘑,此時(shí)調(diào)用了getWritableDatabase的實(shí)例,那么將會(huì)發(fā)生錯(cuò)誤(異常)
getReadableDatabase取得的實(shí)例是先調(diào)用getWritableDatabase以讀寫的方式打開數(shù)據(jù)庫(kù),如果數(shù)據(jù)庫(kù)的磁盤滿了桩皿,此時(shí)返回打開失敗豌汇,繼而用getReadableDatabase的實(shí)例以只讀的方式去打開數(shù)據(jù)庫(kù)
操作數(shù)據(jù)庫(kù)
操作數(shù)據(jù)庫(kù)的類不是SQLiteOpenHelper ,而是SQLiteDatabase业簿,這個(gè)對(duì)象是通過(guò)調(diào)用getWritableDatabase方法返回的對(duì)象瘤礁;
下面來(lái)演示下操作數(shù)據(jù)庫(kù)的增刪改查
添加數(shù)據(jù)
ps:db 是一個(gè)SQLiteDatabase對(duì)象;
調(diào)用db.execSQL(String sql)方法;
String sql = "insert into Students (name,class,year,grade) values ('小明','一年級(jí)',8,98)";
db.execSQL(sql);
這里我用sqlite expert professional 這個(gè)工具打開數(shù)據(jù)庫(kù)梅尤,查看數(shù)據(jù)是否插入成功
其實(shí)SQLiteDatabase還為我們提供了更加簡(jiǎn)單的一種方法插入數(shù)據(jù)柜思;
調(diào)用 db.insert();
ContentValues values = new ContentValues();
values.put("name","小紅");
values.put("class","一年級(jí)");
values.put("year",7);
values.put("grade",100);
db.insert("Students",null,values);
更新數(shù)據(jù)
我們來(lái)將小明的分?jǐn)?shù)偷偷的改成100
使用sql語(yǔ)法的如下:
String sql = "update Students set grade = 100 where name = '小明' ";
db.execSQL(sql);
android內(nèi)置語(yǔ)法:
我們來(lái)把小明的分?jǐn)?shù)偷偷的改成60
ContentValues values1 = new ContentValues();
values1.put("grade",60);
db.update("Students",values1,"name = ?",new String[]{"小明"});
db.update的方法需要傳入四個(gè)參數(shù),第一個(gè)是表名巷燥,第二個(gè)是需要修改的值赡盘,第三個(gè)是條件,第四個(gè)是符合條件的值
刪除數(shù)據(jù)
我們來(lái)將小明的數(shù)據(jù)刪除點(diǎn)缰揪;
sql語(yǔ)法:
String sql = "delete from Students where name = '小明' ";
db.execSQL(sql);
將小明的數(shù)據(jù)刪除了陨享,這樣他爸媽就不知道了。
android內(nèi)置語(yǔ)法:
//這里三個(gè)參數(shù)钝腺,第一個(gè)是表名抛姑,第二個(gè)是條件,第三個(gè)是符合條件的值
db.delete("Students","name = ?",new String[]{"小明"});
查詢數(shù)據(jù)
sql語(yǔ)句:
查詢數(shù)據(jù)這里不能用:db.execSQL(sql)艳狐,
這里需要換一個(gè)方法:db.rawQuery()
String sql1 = "select * from Students where name = '小紅' ";
//第一個(gè)參數(shù)為select語(yǔ)句定硝;第二個(gè)參數(shù)為select語(yǔ)句中占位符參數(shù)的值,如果select語(yǔ)句沒(méi)有使用占位符毫目,該參數(shù)可以設(shè)置為null
Cursor cursor = db.rawQuery(sql1, null);
if (cursor.moveToFirst()){
do {
String name = cursor.getString(cursor.getColumnIndex("name"));
String class_ = cursor.getString(cursor.getColumnIndex("class"));
int year = cursor.getInt(cursor.getColumnIndex("year"));
double grade = cursor.getDouble(cursor.getColumnIndex("grade"));
Log.d(TAG, "name: "+name);
Log.d(TAG, "name: "+class_);
Log.d(TAG, "name: "+year);
Log.d(TAG, "name: "+grade);
}while (cursor.moveToNext());
}
cursor.close();
執(zhí)行完查詢語(yǔ)句返回一個(gè)Cursor數(shù)據(jù)類型蔬啡。他是一個(gè)提供了隨機(jī)讀寫訪問(wèn)數(shù)據(jù)庫(kù)查詢結(jié)果集的接口。Cursor并不是線程安全镀虐,因此在多線程中訪問(wèn)的時(shí)候需要手動(dòng)進(jìn)行同步箱蟆,避免線程出現(xiàn)問(wèn)題。
常用的Cursor函數(shù)有:
close() 關(guān)閉游標(biāo)刮便,釋放資源
copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) 在緩沖區(qū)中檢索請(qǐng)求的列的文本空猜,將將其存儲(chǔ)
getColumnCount() 返回所有列的總數(shù)
getColumnIndex(String columnName) 返回指定列的名稱,如果不存在返回-1
getColumnIndexOrThrow(String columnName) 從零開始返回指定列名稱恨旱,如果不存在將拋出IllegalArgumentException 異常抄肖。
getColumnName(int columnIndex) 從給定的索引返回列名
getColumnNames() 返回一個(gè)字符串?dāng)?shù)組的列名
getCount() 返回Cursor 中的行數(shù)
moveToFirst() 移動(dòng)光標(biāo)到第一行
moveToLast() 移動(dòng)光標(biāo)到最后一行
moveToNext() 移動(dòng)光標(biāo)到下一行
moveToPosition(int position) 移動(dòng)光標(biāo)到一個(gè)絕對(duì)的位置
moveToPrevious() 移動(dòng)光標(biāo)到上一行
android內(nèi)置語(yǔ)法:
/**
* 第一個(gè)參數(shù):表名
* 第二個(gè)參數(shù):要查詢的字段名
* 第三個(gè)參數(shù):要查詢的條件字段
* 第四個(gè)參數(shù):要查詢的條件字段對(duì)應(yīng)的值
* 第五個(gè)參數(shù):分組的字段
* 第六個(gè)參數(shù):篩選的字段
* 第七個(gè)參數(shù):排序的字段
* 返回值:游標(biāo)
Cursor cursor = db.query("Students",null,null,null,null,null,null);
*/
獲取了游標(biāo)Cursor 之后的操作與上面一樣。
android的基本操作就這樣了窖杀,下次有時(shí)候?qū)懸幌聰?shù)據(jù)庫(kù)的升級(jí)和優(yōu)化部分漓摩。等我把github弄好我再吧代碼上傳