1. 程式人生 > >2014-10-27Android學習------SQLite資料庫操作(二)-----資料庫的建立--SQLiteHelper extends SQLiteOpenHelper

2014-10-27Android學習------SQLite資料庫操作(二)-----資料庫的建立--SQLiteHelper extends SQLiteOpenHelper

上篇有篇文章講了資料庫的操作  條件是:資料庫已經建好的了,我們只需要從裡面獲取資料(查詢)就可以了,

現在我們來看看第二種資料庫的操作:

class SQLiteHelper extends SQLiteOpenHelper

封裝一個繼承SQLiteOpenHelper類的資料庫操作類。SQLiteOpenHelper類是一個抽象的輔助類,主要用來生成一個數據庫並對資料庫的版本進行管理,在SQLiteOpenHelper類的構造方法中分別傳入Context、資料庫名稱,CursorFactory(一般傳入null,否則為預設資料庫),資料庫版本號(不能為負數)。

在SQLiteOpenHelper中首先執行的是onCreate方法(當資料庫第一次建立時),一般在這個方法裡生成資料表。

要注意的是,在建構函式時並沒有真正建立資料庫,而是在呼叫getWriteableDatabase()或者getReadableDatabase()方法的時候系統才會真正建立資料庫,

如果當時系統中不存在這個資料庫,系統會自動生成一個數據庫,然後返回SQLiteDatabase物件。

在繼承這個類的時候,要實現裡面的3個方法,其中前兩個方法是必須重寫的。

/**
* 建立表
*/
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("CREATE TABLE IF NOT EXISTS " +
TB_NAME + "(" +
CityBean.ID + " integer primary key," +
CityBean.CITY + " varchar," + 
CityBean.CODE + " integer"+
")");


}


/**
* 當檢測與前一次建立資料庫版本不一樣時,先刪除表再建立新表
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + TB_NAME);// 先刪除表
onCreate(db);//再建立表
}

還有個onOpen(SQLiteDatabase db)  這個函式是:開啟資料庫時的回撥函式,一般不會用到

該類的原始碼如下:

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class SQLiteHelper extends SQLiteOpenHelper {
	
	public static final String TB_NAME = "citys";

	public SQLiteHelper(Context context, String name, CursorFactory factory,
			int version) {
		// version  就是 資料庫的版本號
		super(context, name, factory, version);
		// TODO Auto-generated constructor stub
	}

	/**
	 * 建立表
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		db.execSQL("CREATE TABLE IF NOT EXISTS " +
				TB_NAME + "(" +
				CityBean.ID + " integer primary key," +
				CityBean.CITY + " varchar," + 
				CityBean.CODE + " integer"+
				")");

	}

	/**
	 * 當檢測與前一次建立資料庫版本不一樣時,先刪除表再建立新表
	 */
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub
		db.execSQL("DROP TABLE IF EXISTS " + TB_NAME);// 先刪除表
		onCreate(db);//再建立表
	}
	
	
	/**
	 * 變更列名
	 * @param db
	 * @param oldColumn
	 * @param newColumn
	 * @param typeColumn
	 */
	public void updateColumn(SQLiteDatabase db, String oldColumn, String newColumn, String typeColumn){
		try{
			db.execSQL("ALTER TABLE " +
					TB_NAME + " CHANGE " +
					oldColumn + " "+ newColumn +
					" " + typeColumn
			);
		}catch(Exception e){
			e.printStackTrace();
		}
	}

}
使用這個類:

當我們在一個activity類中使用這個資料庫的時候  步奏如下:

1.必須先定義一個類的成員變數   申明資料庫名字   宣告資料庫的版本號  宣告一個查詢結果遊標  申明一個數據庫物件

private static String DB_NAME = "mycity.db";//資料庫名字
private static int DB_VERSION = 1;//資料庫版本號
private Cursor cursor;//查詢結果遊標集
private SQLiteDatabase db;//開啟資料庫返回物件
private SQLiteHelper dbHelper;//資料庫操作類

2.在一個activity的onCreate(Bundle)裡面初始化和使用上面的變數

    try{
    /* 初始化並建立資料庫 */
    dbHelper = new SQLiteHelper(this, DB_NAME, null, DB_VERSION);
    /* 建立表 */
    db = dbHelper.getWritableDatabase();//呼叫SQLiteHelper.OnCreate()        
        /* 查詢表,得到cursor物件 */
        cursor = db.query(SQLiteHelper.TB_NAME, null, null, null, null, null, CityBean.CODE + " DESC");
        cursor.moveToFirst();
        while(!cursor.isAfterLast() && (cursor.getString(1) != null)){    
        CityBean city = new CityBean();
        city.setId(cursor.getString(0));
        city.setCity(cursor.getString(1));
        city.setCode(cursor.getString(2));
        cityList.add(city);
        cursor.moveToNext();
        }
    }catch(IllegalArgumentException e){
    //當用SimpleCursorAdapter裝載資料時,表ID列必須是_id,否則報錯column '_id' does not exist
    e.printStackTrace();
    //當版本變更時會呼叫SQLiteHelper.onUpgrade()方法重建表 注:表以前資料將丟失
    ++ DB_VERSION;
    dbHelper.onUpgrade(db, --DB_VERSION, DB_VERSION);

    }


