Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發之SQLite數據庫詳解

Android開發之SQLite數據庫詳解

編輯:關於Android編程

Android開發之SQLite數據庫詳解


請尊重他人的勞動成果,轉載請注明出處:Android開發之SQLite數據庫詳解

http://blog.csdn.net/fengyuzhengfan/article/details/40194393

Android系統集成了一個輕量級的數據庫:SQLite, SQLite並不想成為像Oracle、MySQL那樣的專業數據庫。SQLite只是一個嵌入式的數據庫引擎,專門適用於資源有限的設備上(如手機、PDA等)適量數據存取。

雖然SQLite支持絕大部分SQL92語法,也允許開發者使用SQL語句操作數據庫中的數據,但SQLite並不像Orade、MySQL數據庫那樣需要安裝、啟動服務器進程,SQLite數據庫只是一個文件。

從本質上來看,SQLite的操作方式只是一種更為便捷的文件操作。後面我們會看到,當應用程序創建或打開一個SQLite數據庫時,其實只是打開一個文件准備讀寫,因此有人說SQLite有點像Microsoft的Access (實際上SQLite功能要強大得多)。

1.SQLiteDatabase 簡介

Android提供了SQLiteDatabase 代表一個數據庫(底層就是一個數據庫文件>,一旦應用程序獲得了代表指定數據庫的SQLiteDatabase 對象,接下來就可通過SQLiteDatabase 對象來管理、操作數據庫了。

2.打開獲取創建SQLiteDatabase的方法:

1)staticSQLiteDatabase openDatabase(Stringpath,SQLiteDatabase .CursorFactory factory, intflags):打開path文件所代表的SQLite數據庫。

2)staticSQLiteDatabase openOrCreateDatabase(File file,SQLiteDatabase .CursorFactory factory):打開或創建(如果不存在)file文件所代表的SQLite數據庫。

3)staticSQLiteDatabase openOrCreateDatabase(String path,SQLiteDatabase .CursorFactory factory):打開或創建(如果不存在)path文件所代表的SQLite數據庫。

3.操作SQLiteDatabase 的方法主要有:

1)execSQL(Stringsql, Object[] bindArgs):執行帶占位符的 SQL語句。

2)execSQL(String sql):執行 SQL語句。

3)insert(Stringtable, String nullColumnHack,ContentValues values):向執行表中插入數據。

4)update(Stringtable, ContentValues values, String whereClause, String[] whereArgs):吏新指定表中的特定數據。

5)delete(Stringtable, String whereClause, String[] whareArgs):刪除指定表中的特定數據。

6)Cursorquery(String table, String[]columns, String selection, String[] selection Args,String groupBy, String having,String orderBy):對執行數據表執行査詢。

7)Cursorquery(String table, String[] columns, String selection, String[] selectionArgs,String groupBy, String having, String orderBy, String limit}:對執行數據表執行査詢。Limit參數控制最多査詢幾條記錄(用於控制分頁的參數)。

8)Cursorquery(boolean distinct, String table, String[] columns, String selection,String[] selectionArgs, String groupBy, String having, String orderBy, String limit): 對指定表執行査詢語句。其中第一個參數控制是否去除重復值。

9)rawQuery(Stringsql, String[] selectionArgs):執行帶占位符的 SQL查詢。

10)beginTransaction():開始事務。

11)endTransaction():結束事務。

從上面的方法不難看出,其實SQLiteDatabase的作用有點類似於JDBC的Connection接口,但SQLiteDatabase提供的方法更多:比如insert、update、delete、query等方法,其實這些方法完全可通過執行SQL語句來完成,但Android考慮到部分開發者對SQL語法不熟悉,所以提供這些方法幫助開發者以更簡單的方式來操作數據表的數據。

4.操作Cursor

上面査詢方法都是返回一個Cursor對象,Android中的Cursor類似干JDBC的ResultSet, Cursor同樣提供了如下方法來移動査詢結果的記錄指針。

1)move(int offset):將記錄指針向上或向下移動指定的行數。offset為正數就向下移動;為負數就是向上移動。

2)booleanmoveToFirst():將記錄指針移動到第一行,如果移動成功則返回true。

3)booleanmoveToLast():將記錄指針移動到最後一行,如果移動成功則返回true。

4)booleanmoveToNext():將記錄指針移動到下一行,如果移動成功則返回true。

5)booleanmoveToPosition(int position):將記錄指針移動到指定的行,如果移動成功則返回true。

