close
Android使用SQLite資料庫
Android內建的SQLite為開放式的小型資料庫,應用程式可以建立自己需要的資料庫,並使用Android API做管理與查詢的工作
特色為支援精簡「SQL」指令、效能好、相對其它資料庫使用更少的記憶體,因為所有資料都儲存在一個檔案當中,所以在移轉資料時也非常便利
在此先來說一下資料表格,這是用來劃分各個欄位儲存不同資料,例如整理班級考試成績,就會有班級、學號、各項成績....等各項欄位
而欄位的分為以下幾種資料型態:
INTEGER – 整數,對應Java 的byte、short、int 和long。
REAL – 小數,對應Java 的float 和double。
TEXT – 字串,對應Java 的String。
介紹SQLiteOpenHelper類別
Android 中可以透過繼承SQLiteOpenHelper來建立資料庫與表格,後續執行時開啟建立好的資料庫
建立資料庫表格使用SQL的「CREATE TABLE」指令,且需指定表格名稱,還有各個欄位名稱與資料型態
而表格內一定要包含一個可以自動為資料編號的欄位,欄位名稱固定為「_id」,型態為「INTEGER」,後面加上「PRIMARY KEY AUTOINCREMENT」的設定,將能設為主鍵且自動增加,保證裡面的資料是唯一的,而其他欄位型態後面可選擇是否加上「NOT NULL」,該欄位就不可以為空值,如果新增資料時沒有指定該欄位設值將會發生錯誤
使用SQL可分為以下四個動作,等等會在範例中一一使用
1.新增記錄(Insert)。
2.查詢記錄(Query)。
3.更改記錄(Update)。
4.刪除記錄(Delete)。
以下先來決定資料表的欄位,如果範例為多人聊天紀錄,就必須有以下欄位:
1.用來判斷第幾筆資料的主鍵的:_id
2.聊天紀錄說話者姓名:name
3.說的內容:content
4.字的顏色:color
5.多人聊天的玩家號碼:number
先來設定一下幾種文字顏色,範例為:
package com.example.sqlite; import android.graphics.Color; public enum Colors { //能在列舉內實作幾個物件 LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"), GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444"); private String code; private Colors(String code) { //建構子設為private因為只在物件內實作出物件 this.code = code; } public String getCode() { //取得顏色的String return code; } public int parseColor() { //使用Color解析code return Color.parseColor(code); } }
設定完顏色後,再來針對各個欄位的資料寫一個物件方便存取,範例為:
package com.example.sqlite; import java.io.Serializable; @SuppressWarnings("serial") public class Item implements Serializable{ //介面為物件序列化,可將物件變成二進位串流,就可儲存成檔案,也可以直接將物件丟進輸出入串流做傳送 private long id; private String name; private String content; private Colors color; private long number; public Item(){ content = ""; color = Colors.LIGHTGREY; } public Item(long id,String name,String content,Colors color,long number){ this.id=id; this.name=name; this.content=content; this.color=color; this.number=number; } public void setId(long id){ this.id=id; } public long getId(){ return this.id; } public void setName(String name){ this.name=name; } public String getName(){ return this.name; } public void setContent(String content){ this.content=content; } public String getContent(){ return this.content; } public void setColor(Colors color){ this.color=color; } public Colors getColor(){ return this.color; } public void setNumber(long number){ this.number=number; } public long getNumber(){ return this.number; } }
再來示範繼承SQLiteOpenHelper的物件並建立資料庫與表格
package com.example.sqlite; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class MyDBHelper extends SQLiteOpenHelper { // 資料庫名稱 public static final String DATABASE_NAME = "mydata.db"; // 資料庫版本,資料結構改變的時候要更改這個數字,通常是加一 public static int VERSION = 1; // 資料庫物件,固定的欄位變數 private static SQLiteDatabase database; //context為當前activity的上下文,name為要操作的資料庫名稱,factory用來做深入查詢用,version為版本 public MyDBHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub } //只有在資料庫不存在時,才會呼叫onCreate()建立資料庫 @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub // 建立要存放資料的資料表格 // 1. SQL語法不分大小寫 // 2. 這裡大寫代表的是SQL標準語法, 小寫字是資料表/欄位的命名 // 建立應用程式需要的表格 db.execSQL(Test_Data.CREATE_TABLE); } //使用建構子時如果版本增加,便會呼叫onUpgrade()刪除舊的資料表與其內容,再重新呼叫onCreate()建立新的資料表 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub // 刪除原有的表格 db.execSQL("DROP TABLE IF EXISTS " + Test_Data.TABLE_NAME); // 呼叫onCreate建立新版的表格 onCreate(db); } // 需要資料庫的元件呼叫這個方法,這個方法在一般的應用都不需要修改 public static SQLiteDatabase getDatabase(Context context) { if (database == null || !database.isOpen()) { database = new MyDBHelper(context, DATABASE_NAME, null, VERSION).getWritableDatabase(); } return database; } }
上面範例的Test_Data物件是寫來實作表單、實作資料庫物件、關閉資料庫、新增記錄、查詢記錄、更改記錄、刪除記錄、建立範例資料,以下為該範例:
package com.example.sqlite; import java.util.ArrayList; import java.util.List; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; // 資料功能類別 public class Test_Data { // 表格名稱 public static final String TABLE_NAME = "test_data"; // 編號表格欄位名稱,固定不變 public static final String KEY_ID = "_id"; // 其它表格欄位名稱 public static final String NAME_COLUMN = "name"; public static final String CONTENT_COLUMN = "content"; public static final String COLOR_COLUMN = "color"; public static final String NUMBER_COLUMN = "number"; // 使用上面宣告的變數建立表格的SQL指令 public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + NAME_COLUMN + " TEXT NOT NULL, " + CONTENT_COLUMN + " TEXT, " + COLOR_COLUMN + " INTEGER NOT NULL, " + NUMBER_COLUMN + " INTEGER NOT NULL)"; // 資料庫物件 private SQLiteDatabase db; // 建構子,一般的應用都不需要修改 public Test_Data(Context context){ db = MyDBHelper.getDatabase(context); } // 關閉資料庫,一般的應用都不需要修改 public void close() { db.close(); } // 新增參數指定的物件 public Item insert(Item item) { // 建立準備新增資料的ContentValues物件 ContentValues cv = new ContentValues(); // 加入ContentValues物件包裝的新增資料 // 第一個參數是欄位名稱, 第二個參數是欄位的資料 cv.put(NAME_COLUMN, item.getName()); cv.put(CONTENT_COLUMN, item.getContent()); cv.put(COLOR_COLUMN, item.getColor().parseColor()); cv.put(NUMBER_COLUMN, item.getNumber()); // 新增一筆資料並取得編號 // 第一個參數是表格名稱 // 第二個參數是沒有指定欄位值的預設值 // 第三個參數是包裝新增資料的ContentValues物件 long id = db.insert(TABLE_NAME, null, cv); // 設定編號 item.setId(id); // 回傳結果 return item; } // 修改參數指定的物件 public boolean update(Item item) { // 建立準備修改資料的ContentValues物件 ContentValues cv = new ContentValues(); // 加入ContentValues物件包裝的修改資料 // 第一個參數是欄位名稱, 第二個參數是欄位的資料 cv.put(NAME_COLUMN, item.getName()); cv.put(CONTENT_COLUMN, item.getContent()); cv.put(COLOR_COLUMN, item.getColor().parseColor()); cv.put(NUMBER_COLUMN, item.getNumber()); // 設定修改資料的條件為編號 // 格式為「欄位名稱=資料」 String where = KEY_ID + "=" + item.getId(); // 執行修改資料並回傳修改的資料數量是否成功 return db.update(TABLE_NAME, cv, where, null) > 0; } // 刪除參數指定編號的資料 public boolean delete(long id){ // 設定條件為編號,格式為「欄位名稱=資料」 String where = KEY_ID + "=" + id; // 刪除指定編號資料並回傳刪除是否成功 return db.delete(TABLE_NAME, where , null) > 0; } // 讀取所有記事資料 public List<Item> getAll() { List<Item> result = new ArrayList<Item>(); //游標指向該資料表 Cursor cursor = db.query(TABLE_NAME, null, null, null, null, null, null, null); //將所有資料轉成Item並添加進List while (cursor.moveToNext()) { result.add(getRecord(cursor)); } //關閉游標 cursor.close(); return result; } // 取得指定編號的資料物件 public Item get(long id) { // 準備回傳結果用的物件 Item item = null; // 使用編號為查詢條件 String where = KEY_ID + "=" + id; // 執行查詢 Cursor result = db.query(TABLE_NAME, null, where, null, null, null, null, null); // 如果有查詢結果 if (result.moveToFirst()) { // 讀取包裝一筆資料的物件 item = getRecord(result); } // 關閉Cursor物件 result.close(); // 回傳結果 return item; } // 把游標Cursor取得的資料轉換成目前的資料包裝為物件 public Item getRecord(Cursor cursor) { // 準備回傳結果用的物件 Item result = new Item(); result.setId(cursor.getLong(0)); result.setName(cursor.getString(1)); result.setContent(cursor.getString(2)); result.setColor(getColors(cursor.getInt(3))); result.setNumber(cursor.getLong(4)); return result; } //將顏色的int型態轉換成Colors物件(只能為內建的幾種選項) private Colors getColors(int color) { Colors result = Colors.LIGHTGREY; if (color == Colors.BLUE.parseColor()) { result = Colors.BLUE; }else if (color == Colors.PURPLE.parseColor()) { result = Colors.PURPLE; }else if (color == Colors.GREEN.parseColor()) { result = Colors.GREEN; }else if (color == Colors.ORANGE.parseColor()) { result = Colors.ORANGE; }else if (color == Colors.RED.parseColor()) { result = Colors.RED; } return result; } // 取得資料數量 public int getCount() { int result = 0; Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + TABLE_NAME, null); if (cursor.moveToNext()) { result = cursor.getInt(0); } return result; } // 建立範例資料 public void sample() { Item item = new Item(0,"test 玩家1號",null, Colors.RED,1); Item item2 = new Item(0,"test 玩家2號","內文zxc", Colors.BLUE,2); Item item3 = new Item(0,"test 玩家3號","內文asd", Colors.GREEN,3); Item item4 = new Item(0,"test 玩家4號","內文qwe", Colors.ORANGE,4); insert(item); insert(item2); insert(item3); insert(item4); } }
最後來寫個app使用以上物件,此範例僅時做資料庫物件後,添加範例資料並取得所有資料顯示出來,最後關閉資料庫:
package com.example.sqlite; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends Activity { TextView t01; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); t01=(TextView) this.findViewById(R.id.t01); // 建立資料庫物件 Test_Data test=new Test_Data(MainActivity.this); // 如果資料庫是空的,就建立一些範例資料 // 這是為了方便測試用的,完成應用程式以後可以拿掉 if (test.getCount() == 0) { test.sample(); } t01.setText("Test測試:\n"); //取得資料數 t01.append("目前資料庫裡有"+String.valueOf(test.getCount()).toString()+"筆資料\n"); // 取得所有記事資料 List<Item> items=test.getAll(); for(Item i:items){ t01.append("\n第"+String.valueOf(i.getId()).toString()+"筆聊天紀錄\n"); t01.append("該玩家number為="+String.valueOf(i.getNumber()).toString()+"\n"); t01.append("name為="+i.getName()+"\n"); t01.append("content為="+i.getContent()+"\n"); t01.append("文字color為="+i.getColor().getCode()+"\n"); } test.close(); } }
新增記錄時,實做好Item後使用insert()添加,id部分隨便填,到時會自動依位置更改
修改記錄時,實做好Item後使用update()修改,id部分設為想修改的記錄id
如需刪除記錄則使用delete()刪除,參數為想刪除的記錄id
查詢可以分為指定id與所有記錄,還有查詢資料筆數
基本的功能都有了,剩下的就自行修改使用了
此連結為用Eclipse輸出的範例:
https://mega.nz/#!M0lC1YoT!bc5eKV77Jix54E5Xgqht99S1fdii-yTMcl7L8fRbf18
參考資料:
http://blog.kdchang.cc/2015/07/android-note-sql-sq...
http://www.aaronlife.com/teaching/uch_android_2015...
http://www.codedata.com.tw/mobile/android-tutorial...
文章標籤
全站熱搜