3.在函式中使用:

查詢:

    cursor = db.query(true, SQLiteHelper.TB_NAME, 
    new String[]{CityBean.ID, CityBean.CITY, CityBean.CODE}, 
    sql, 
    null, null, null, null, null);

新增:

Long cityID = db.insert(SQLiteHelper.TB_NAME, CityBean.ID, values); 插入成功的話會返回一個值

修改:

db.update(SQLiteHelper.TB_NAME, values, CityBean.ID + "=" + cityList.get(POSTION).getId(), null);

刪除:

db.delete(SQLiteHelper.TB_NAME, CityBean.ID + "=" + view.getId(), null);

4.在activity銷燬之後需要關閉資料庫的:

在activity的生命週期函式onDestroy()裡面加上下面的程式碼

    @Override
    protected void onDestroy() {
    db.delete(SQLiteHelper.TB_NAME, null, null);
    super.onDestroy();
    }

至此  一個簡單的資料庫操作基本完成了,下面我們來看看需要掌握的知識:

Android中每一個數據庫對建立它的應用程式包套件來說都是私有的,預設情況下其他應用程式無法直接訪問此私有資料庫。所有的資料庫檔案存放在手機中的/data/data/package_name/databases路徑下,以下是常用的與資料庫相關的函式:


那麼我們首先需要學習一下資料庫的  建立函式    開啟函式  關閉函式   

返回值

函式

備註

static SQLiteDatabase

create(SQLiteDatabase.CursorFactory factory)

建立一個數據庫

factory:可選的資料庫遊標工廠類,當查詢(query)被提交時,該物件會被呼叫來例項化一個遊標。

static SQLiteDatabase

openDatabase(String path,SQLiteDatabase.CursorFactory factory,int flags)

根據提供的模式開啟一個數據庫

path:開啟或建立的資料庫檔案

factory:可選的資料庫遊標工廠類,當查詢(query)被提交時,該物件會被呼叫來例項化一個遊標。預設為null。

flags:控制資料庫的訪問模式。主要有以下幾種模式:

l OPEN_READWRITE

l OPEN_READONLY

l CREATE_IF_NECESSARY

l NO_LOCALIZED_COLLATORS

static SQLiteDatabase

openOrCreateDatabase(File file, SQLiteDatabase.CursorFactory factory)

等同於openDatabase(file.getPath(), factory, CREATE_IF_NECESSARY)

static SQLiteDatabase

openOrCreateDatabase(String path, SQLiteDatabase.CursorFactory factory)

等同於openDatabase(path,factory, CREATE_IF_NECESSARY)

void

close()

關閉資料庫

boolean

deleteDatabase(String name)

刪除指定的資料庫

name:要關閉的資料庫的名字

上面表格裡面的有些引數請看我的上面一篇文章   地址:http://blog.csdn.net/u014737138/article/details/40618003

這些函式的使用方法:

//建立資料庫

SQLiteDatabase mydataBase=SQLiteDatabase.create(new CursorFactory(){

//工廠類,一個可選工廠類,當查詢時呼叫來例項化一個遊標

@Override

public Cursor newCursor(SQLiteDatabase db,

SQLiteCursorDriver masterQuery, String editTable,

SQLiteQuery query) {

// TODO Auto-generated method stub

return null;

}

});

//建立或開啟資料庫

SQLiteDatabase myDataBase=this.openOrCreateDatabase("myDataBase.db",

MODE_PRIVATE, new CursorFactory(){

//建立新的資料庫,名稱myDatabase,模式MODE_PRIVATE,可選的遊標工廠類

@Override

public Cursor newCursor(SQLiteDatabase db,

SQLiteCursorDriver masterQuery, String editTable,

SQLiteQuery query) {

// TODO Auto-generated method stub

return null;

}

});

SQLiteDatabase myDataBase=this.openOrCreateDatabase("myDataBase.db",MODE_PRIVATE,null);

//關閉資料庫

myDataBase.close();

//刪除指定名稱的資料庫

this.deleteDatabase(“myDatabase.db”);
2.對資料庫表的操作   主要是建表:這個是一個非查詢操作  一般使用execSQL(sql)命令來執行

在對資料庫中的表進行相關操作時,可以使用非查詢的execSQL(String sql)來執行。示例程式碼如下:

String CREATE_TABLE = “create table table1 (_id integer primary key autoincrement,number integer,data text)”; //建立表

myDataBase.execSQL(CREATE_TABLE);


1)對錶的插入操作:

long insert(String table, String nullColumnHack, ContentValues values)
向表中插入一條資料
引數:
table:想要插入資料的表名
nullColumnHack:SQL不允許插入空行,初始化值為空時,這一列將會被顯示地賦一個null值
values:要插入的值,型別為ContentValues

