標籤:android 移動開發
在Android中使用的資料庫是開來源資料庫Sqlite資料庫,下面主要詳細的介紹Sqlite的使用:
一 SQLite簡介
我們在編寫資料庫應用軟體時,需要考慮這樣的問題:因為我們開發的軟體可能會安裝在很多使用者的手機上,如果應用使用到了SQLite資料庫,我們必須在使用者初次使用軟體時建立出應用使用到的資料庫表結構及添加一些初始化記錄,另外在軟體升級的時候,也需要對資料表結構進行更新。那麼,我們如何才能實現在使用者初次使用或升級軟體時自動在使用者的手機上建立出應用需要的資料庫表呢?總不能讓我們在每個需要安裝此軟體的手機上通過手工方式建立資料庫表吧?因為這種需求是每個資料庫應用都要面臨的,所以在Android系統,為我們提供了一個名為SQLiteOpenHelper的抽象類別,必須繼承它才能使用,它是通過對資料庫版本進行管理來實現前面提出的需求。
為了實現對資料庫版本進行管理,SQLiteOpenHelper類提供了兩個重要的方法,分別是onCreate(SQLiteDatabasedb)和onUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion),前者用於初次使用軟體時產生資料庫表,後者用於升級軟體時更新資料庫表結構。當調用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法擷取用於操作資料庫的SQLiteDatabase執行個體的時候,如果資料庫不存在,Android系統會自動產生一個資料庫,接著調用onCreate()方法,onCreate()方法在初次產生資料庫時才會被調用,在onCreate()方法裡可以產生資料庫表結構及添加一些應用使用到的初始化資料。onUpgrade()方法在資料庫的版本發生變化時會被調用,一般在軟體升級時才需改變版本號碼,而資料庫的版本是由程式員控制的,假設資料庫現在的版本是1,由於業務的變更,修改了資料庫表結構,這時候就需要升級軟體,升級軟體時希望更新使用者手機裡的資料庫表結構,為了實現這一目的,可以把原來的資料庫版本設定為2(有同學問設定為3行不行?當然可以,如果你願意,設定為100也行),並且在onUpgrade()方法裡面實現表結構的更新。當軟體的版本升級次數比較多,這時在onUpgrade()方法裡面可以根據原版號和目標版本號碼進行判斷,然後作出相應的表結構及資料更新。
getWritableDatabase()和getReadableDatabase()方法都可以擷取一個用於操作資料庫的SQLiteDatabase執行個體。但getWritableDatabase()方法以讀寫方式開啟資料庫,一旦資料庫的磁碟空間滿了,資料庫就只能讀而不能寫,倘若使用getWritableDatabase()開啟資料庫就會出錯。getReadableDatabase()方法先以讀寫方式開啟資料庫,如果資料庫的磁碟空間滿了,就會開啟失敗,當開啟失敗後會繼續嘗試以唯讀方式開啟資料庫。
1先完成建立資料庫操作:定義DBOpenHelper需要繼承SQLiteOpenHelper類,重寫onCreate方法建立資料庫,當版本號碼變化時,執行onUpgrade更新資料表資訊。
package com.andy.service;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;public class DBOpenHelper extends SQLiteOpenHelper{ public DBOpenHelper(Context context) {super(context, "andy.db", null, 0);}//資料庫版本號碼從0開始 第一次為建立 沒加一次就會執行資料庫資訊的更新操作@Overridepublic void onCreate(SQLiteDatabase db) {//資料庫每一次被建立的時間調用db.execSQL("CREATE TABLE person(personid integer primary key autoincrement, name varchar(20), phone VARCHAR(12) NULL)");}@Overridepublic void onUpgrade(SQLiteDatabase db, int orderVersion, int newVersion) {db.execSQL("ALTER TABLE person ADD amount integer");}}
2 定義實現的PersonService資料庫操作類
package com.andy.service;import java.util.ArrayList;import java.util.List;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import com.andy.domain.Person;public class PersonService {private DBOpenHelper dbOpenHelper;public PersonService(Context context) {dbOpenHelper = new DBOpenHelper(context);}// 開啟資料庫的方法有getWritableDatabase getReadableDatabase 如果資料庫未滿時 返回的是writablepublic void save(Person person) {SQLiteDatabase sqLiteDatabase = dbOpenHelper.getWritableDatabase();sqLiteDatabase.execSQL("insert into person(name, phone, amount) values(?, ?, ?) ",new String[] { person.getName(), person.getPhone(),String.valueOf(person.getAmount()) });}public void update(Person person) {SQLiteDatabase sqLiteDatabase = dbOpenHelper.getWritableDatabase();sqLiteDatabase.execSQL("update person set name=?, phone=?, amount=? where personid = ?",new String[] { person.getName(), person.getPhone(),person.getAmount().toString(),person.getId().toString() });}public void delete(int id) {SQLiteDatabase sqLiteDatabase = dbOpenHelper.getWritableDatabase();sqLiteDatabase.execSQL("delete from person where personid=?",new Integer[] { id });}public Person find(Integer id) {SQLiteDatabase sqLiteDatabase = dbOpenHelper.getReadableDatabase();// 讀取資料Cursor cursor = sqLiteDatabase.rawQuery("SELECT * FROM person WHERE personid = ?",new String[] { id.toString() });if (cursor.moveToFirst()) {int personid = cursor.getInt(cursor.getColumnIndex("personid"));String name = cursor.getString(cursor.getColumnIndex("name"));String phone = cursor.getString(cursor.getColumnIndex("phone"));int amount = cursor.getInt(cursor.getColumnIndex("amount"));return new Person(personid, name, phone, amount);}cursor.close();// 遊標 需要關閉return null;}public List<Person> getScrollData(int offset, int maxResult) {SQLiteDatabase sqLiteDatabase = dbOpenHelper.getReadableDatabase();List<Person> persons = new ArrayList<Person>();Cursor cursor = sqLiteDatabase.rawQuery("select * from person order by personid limit ?,? ",new String[] { String.valueOf(offset),String.valueOf(maxResult) });while (cursor.moveToNext()) {int personid = cursor.getInt(cursor.getColumnIndex("personid"));String name = cursor.getString(cursor.getColumnIndex("name"));String phone = cursor.getString(cursor.getColumnIndex("phone"));int amount = cursor.getInt(cursor.getColumnIndex("amount"));persons.add(new Person(personid, name, phone, amount));}cursor.close();return persons;}public long getCount() {SQLiteDatabase sqLiteDatabase = dbOpenHelper.getReadableDatabase();Cursor cursor = sqLiteDatabase.rawQuery("select count(*) from person",null);cursor.moveToFirst();long result = cursor.getLong(0);cursor.close();return result;}public Cursor getCursorScrollData(int offset, int maxResult){SQLiteDatabase sqLiteDatabase = dbOpenHelper.getReadableDatabase();Cursor cursor = sqLiteDatabase.rawQuery("select personid _id, name, phone, amount from person order by personid limit ?,? ",new String[] { String.valueOf(offset),String.valueOf(maxResult) });return cursor;}//測試事務 transaction public void payment(){SQLiteDatabase sqLiteDatabase = dbOpenHelper.getWritableDatabase();sqLiteDatabase.beginTransaction();try{sqLiteDatabase.execSQL("update person set amount = amount -10 where personid = 1");sqLiteDatabase.execSQL("update person set amount = amount + 10 where personid = 2");sqLiteDatabase.setTransactionSuccessful();}finally{sqLiteDatabase.endTransaction();//結束事務有兩種情況 commit rollback //事物的提交是由事務的標誌決定的,如果事務的標誌為true,事務就會提交,否則就會復原,預設情況下事務的狀態的狀態是FALSE//無論復原或者是提交 必須要執行事務的結束 放在try finally中執行}}}
3 使用到的Person類
package com.andy.domain;public class Person {private Integer id;private String name;private String phone;private Integer amount;public Person(){}public Person(String name, String phone, Integer amount) {super();this.name = name;this.phone = phone;this.amount = amount;}public Person(Integer id, String name, String phone, Integer amount) {super();this.id = id;this.name = name;this.phone = phone;this.amount = amount;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public Integer getAmount() {return amount;}public void setAmount(Integer amount) {this.amount = amount;}@Overridepublic String toString() {return "Person [id=" + id + ", name=" + name + ", phone=" + phone+ ", amount=" + amount + "]";}}
Android開發之資料庫Sqlite