6)booleanmoveToPrevious():將記錄指針移動到上一行,如果移動成功則返回true。

—旦將記錄指針移動到指定行之後,接下來就可以調用Cursor的getXxx()方法獲取該行的指定列的數據。

其實如果大家具有JDBC編程的經驗,完全可以把SQLiteDatabase當成JDBC :中Connection和Statement的混合體因為SQLiteDatabase 既代表了與數據庫的連接,也可直接用於執行SQL操作;而Android中Cursor則可當成ResultSet,而且Cursor提供了更多便捷的方法來操作結果集。

5.創建數據庫和表

前面已經講到,使用SQLiteDatabase的靜態方法即可打開或創建數據庫,例如如下代碼:

SQLiteDatabase.openOrCreateDatabase(“/mnt/db/temp.db3”,null);

上面的代碼就用於打開或創建一個SQLite數據庫,如果/mnt/db/目錄下的temp.db3文件 (該文件就是一個數據庫)存在,那麼程序就是打開該數據庫:如果該文件不存在,則上面的代碼將會在該目錄下創建temp.db3文件(即對應於數據庫)。

上面的代碼中沒有指定SQLiteDatabase.CursorFactory參數,該參數是一個用於返回 Cursor的工廠,如果指定該參數為null,則意味著使用默認的工廠。

上面的代碼即可返回一個SQLiteDatabase對象,該對象的execSQL可執行任意的SQL語句。

通過如下代碼在程序中創建數據表:

//定義建表語句

create tabletb_news(

id integer primarykey autoincrement,

title varchar(100)not null,

content varchar(2000));

在程序中執行上面的代碼即可在數據庫中創建一個數據表。

6.使用SQL語句操作SQLite數據庫

正如前面提到的,SQLiteDatabase的execSQL方法可執行任意SQL語句,包括帶占位符的SQL語句。但由於該方法沒有返回值,一般用於執行DDL語句或DML語句;如果需要執行査詢語句,則可調用SQLiteDatabase 的 rawQuery(String sql,String[] selectionArgs)方法。例如如下代碼可用於執行DML語句,

//執行插入語句

String sql ="insert into tb_news(title,content,publishDate)values(?,?,?)";

db.execSQL(sql,new Object[]{news.getTitle(),news.getContent(),news.getPublishDate()});

提示:SQLite允許把各種類型的數據保存到任何類型字段中,開發者可以不用關心聲明該字段所使用的數據類型。例如程序可以把字符串類型的值存INTEGER類型的字段中,也可以把數值類型的值存入布爾類型的字段中……但有一種情況例外:定義為INTEGERPRIMARY KEY的字段只能存儲64位整數,當向這種字段保存除整數以外的其他類型的數據時,SQLite會產生錯誤。

由於SQLite允許存入數據時忽略底層數據列實際的數據類型,因此在編寫建表語句時可以柯略數據列後面的類型聲明,例如如下SQL語句對於SQLite也是正確的。

create table my_test

(_id integer primary key autoincrement,

name,pwd)

7.使用Android數據庫操作的操作數據庫

Android的SQLiteDatabase 提供了 insert、upate、delete或 query 語句來操作數據庫。

1.使用insert方法插入記錄

SQLiteDatabase 的 insert方法的簽名為 longinsert (String table, String nullColumnHack, ContentValuesvalues),這個插入方法的參數說明如下。

table:代表想插入數據的表名。

nullColumnHack:代表強行插入null值的數據列的列名。

values:代表一行記錄的數據。

insert方法插入的一行記錄使用ComentValues存放,ContentValues類似於Map,它提供了 put其中key為數據列的列名,該方法用於存入數據、getAsXxx(String key)方法用於取出數據。

例如如下語句:

ContentValues values = new ContentValues();