ContentValues主要是存放表中的資料段,以及其對應的值,與map一樣採用名值對的形式儲存,但是它儲存的名值對中,名是一個String型別,值是基本資料型別。其使用示例如下:簡單的理解他就是鍵值對,跟map一樣,如果你看原始碼,它其實就是繼承他們並實現的。

ContentValues args = new ContentValues();

args.put(KEY_TITLE, title);

args.put(KEY_BODY, body);

myDataBase.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null);


2)對錶的更新  修改操作

int update(String table, ContentValues values, String whereClause, String[] whereArgs)
修改表中的資料
table:想要修改資料的表名
values:要更新的值,使用方法看上面的例子
whereClause:可選的where子句,如果其值為null,將會修改所有的行。
whereArgs:當在whereClause中包含”?”時,如果whereArgs的值不為null,則這個陣列中的值將依次替換whereClause中出現的”?”   ?就是寫sql語句佔位符

3)刪除一行資料

int delete(String table, String whereClause, String[] whereArgs)
從表中刪除一行資料
table:想要刪除資料的表名
whereClause:可選的where子句,如果其值為null,將會刪除所有的行。
whereArgs:當在whereClause中包含”?”時,如果whereArgs的值不為null,則這個陣列中的值將依次替換whereClause中出現的”?”

4)查詢表操作

Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
查詢資料表
table:要查詢資料的表名
columns:要返回的列的列名陣列
selection:可選的where子句 ,如果其值為null,將會返回所有的行
selectionArgs:當在selection中包含”?”時,如果selectionArgs的值不為null,則這個陣列中的值將依次替換selection中出現的”?”
groupBy:可選的group by子句,如果其值為null,將不會對行進行分組
having:可選的having子句,如果其值為null,將會包含所有的分組
orderBy:可選的order by子句,如果其值為null,將會使用預設的排序規則
limit:可選的limit子句,如果其值為null,將不會包含limit子句

3.關於遊標Cursor學習:

Android採用遊標對從資料庫中查詢出來的結果進行隨機的讀寫訪問,在查詢資料庫後,將結果返回給遊標(即android.database.Cursor),這是查詢結果的記錄集,示意圖如下:

_id

someNumber

clip_image002

1

8

2

10

3

2


Cursor類常見的方法如下:

返回值

函式

備註

boolean

move(int offset)

以當前位置為參考,將Cursor移動指定數目的位置(相對位置)

boolean

moveToPosition(int position)

將Cursor移動到指定位置(絕對位置)

boolean

moveToNext()

將Cursor向前移動一個位置

boolean

moveToLast()

將Cursor向後移動一個位置

boolean

moveToFirst()

將Cursor移動到第一行

boolean

isBeforeFirst()

返回Cursor是否指向第一項資料之前

boolean

isAfterLast()

返回Cursor是否指向最後一項資料之後

boolean

isClosed()

返回Cursor是否關閉

boolean

isFirst()

返回Cursor是否指向第一項資料

boolean

isLast()

返回Cursor是否指向最後一項資料

boolean

isNull(int columnIndex)

返回指定位置的值是否為null

int

getCount()

返回總的專案總數

int

getInt(int columnIndex)

返回指定列中的資料的int型表示

int

getColumnIndex(String columnName)

按給定的列的名字返回列的索引值,如果不存在則返回 -1


特別提示:

要建立一個Cursor(遊標),必須執行一個查詢,通過SQL使用rawQuery()方法或是更精心的query()方法,而不能使用execSQL(String sql)【戴帽子】方法。以下為Cursor的使用示例:

Cursor cur=myDataBase.rawQuery("select * from test", null);

if(cur!=null){//遊標不為空

//返回給定名稱的列的基於0開始的index,如果該屬性列不存在則返回-1

//通過它們的index來檢索屬性值

int numColumn=cur.getColumnIndex("someNumber");

if(cur.moveToFirst()){ //cur.moveToFirst()讓遊標指向第一行,如果遊標指向第一行,則返回true

do {

int num=cur.getInt(numColumn);//獲得當前行該屬性的值

/*Cursor提供了不同的方法來回索不同的資料型別,例如getInt(int index)/getString(int index)等等*/

/*做一些事情*/

} while (cur.moveToNext());

/*遊標移動到下一行,如果遊標已經到達結果集中的最後,即沒有行可以移動時,則返回false*/

//其他可能移動的是 moveToPrevious() 和moveToFirst()方法

}

}

至此資料庫的函式基本學習了一篇,現在就是以後如何去熟練的使用它們了

最後還是總結下   public class SQLiteHelper extends SQLiteOpenHelper{}做法經常用到的兩個函式:

返回值

函式

備註

public void

onCreate(SQLiteDatabase db)

在資料庫第一次生成時會呼叫這個方法,一般我們在這個方法裡生成資料表

public void

onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion)

當資料庫需要升級時,系統會自動呼叫這個方法,一般我們在這個方法裡刪除資料表,並建立新的資料表,並根據實際需求做其他的操作

public void

onOpen(SQLiteDatabase db)

這是開啟資料庫時的回撥函式,一般不會用到