2013年9月6日 星期五

單元二: 手機的資料儲存 --- SQLite

Android SQLite 是 Android 手機上管理資料存取的系統,  它可以執行增(insert), 刪(delete), 改(update), 查(read)的動作, 特點是生成的檔案很輕量, 也支持標準的 SQL 語句.

要瞭解 SQLite 的使用, 必須先認識一下資料庫的格式:

資料庫格式

資料庫一般可以想成是一張表, 整張表會有個名稱叫 table_name,
表直的部分稱作 Column, 橫的叫 Row,
這裡的 product_id, product_name 都是 column_name,
而每個 Row 都是一組 Data,
例如: product_id = 1, product_name = cup_1 就是我們這張表的第一組 Data 了.



SQLite 的 Type 只有 TEXT, INTEGER, REAL ( similar to double in java) 三種. 使用上要稍注意.

SQLite 的使用

SQLite 使用上可以分三個步驟:
1. 建立資料的物件 Product
2. 建立繼承自 SQLiteOpenHelper 的 DatabasHelper
3. 在主程式內調用

我們就以一開始介紹的那張表為例, 來講解這三個步驟.

1. 建立資料的物件 Product

Product.class
 public class Product {  
      private int id;  
      private String name;  
      public Product() {  
      }  
      public Product(int id, String productname) {  
           this.id = id;  
           this.name = productname;  
      }  
      public Product(String productname) {  
           this.name = productname;  
      }  
      public void setID(int id) {  
           this.id = id;  
      }  
      public int getID() {  
           return this.id;  
      }  
      public void setProductName(String productname) {  
           this.name = productname;  
      }  
      public String getProductName() {  
           return this.name;  
      }  
 }  

2. 建立繼承自 SQLiteOpenHelper 的 DatabasHelper

SQLiteOpenHelper 是 Android 幫我們準備好的元件,
我們要繼承它, 並實作 onCreate(), 以及 onUpgrade().
OnCreate() 用來創建一張新的表,
onUpgrade() 則會先檢查這張表的 version, 如果有新 version 就把舊的丟掉, 呼叫 onCreate() 做張新的.

ProductDBHelper.class
      @Override  
      public void onCreate(SQLiteDatabase db) {  
           String CREATE_PRODUCTS_TABLE = "CREATE TABLE " +  
             TABLE_PRODUCTS + "("  
             + COLUMN_ID + " INTEGER PRIMARY KEY," + COLUMN_PRODUCTNAME   
             + " TEXT" + ")";  
         db.execSQL(CREATE_PRODUCTS_TABLE);  
      }  
      @Override  
      public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
           db.execSQL("DROP TABLE IF EXISTS " + TABLE_PRODUCTS);  
         onCreate(db);  
      }  

同時, 我們也把增.刪.查的方法寫在 ProductDBHelper.class 裡, 方便之後使用

ProductDBHelper.class
      // 增加單筆資料  
      public void addProduct(Product product) {  
          ContentValues values = new ContentValues();  
          values.put(COLUMN_PRODUCTNAME, product.getProductName());  
          SQLiteDatabase db = this.getWritableDatabase();  
          db.insert(TABLE_PRODUCTS, null, values);  
          db.close();  
      }  
      // 找所有資料  
      public ArrayList<Product> getAllProduct(){       
           ArrayList<Product> products = new ArrayList<Product>();  
           String query = "Select * FROM " + TABLE_PRODUCTS + " ORDER BY _ID ASC";  
           SQLiteDatabase db = this.getWritableDatabase();  
           Cursor cursor = db.rawQuery(query, null);  
           int rows_num = cursor.getCount();  
            if(rows_num != 0) {  
            cursor.moveToFirst();    
            for(int i=0; i<rows_num; i++) {  
             Product product = new Product();  
             product.setID(Integer.parseInt(cursor.getString(0)));  
             product.setProductName(cursor.getString(1));  
             products.add(product);  
             cursor.moveToNext();  
            }  
            }  
            cursor.close();  
           return products;  
      }  
      // 找單筆資料  
      public Product findProduct(String productname) {  
           String query = "Select * FROM " + TABLE_PRODUCTS + " WHERE " + COLUMN_PRODUCTNAME + " = \"" + productname + "\"";  
           SQLiteDatabase db = this.getWritableDatabase();  
           Cursor cursor = db.rawQuery(query, null);  
           Product product = new Product();  
           if (cursor.moveToFirst()) {  
                cursor.moveToFirst();  
                product.setID(Integer.parseInt(cursor.getString(0)));  
                product.setProductName(cursor.getString(1));  
                cursor.close();  
           } else {  
                product = null;  
           }  
          db.close();  
           return product;  
      }  
      // 刪除資料  
      public boolean deleteProduct(String productname) {  
           boolean result = false;  
           String query = "Select * FROM " + TABLE_PRODUCTS + " WHERE " + COLUMN_PRODUCTNAME + " = \"" + productname + "\"";  
           SQLiteDatabase db = this.getWritableDatabase();  
           Cursor cursor = db.rawQuery(query, null);  
           Product product = new Product();  
           if (cursor.moveToFirst()) {  
                product.setID(Integer.parseInt(cursor.getString(0)));  
                db.delete(TABLE_PRODUCTS, COLUMN_ID + " = ?",  
                 new String[] { String.valueOf(product.getID()) });  
                cursor.close();  
                result = true;  
           }  
          db.close();  
           return result;  
      }  

3. 在主程式內調用

在這個程式, 我們先產生 product 的資料, 將其寫入資料庫裡,
然後再讀出來設給 ListView

MainActivity.class
          // 寫入資料  
           ProductDBHelper dbHandler = new ProductDBHelper(this, null, null, 1);  
           for (int i = 0 ; i< 11 ; i++){       
                Product newProduct = new Product("cup_"+ Integer.toString(i));  
                dbHandler.addProduct(newProduct);  
           }  
           // 讀取資料  
           mProducts = dbHandler.getAllProduct();  
           ListAdapter adapter = new ListAdapter(this, mProducts);  
           mainList.setAdapter(adapter);  

當然我們還必須實作 ListAdapter. 不過這不是這篇的重點.
就請直接看程式碼吧.

P.S 如果對於 ListAdapter 不大瞭解, 可以看 ListView 的教學.

範例圖: (原始碼連結)




沒有留言:

張貼留言