values.put ("name” , “孫悟空”);

values.put(“age”, 500);

//返回新添記錄的行號,該行號是一個內部值,與主鍵1^1無關,發生铕誤返回一1

long rowid = db.insert("person_in”,null,values);

不管第三個參數是否包含數據,執行insert()方法總會添加一條記錄,如果第三個參數為空,會添加一條除主鍵之外其他宇段值都為null的記錄。

insert()方法的底層實際上依然是通過構造insert SQL語句來進行插入的,因此它生成的 SQL語句總是形如下面的語句:

//ContentValue 裡 key-value對的數值決定了下面的key-value對.

insert into <表名>(key1,key 2...) values(valuel , value2 ...)

此時如果第三個參數為null或其中key-value對的數量為0,由於insert方法還會按此方式生成一條insert語句,此時的insert語句為:

insert into <表名>()values()

上面的SQL語句顯然有問題,為了滿足SQL語法的需要,insert語句必須給定一個列名,如:insert intoperson(name)values(null),這個name列名就由第二個參數來指定。由此可見,當ComentValues為null或它包含的key-value對的數量為()時,第二個參數就會起作用了。

一般來說,第二個參數指定的列名不應該是主鍵列的列名,也不應該是非空列的列名,否則強行往這些數據列插入nul會引發異常。

2.使用update方法更新記錄

SQLiteDatabase 的 update方法的簽名為update(String table, ContentValues values, String whereClause, String[]whereArs),這個更新方法的參數說明如下:

table:代表想更新數據的表名。

values:代表想更新的數據。

whereClause:滿足該whereClause子句的記錄將會被更新。

whereArgs:用於為whereClause子句傳入參數。

該方法返回受此update語句影響的記錄的條數。

實例:

ContentValues values=new ContentValues();

values.put("title", news.getTitle());

values.put("content", news.getContent());

db.update("tb_news", values, "id=?",new String[]{String.valueOf(news.getId())});

3.使用delete方法刪除記錄

SQLiteDatabase 的 delete方法的簽名為delete(String table , String whereClause, String[]whereArgs),這個刪除的參數說明如下。

table:代表想刪除數據的表名。

whereClause:滿足該whereClause子句的記錄將會被刪除。

whereArgs:用於為whereClause子句傳入參數。

該方法返回受此delete語句影響的記錄的條數。

實例:

db=helper.getWritableDatabase();

db.execSQL("delete from tb_news where id=?",new String[]{String.valueOf(newsId)});

使用query方法查詢記錄

SQLiteDatabase 的 query方法的簽名為 Cursorquery(boolean distinct, String table,String[]

columns, String selection, Stringl]selecrionArgs, String groupBy, String having. String orderBy, String limit),這個query方法的參數說明如下,

distinct:指定是否去除重復記錄,

table:執行査詢數據的表名。

columns:要査詢出來的列名。相當於select語句select關鍵字後面的部分s

selection:査詢條件子句,相當於select語句where關鍵字後面的部分,在條件子

句中允許使用占位符。

selectionArgs:用於為selection子句中占位符傳入參數值,值在數組中的位置與占位符在語句中的位置必須一致,否則就會有異常。

groupBy:用於控制分組?相當於select語句group by關鍵字後面的部分

having:用於對分組進行過濾。相當於select語句having關鍵字後面的部分

orderBy:用於對記錄進行排序。相當於select語句order by關鍵字後面的部分,如:personid desc, age asc;

limit:用於進行分頁,相當於select語句limit關鍵字後面的部分。

實例:

/**

*獲取分頁數據

*@param currentPage當前頁碼

*@param pageSize每頁顯示的數據量

*@return

*/

public List getNewsByPage(int currentPage,int pageSize) {

db=helper.getReadableDatabase();

Listlist=newArrayList();

String start=String.valueOf((currentPage-1)*pageSize);

Cursor cursor=db.query(true,"tb_news",null,null,null,null,null,"id asc",start+","+String.valueOf(pageSize));

// String sql="select* from tb_news order by id asc limit ?,?";

// Cursorcursor=db.rawQuery(sql, new String[]{start,String.valueOf(pageSize)});

while(cursor.moveToNext()){

intid=cursor.getInt(cursor.getColumnIndex("id"));

Stringtitle=cursor.getString(cursor.getColumnIndex("title"));

Stringcontent=cursor.getString(cursor.getColumnIndex("content"));

StringdateString=cursor.getString(cursor.getColumnIndex("publishDate"));

Date publishDate=null;

try {

publishDate= Utils.convertStr2Date(dateString);

} catch (ParseException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

list.add(new News(id, title,content, publishDate));

}

return list;

}

8.事務

SQLiteDatabase中包含如下兩個方法來控制事務。

beginTransaction():開始事務。

endTransaction():結束事務。

除此之外,SQLileDatabase還提供了如下方法來判斷當前上下文是否處於事務環境中》

inTransaction():如果當前上下文處於事務中,則返回true:否則返回false。

當程序執行endTiansaction()方法時將會結束事務——那到底是提交事務呢,還是回滾事務呢?這取決於SQLiteDatabase是否調用了 setTransactionSuccessful()方法來設置事務標志, 如果程序事務執行中調用該方法設置了事務成功則提交事務,否則程序將會回滾事務。示例代碼如下:

//事務處理

publicvoid tran(int id1,int id2,int des){

SQLiteDatabase db =helper.getWritableDatabase();

//按照這個語法格式寫事務

db.beginTransaction();//開始事務

try{

db.execSQL("update tb_news set account=account - ? whereid=?",new Integer[]{des,id1});

// inti = 1 / 0;

db.execSQL("update tb_news set account=account + ? whereid=?",new Integer[]{des,id2});

db.setTransactionSuccessful();//設置事務成功標志

}finally{

db.endTransaction();//結束事務:看事務是否成功,如果則提交,如果失敗則回滾

}

}

9.SQLiteOpenHelper

SQLiteOpenHelper是Android提供的一個管理數據庫的工具類,可用於管理數據庫的創建和版木更新。一般的用法是創建SQLiteOpenHelper的子類,並擴展它的onCreate (SQLiteDatabasedb)和 onUpgrade (SQLiteDatabasedb,intoldVersion,intnewVersion)方法。

SQLiteOpenHelper包含如下常用的方法。

synchronized SQLiteDatabase getReadableDatabase():以讀寫的方式打開數據庫對應的SQLiteDatabase對象。

synchronized SQLiteDatabase getWritableDatabase():以寫的方式打開數據庫對應的 SQLiteDatabase 對象。

abstract void onCreate (SQLiteDatabase db):當第一次創建數據庫時回調該方法。

abstract void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion):當數據庫版本更新時回調該方法。

synchronized void close():關閉所有打開的SQLiteDatabase 。

從上面的方法介紹中不難看出,SQLiteOpenHelper提供了getReadableDatabase()、 getWritableDatabase()兩個方法用於打開數據庫連接,並提供了close方法來關閉數據庫連接,而開發者需要做的就是重寫它的兩個抽象方法。

onCreate (SQLiteDatabase db):

用於初次使用軟件時生成數據庫表,當調用SQLiteOpenHelper的 getWritableDatabase()或者 getReadableDalabase()方法獲取用於操作數據庫的SQLiteDatabase實例時,如果數據庫不存在,Android系統會自動生成一個數據庫,接著調用onCreateO方法,onCreateO方法在初次生成數據庫時才會被調用,在onCreateO方法裡可以生成數據庫表結構及添加一些應用使用到的初始化數據。

onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion):

