1. 程式人生 > >Android中使用SQlite進行資料操作

Android中使用SQlite進行資料操作

本文參考了這篇文章:http://www.ibm.com/developerworks/cn/opensource/os-cn-sqlite/

簡介: SQLite 是一款非常流行的嵌入式資料庫,它支援 SQL 查詢,並且只用很少的記憶體。Android在執行時集成了 SQLite,所以每個 Android 應用程式都可以使用 SQLite 資料庫。對數熟悉 SQL 的開發人員來時,使用 SQLite 相當簡單。可以,由於 JDBC 不適合手機這種記憶體受限裝置,所以 Android 開發人員需要學習新的 API 來使用 SQLite。本文主要講解 SQLite 在 Android 環境中的基本使用。

SQLite 一個非常流行的嵌入式資料庫,它支援 SQL 語言,並且只利用很少的記憶體就有很好的效能。此外它還是開源的,任何人都可以使用它。許多開源專案((Mozilla, PHP, Python)都使用了 SQLite。

SQLite 由以下幾個元件組成:SQL 編譯器、核心、後端以及附件。SQLite 通過利用虛擬機器和虛擬資料庫引擎(VDBE),使除錯、修改和擴充套件 SQLite 的核心變得更加方便。

SQLite 基本上符合 SQL-92 標準,和其他的主要 SQL 資料庫沒什麼區別。它的優點就是高效,Android 執行時環境包含了完整的 SQLite。

SQLite 和其他資料庫最大的不同就是對資料型別的支援,建立一個表時,可以在 CREATE TABLE 語句中指定某列的資料型別,但是你可以把任何資料型別放入任何列中。當某個值插入資料庫時,SQLite 將檢查它的型別。如果該型別與關聯的列不匹配,則 SQLite 會嘗試將該值轉換成該列的型別。如果不能轉換,則該值將作為其本身具有的型別儲存。比如可以把一個字串(String)放入 INTEGER 列。SQLite稱這為“弱型別”(manifest typing.)。

此外,SQLite 不支援一些標準的 SQL 功能,特別是外來鍵約束(FOREIGN KEY constrains),巢狀 transcaction 和 RIGHT OUTER JOIN 和 FULL OUTER JOIN, 還有一些 ALTER TABLE 功能。

除了上述功能外,SQLite 是一個完整的 SQL 系統,擁有完整的觸發器,交易等等。

Android 集成了 SQLite 資料庫

Android 在執行時(run-time)集成了 SQLite,所以每個 Android 應用程式都可以使用 SQLite 資料庫。對於熟悉 SQL 的開發人員來時,在 Android 開發中使用 SQLite 相當簡單。但是,由於 JDBC 會消耗太多的系統資源,所以 JDBC 對於手機這種記憶體受限裝置來說並不合適。因此,Android 提供了一些新的 API 來使用 SQLite 資料庫,Android開發中,程式設計師需要學使用這些 API。

資料庫儲存在 data/< 專案資料夾 >/databases/ 下。

Android 開發中使用 SQLite 資料庫

Activites 可以通過 Content Provider 或者 Service 訪問一個數據庫。下面會詳細講解如果建立資料庫,新增資料和查詢資料庫。

建立資料庫

Android 不自動提供資料庫。在 Android 應用程式中使用 SQLite,必須自己建立資料庫,然後建立表、索引,填充資料。Android 提供了 SQLiteOpenHelper 幫助你建立一個數據庫,你只要繼承 SQLiteOpenHelper 類,就可以輕鬆的建立資料庫。SQLiteOpenHelper類根據開發應用程式的需要,封裝了建立和更新資料庫使用的邏輯。SQLiteOpenHelper 的子類,至少需要實現三個方法:

        1.  建構函式,呼叫父類 SQLiteOpenHelper 的建構函式。這個方法需要四個引數:上下文環境(例如,一個 Activity),資料庫名字,一個可選的遊標工廠(通常是 Null),一個代表你正在使用的資料庫模型版本的整數。

        2. onCreate()方法,它需要一個 SQLiteDatabase 物件作為引數,根據需要對這個物件填充表和初始化資料。

        3. onUpgrage()方法,它需要三個引數,一個SQLiteDatabase 物件,一箇舊的版本號和一個新的版本號,這樣你就可以清楚如何把一個數據庫從舊的模型轉變到新的模型。

下面示例程式碼展示瞭如何繼承 SQLiteOpenHelper 建立資料庫(AbstractDBOpenHelper繼承了SQLiteOpenHelper,在onCreate中建立了一張note表。):

/**
 * 摘要的DBOpenHelper
 * @author haozi
 *
 */
public class AbstractDBOpenHelper extends SQLiteOpenHelper {

	public AbstractDBOpenHelper(Context context, String name,
			CursorFactory factory, int version) {
		super(context, name, factory, version);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		
		// TODO 建立資料庫,對資料庫進行操作
                // 建立了一張note表
                String sql = "create table note( id integer primary key autoincrement, " +                                                 // 筆記的id
											"ntitle varchar(100), " +                          // 筆記的標題
											"ncontent varchar(600), " +                        // 筆記的內容      
											"course_id integer, " +                            // 課程id
											"ndate date, " +                                   // 日期
											"ntime time, " +                                   // 時間
											"deletable integer default 0" +                    // 可否刪除(1表示可以,0表示不可以)
		// 執行建表語句									" );";
		db.execSQL(sql);
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO 更改資料庫版本的操作

	}
	
	@Override
	public void onOpen(SQLiteDatabase db) {
		// TODO 每次成功開啟資料庫後首先被執行
		super.onOpen(db);
	}

}


接下來討論具體如何建立表、插入資料、刪除表等等。呼叫 getReadableDatabase() 或getWriteableDatabase() 方法,你可以得到 SQLiteDatabase 例項,具體呼叫那個方法,取決於你是否需要改變資料庫的內容:

// 得到可以修改資料表(增,刪,改)的sqliteDataBase例項
database = dbOpenHelper.getWritableDatabase();

// 得到只讀(查)的sqliteDataBase例項
database  = dbOpenHelper.getReadableDatabase();

上面的程式碼,已經建立了資料庫和表,現在需要給表新增資料。有兩種方法可以給表新增資料。

像上面建立表一樣,你可以使用 execSQL() 方法執行 INSERT, UPDATE, DELETE 等語句來更新表的資料。execSQL() 方法適用於所有不返回結果的 SQL 語句。例如:

	/**
	 * 儲存一條筆記
	 *
	 * @param note
	 * 
	 * @project:note
	 *
	 * @author haozi on 2012-2-27
	 */
	public void save(Note note){
		
		String sql = "insert into note(ntitle, ncontent, course_id, ndate, ntime, deletable) values(?,?,?,date('now'),time('now'),0);";
		
		db = dbHelper.getWritableDatabase();
		// 開始事務
		db.beginTransaction();	
		try{
			db.execSQL(sql, new Object[]{note.getTitle(), note.getContent(), note.getCourse_id()});
			db.setTransactionSuccessful();			
		}catch(Exception e){	
			System.out.println("插入筆記出現錯誤!");
		}
		// 結束事務
		db.endTransaction();
		db.close();
	}

另一種方法是使用 SQLiteDatabase 物件的 insert(), update(),delete() 方法。這些方法把 SQL 語句的一部分作為引數。示例如下:

	/**
	 * 更新筆記
	 *
	 * @param note
	 * 
	 * @project:note
	 *
	 * @author haozi on 2012-2-27
	 */
	public void update(Note note){
		
		db = dbHelper.getWritableDatabase();
		// 開始事務處理
		db.beginTransaction();
		
		ContentValues cv = new ContentValues();
		cv.put("ntitle", note.getTitle());
		cv.put("ncontent", note.getContent());
		cv.put("course_id", note.getId());
		
		db.update("note", cv, "id=?", new String[]{""+note.getId()});
		db.setTransactionSuccessful();
		// 結束事務處理
		db.endTransaction();
		db.close();	
	}

查詢資料庫

類似 INSERT, UPDATE, DELETE,有兩種方法使用 SELECT 從 SQLite 資料庫檢索資料。

1 .使用 rawQuery() 直接呼叫 SELECT 語句:

	/**
	 * 查詢全部的筆記記錄
	 *
	 * @return
	 * 
	 * @project:note
	 *
	 * @author haozi on 2012-2-27
	 */
	public ArrayList<Note> findAll(){
		
		ArrayList<Note> notes = new ArrayList<Note>();
		
		db = dbHelper.getReadableDatabase();
		String sql = "select * from note;";
		
		Cursor cursor = db.rawQuery(sql, null);
		
		while(cursor.moveToNext()){
			Note note = new Note();
			note.setId(cursor.getInt(cursor.getColumnIndex("id")));
			note.setTitle(cursor.getString(cursor.getColumnIndex("ntitle")));
			note.setContent(cursor.getString(cursor.getColumnIndex("ncontent")));
			note.setCourse_id(cursor.getInt(cursor.getColumnIndex("course_id")));
			note.setDate(cursor.getString(cursor.getColumnIndex("ndate")));
			note.setTime(cursor.getString(cursor.getColumnIndex("ntime")));
			int deletable = cursor.getInt(cursor.getColumnIndex("deletable"));
			if(deletable == 1){
				note.setDeletable(true);
			}else{
				note.setDeletable(false);
			}
			notes.add(note);
		}
		
		db.close();
		cursor.close();
		
		return notes;
	}


使用遊標

不管你如何執行查詢,都會返回一個 Cursor,這是 Android 的SQLite 資料庫遊標,使用遊標,你可以:

通過使用 getCount() 方法得到結果集中有多少記錄;

通過 moveToFirst(), moveToNext(), 和isAfterLast() 方法遍歷所有記錄;

通過 getColumnNames() 得到欄位名;

通過 getColumnIndex() 轉換成欄位號;

通過 getString(),getInt() 等方法得到給定欄位當前記錄的值;

通過 requery() 方法重新執行查詢得到遊標;

通過 close() 方法釋放遊標資源;

例如,上面查詢表中所有筆記的方法還可以這樣寫:

    /**
     * 查詢全部的筆記記錄
     *
     * @return
     * 
     * @project:note
     *
     * @author haozi on 2012-2-27
     */
    public ArrayList<Note> findAll(){
        
        ArrayList<Note> notes = new ArrayList<Note>();
        
        db = dbHelper.getReadableDatabase();
        String sql = "select * from note;";
        
        Cursor cursor = db.rawQuery(sql, null);
        
        cursor.moveToFirst();
        while(!cursor.isAfterLast()){
            Note note = new Note();
            note.setId(cursor.getInt(cursor.getColumnIndex("id")));
            note.setTitle(cursor.getString(cursor.getColumnIndex("ntitle")));
            note.setContent(cursor.getString(cursor.getColumnIndex("ncontent")));
            note.setCourse_id(cursor.getInt(cursor.getColumnIndex("course_id")));
            note.setDate(cursor.getString(cursor.getColumnIndex("ndate")));
            note.setTime(cursor.getString(cursor.getColumnIndex("ntime")));
            int deletable = cursor.getInt(cursor.getColumnIndex("deletable"));
            if(deletable == 1){
                note.setDeletable(true);
            }else{
                note.setDeletable(false);
            }
            notes.add(note);    
            cursor.moveToNext();
        }
        
        db.close();
        cursor.close();
        
        return notes;
    }

2.使用dataBase.query(...),這很容易,在此就不說了。