用於升級軟件時更新數據庫表結構,方法在數據庫的版本發生變化時會被調用,該方法調用時oldVersion代表數據庫之前的版本號,newVersion代表當前數據庫當前的版本號。那麼在哪裡指定數據庫的版本號呢?當程序創建SQLiteOpenHelper對象時,必須指定一個version參數,該參數就決定了所使用的數據庫的版本——也就是說,數據庫的版本是由程序員控制的。只要某次創建 SQLiteOpenHdper時指定的數據庫版本號高於之前指定的版本號,系統就會自動觸發 onUpgrade(SQLiteDatabase db, int oldVersion, int new Version)方法,程序就可以在onUpgrade()方法裡面根據原版號和目標版本號進行判斷,即可根據版本號進行必需的表結構更新。

提示:實際上,當應用程序升級表結構時,完全可能因為已有的數據導致升級失敗,在這種時候程序可能需要先對數據進行轉姑,清空數據表中的記錄,接著對數據!表進行更新,當教據表更新完成後再將教據保存回來。

一旦得到了SQLiteOpenHelper對象之後,程序無須使用SQLiteDatabase的靜態方法創建SQLiteDatabase 實例,而且可以使用getWritableDatabase()或 getReadableDatabase()方法來獲取一個用於操作數據庫的SQLiteDatabase實例。

其中getWritableDatabase()方法以讀寫方式打開數據庫,一旦數據庫的磁盤空間滿了,數據庫就只能讀而不能寫,倘若使用getWritableDatabase()打開數據庫就會出錯。 getReadableDatabase()方法先以讀寫方式打開數據庫,如果數據庫的磁盤空間滿了,就會打開失敗,當打開失敗後會繼續嘗試以只讀方式打開數據庫。

請尊重他人的勞動成果,轉載請注明出處:Android開發之SQLite數據庫詳解

http://blog.csdn.net/fengyuzhengfan/article/details/40194393


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved