顯示具有 sqlite 標籤的文章。 顯示所有文章
顯示具有 sqlite 標籤的文章。 顯示所有文章

2012-08-06

Android 手機資料庫(五) - SQLite之資料庫更新說明篇


如果你對資料庫還完全陌生,請參考之前的三篇文章(第一篇、第二篇、第三篇)

因為很多人都不了解Android的資料庫更新應該怎麼做,所以在此寫一篇說明文好了

希望不了解的人看完之後能比較有所了解,下面開始解釋:

先貼上資料庫的程式碼,裡面當然也包含一般更新資料庫(onUpgrade)


程式碼
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;

public class NewListDataSQL extends SQLiteOpenHelper {

  private static final int VERSION = 3;//資料庫版本  
  
  public NewListDataSQL(Context context, String name, CursorFactory factory,int version) { //建構子
   super(context, name, factory, version);
  }

  public NewListDataSQL(Context context,String name) { 
   this(context, name, null, VERSION); 
   } 
  
   public NewListDataSQL(Context context, String name, int version) {  
    this(context, name, null, version);  
      }  
   
  //輔助類建立時運行該方法
  @Override
  public void onCreate(SQLiteDatabase db) {
   String DATABASE_CREATE_TABLE =
     "create table newMemorandum("
       + "_ID INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL,"
             + "date VARCHAR,"
             + "note VARCHAR,"
             + "pw VARCHAR,"
             + "reminder INT,"
             + "type VARCHAR,"
             + "memo VARCHAR"
         + ")";
            db.execSQL(DATABASE_CREATE_TABLE);
  }

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
   //oldVersion=舊的資料庫版本;newVersion=新的資料庫版本
     //db.execSQL("DROP TABLE IF EXISTS newMemorandum"); //刪除舊有的資料表
     //onCreate(db);
   
   
   if (newVersion > oldVersion) {
       db.beginTransaction();
    
       boolean success = true;
       
         
         switch (oldVersion) {
           case 2:           
            
            Cursor cursor = db.rawQuery("select _ID,date from newMemorandum", null);
            int[] iID = new int[cursor.getCount()];
            String[] sDate = new String[cursor.getCount()];
            
            int rows_num = cursor.getCount(); //取得資料表列數
            
            if(rows_num != 0) {
            cursor.moveToFirst();   //將指標移至第一筆資料
            for(int i=0; i<rows_num; i++) {
             int iCr = cursor.getInt(0);
             String strCr = cursor.getString(1);
             iID[i]=iCr;
             sDate[i]=strCr.split(" ")[0].split("/")[0] + "/" + String.valueOf(Integer.valueOf(strCr.split(" ")[0].split("/")[1])) + "/" + String.valueOf(Integer.valueOf(strCr.split(" ")[0].split("/")[2])) + " " + strCr.split(" ")[2];
             
             //因為日期格式有變,所以重新更新
             //格式改為2012/6/6 12:02
             ContentValues cv = new ContentValues();
             cv.put("date", sDate[i]);
             
             db.update("newMemorandum", cv, "_ID=" + iID[i], null);
             
             cv = null;//消滅物件
             
             
             cursor.moveToNext();  //將指標移至下一筆資料
            }
           }
           cursor.close();  //關閉Cursor
            
           
            db.execSQL("ALTER TABLE newMemorandum ADD COLUMN reminder integer DEFAULT 0");
            db.execSQL("ALTER TABLE newMemorandum ADD COLUMN type VARCHAR");
            db.execSQL("ALTER TABLE newMemorandum ADD COLUMN memo VARCHAR");
            oldVersion++;
            
               success = true;
             break;
           case 1:
                        
            Cursor cursor2 = db.rawQuery("select _ID,date from newMemorandum", null);
            int[] iID2 = new int[cursor2.getCount()];
            String[] sDate2 = new String[cursor2.getCount()];
            
            int rows_num2 = cursor2.getCount(); //取得資料表列數
            
            if(rows_num2 != 0) {
             cursor2.moveToFirst();   //將指標移至第一筆資料
            for(int j=0; j<rows_num2; j++) {
             int iCr2 = cursor2.getInt(0);
             String strCr = cursor2.getString(1);
             iID2[j]=iCr2;
             sDate2[j]=strCr.split(" ")[0].split("/")[0] + "/" + String.valueOf(Integer.valueOf(strCr.split(" ")[0].split("/")[1])) + "/" + String.valueOf(Integer.valueOf(strCr.split(" ")[0].split("/")[2])) + " " + strCr.split(" ")[2];
             
             //因為日期格式有變,所以重新更新
             //格式改為2012/6/6 12:02
             ContentValues cv2 = new ContentValues();
             cv2.put("date", sDate2[j]);
             
             db.update("newMemorandum", cv2, "_ID=" + iID2[j], null);
             
             cv2 = null;//消滅物件
             
             
             cursor2.moveToNext();  //將指標移至下一筆資料
            }
           }
            cursor2.close();  //關閉Cursor
           
            db.execSQL("ALTER TABLE newMemorandum ADD COLUMN pw VARCHAR");
            db.execSQL("ALTER TABLE newMemorandum ADD COLUMN reminder integer DEFAULT 0");
            db.execSQL("ALTER TABLE newMemorandum ADD COLUMN type VARCHAR");
            db.execSQL("ALTER TABLE newMemorandum ADD COLUMN memo VARCHAR");
            oldVersion = 3;
               success = true;
             break;
         }
           
    
       if (success) {
         db.setTransactionSuccessful();
       }
       db.endTransaction();
     }
     else {
       onCreate(db);
     }
   
  }
  
  @Override    
   public void onOpen(SQLiteDatabase db) {     
           super.onOpen(db);       
           // TODO 每次成功打開數據庫後首先被執行     
       } 

   @Override
        public synchronized void close() {
            super.close();
            // TODO 每次關閉數據庫後被執行     
        }
}


說明:

此為資料庫SQLiteOpenHelper類的程式碼,幾個地方分析

1.資料庫的執行方式  
當系統要new出SQLiteOpenHelper類時,會先去找應用程式的DB資料夾下是否有該資料庫
如果沒有就執行建構子及onCreate建構該類別
如果有就執行onUpgrade更新資料庫

2.private static final int VERSION = 3;//資料庫版本  代表的意義與作用
(1)如果手機中沒有該應用程式,也等於沒有該資料庫(因為資料庫是獨立個體)
就會執行建構子構建該資料庫,建構子會帶入此VERSION,也就是從第3版開始
之後的更新也是從第4版開始,不能再回到第1版開始。

(2)如果有資料庫就會跳到onUpgrade事件中
oldVersion=舊的資料庫版本
newVersion=新的資料庫版本
這兩個是怎麼出現的呢?
在要更新資料庫時,您之前的VERSION一定是寫成這樣VERSION = 2
VERSION = 2 就是  = oldVersion
程式有修改時,資料庫也有修改,這時也會把VERSION改為VERSION = 3
VERSION = 3 就是 = newVersion
當你更新資料庫時,程式判別出VERSION = 3比之前的VERSION = 2大時
就會自動跳到onUpgrade事件中,帶入oldVersion=2、newVersion=3
當然你的舊版也可能是VERSION = 1(因為沒有即時更新)
程式還是會帶入oldVersion=1、newVersion=3

3.onUpgrade資料庫更新
(1)當我們了解了程式是怎麼判別資料庫更新後,再來看資料庫是怎麼更新的
因為舊版本可能不一樣,有可能最新版是第3版,舊版有1、2兩版
所以這裡可以針對不同版本做不同的更新動作,因為各版更新的都不同
所以可以用switch case分開各版本再對各版本做不同的更新動作(如上面程式碼)

(2)更新資料庫不止可以下ALTER的SQL指令而已,因為資料本身是存在的
只要不下Drop,所以可以用Cursor cursor = db.rawQuery把資料撈出來做變更
我個人是把資料撈出來做日期格式的變更,最後再下ALTER新增欄位
注意看程式碼中1版是ALTER了4個欄位,2版是ALTER了3個欄位
所以如果你是放上google play上是要針對每個版本做不同的更新
因為你不知道下載者有沒有即時去更新你的應用程式,所以基本上要保留資料
就要這樣寫把之前的版本做不同的更新,這樣才能確保每一個版本都能更新
到最新的版本而不會出錯。

以上說明希望能幫助你對Android的資料庫有了進一步的了解,謝謝。



2012-08-01

Android 手機資料庫(四) - 將圖片存入資料庫的方法

我們都知道一般照片都是放在手機的圖片資料夾下,很少會放到資料庫內

不過為了怕應用程式需要的照片不小心被刪了而讓應用程式出錯,所以

就需要把圖片存進資料庫內,這裡我就來介紹怎麼樣把照片存進資料庫和取出

注意:這部份因為有關係到資料庫,所以為了不讓程式碼太多,所以我只show出
如何取出和存入圖片的程式碼,所以對資料庫需要有一定的認識,這部份請參考
前三篇(第一篇、第二篇、第三篇)的介紹。


存入的程式碼
//圖片
 ImageView imageView_save = (ImageView) findViewById(R.id.img_newphoto);
               
        //imageView轉Bitmap
        //imageView_save.setDrawingCacheEnabled(true);
        //建立圖片的緩存,圖片的緩存本身就是一個Bitmap
        imageView_save.buildDrawingCache();
        //取得緩存圖片的Bitmap檔
        Bitmap bmp=imageView_save.getDrawingCache();
          
            //轉換為圖片指定大小
            //獲得圖片的寬高
            int width = bmp.getWidth();
            int height = bmp.getHeight();
            // 設置想要的大小
            int newWidth = 480;
            int newHeight = 525;
            // 計算缩放比例
            float scaleWidth = ((float) newWidth) / width;
            float scaleHeight = ((float) newHeight) / height;
            // 取得想要缩放的matrix參數
            Matrix matrix = new Matrix();
            matrix.postScale(scaleWidth, scaleHeight);
            // 得到新的圖片
            Bitmap newbm = Bitmap.createBitmap(bmp, 0, 0, width, height, matrix,true);
             
          
            // 先把 bitmap 轉成 byte
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            newbm.compress(Bitmap.CompressFormat.JPEG, 100, stream );
            byte bytes[] = stream.toByteArray();
            // Android 2.2以上才有內建Base64,其他要自已找Libary或是用Blob存入SQLite
            // 把byte變成base64
            String base64 = Base64.encodeToString(bytes, Base64.DEFAULT); 
           
            //放img進去SQLite
            ContentValues cv = new ContentValues();
            cv.put("image", base64);
           //添加方法
           long long1 = db.insert(table_name, "", cv)



取出的程式碼
//取出資料
        Cursor cursor = db.rawQuery("select * from newimg where season = '秋'", null);
        
        //用陣列存圖片,陣列大小 = 取出資料的筆數
 Drawable[] Drawablelist = new Drawable[cursor.getCount()];
 Bitmap[] bmplist = new Bitmap[cursor.getCount()];
        
        //取得資料表筆數
        int rows_num = cursor.getCount(); 
  if(rows_num != 0) {

          //將指標移至第一筆資料
   cursor.moveToFirst(); 
            
   for(int i=0; i<rows_num; i++) {
            // 把Base64變回bytes
     byte bytes[] = Base64.decode(cursor.getString(2), Base64.DEFAULT);

            //用BitmapFactory生成bitmap
     bmplist[i] = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 
       
     //轉換Bitmap為Drawable
            Drawable drawable = new BitmapDrawable(bmplist[i]);

            //存入Drawable陣列中
     Drawablelist[i]=drawable;

            //將指標移至下一筆資料
            cursor.moveToNext();  
          }
        }

        //關閉Cursor
 cursor.close(); 
        //關閉資料庫,釋放記憶體 
 dbHelper.close(); 



後記:

          在存入時我有多用了縮放圖片,而在取出時因程式需要,所以有把Bitmap

再轉換為Drawable,這個可以看個人程式上的需求去做改變,不一定要照copy

程式是死的,人是活的,希望大家都能寫出一支好的程式,感謝。

2012-07-05

Android 手機資料庫(三) - SQLite之資料庫更新(onUpgrade)操作

大家都知道當程式開始使用後,難免會因為修改或新增功能去修改資料庫

比如要加個功能,所以資料庫內要新增欄位,這時應該怎麼做呢?

網路上的資訊其實很少,一般都只會寫把舊的刪除

db.execSQL("DROP TABLE IF EXISTS newMemorandum"); //刪除舊有的資料表

但這樣寫使用者是會氣死的,因為資料全清空,一切重key

所以寫這個出來希望對有需要的人有幫助

該有的認知:

1.手機應用程式因為是單一封裝個體,所以資料庫也是各個獨立的
而且有版本之分,用意是用來判斷資料庫是否有修改


2.如果你只變更資料庫欄位(增加或減少),而沒有去修改版號(1 -> 2)
此時載入資料庫就會出錯,而且是要增加1號,這點要注意

實作增加欄位:
步驟1:
 private static final int VERSION = 2;//資料庫版本由1改為2  


步驟2:
新增onCreate裡面的table欄位
  //輔助類建立時運行該方法
    @Override
    public void onCreate(SQLiteDatabase db) {
    String DATABASE_CREATE_TABLE =
           "create table newMemorandum("
  + "_ID INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL,"
         + "date VARCHAR,"
         + "note VARCHAR,"
         + "pw VARCHAR,"
         + "reminder INT,"//新增欄位
         + "type VARCHAR,"//新增欄位
         + "memo VARCHAR"//新增欄位
         + ")";
        db.execSQL(DATABASE_CREATE_TABLE);
 }

步驟3:
修改onUpgrade
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  //oldVersion=舊的資料庫版本;newVersion=新的資料庫版本

  if (newVersion > oldVersion) {
   db.beginTransaction();//建立交易
    
    boolean success = false;//判斷參數
       
    //由之前不用的版本,可做不同的動作     
    switch (oldVersion) {
    case 1:           
      db.execSQL("ALTER TABLE newMemorandum ADD COLUMN reminder integer DEFAULT 0");
      db.execSQL("ALTER TABLE newMemorandum ADD COLUMN type VARCHAR");
      db.execSQL("ALTER TABLE newMemorandum ADD COLUMN memo VARCHAR");
      oldVersion++;
            
     success = true;
     break;
    }
               
     if (success) {
       db.setTransactionSuccessful();//正確交易才成功
      }
    db.endTransaction();
  }
  else {
    onCreate(db);
  }   
}

在載入資料庫時,程式會自動去判斷資料庫的版號
如果新的版號 > 原有資料庫版號,程式就會進入onUpgrade內
讓你做原資料庫升級的動作,不然在套用修改後的table時
會出現錯誤,一些網路上的資訊都是寫直接砍掉重練XD
db.execSQL("DROP TABLE IF EXISTS newMemorandum"); //刪除舊有的資料表
不過寫這樣的程式放上Google Play應該會被罵死吧
好了,就為你介紹到這裡,有問題請留言,謝謝。


Android 手機資料庫(二) - SQLite操作:新增、修改、刪除

上一節已經介紹了SQLite的創建及查詢

這節為你介紹SQLite的新增、修改、刪除

不囉嗦,直接進入主題

新增資料

package jim.memorandum;
import android.database.sqlite.SQLiteDatabase;

public class Add extends Activity {

        //SQLiteDatabase對象
 SQLiteDatabase db;
 //資料庫名
 public String db_name = "MemorandumSQL";
   
 //表名
 public String table_name = "newMemorandum";

 //輔助類名
 NewListDataSQL helper = new NewListDataSQL(Add.this, db_name);

        @Override
        public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.add);

          //以輔助類獲得類據庫對象
   db = helper.getWritableDatabase();
        }

        //儲存
        Button Add = (Button)findViewById(R.id.btn_save);
        
        View.OnClickListener listener1 = new View.OnClickListener() {  
        
        public void onClick(View view) {  
         String strToast = "新增成功!";//返回訊息
         note = (EditText) findViewById(R.id.editText1);//備忘事項
         
        //寫進SQLite
      ContentValues cv = new ContentValues();
      cv.put("date", date_add.getText().toString() + time_add.getText().toString());
      cv.put("note",note.getText().toString());
     String sPW = pw.getText().toString();
   //checkBox打勾了才加入密碼
   if(ckBox.isChecked())
   {
    strToast = strToast + " 密碼保護:已開啟!";
    if(sPW.equalsIgnoreCase(""))
    {
     cv.put("pw","");
    }
    else{
        cv.put("pw",sPW);
    }
   }
   else
   {
    strToast = "新增成功!";
    cv.put("pw","");
   }
   
   //提醒
   if(ck_remind_add.isChecked())
   {
    cv.put("reminder",1);
   }
   else
   {
    cv.put("reminder",0);
   }
   
   //備註
   cv.put("memo","");
   cv.put("type", "");
   
     //添加方法
      long long1 = db.insert(table_name, "", cv);
      //Cursor c = db.query(table_name, null, null, null, null,null, null);
      //添加成功後返回行號,失敗後返回-1
    if (long1 == -1) {
     Toast.makeText(Add.this,
       "新增失敗!", Toast.LENGTH_SHORT)
       .show();
    } else {
     mID = (int) long1;
       //加入提醒
      if(ck_remind_add.isChecked())
      {
        strToast = strToast + " 提醒:已開啟!";
        setReminder(true); 
      }
     
      
     Toast.makeText(Add.this,
       strToast, Toast.LENGTH_SHORT)
       .show();
     
     //新增完成就關閉
     Add.this.finish(); 
     
     //跳回主畫面,用下面的方式才會刷新
     Intent intent_request = new Intent(Add.this, MemorandumActivity.class);
     Add.this.startActivity(intent_request);
      
    }
           }  
       };  
       Add.setOnClickListener(listener1); 

說明:

創建db之前第一篇就有說明過了,所以這裡就不再贅述,不了解的請參考第一篇

New 一個 ContentValues 容器,用於儲存要新增進資料庫的資料

用法為ContentValues .put(欄位名稱,值)

再來新增進資料庫   long long1 = db.insert(table_name, "", cv);

long1是資料庫回傳值,-1表示失敗、不為-1時為新增的到第幾筆的行號

比如說資料庫內有二筆,我現在新增成功了,long1就會返回3

可以用來顯示現在資料庫共有幾筆資料

最後用Toast.makeText顯示成功訊息就完成新增了。



修改資料

  //修改:db.update(table,Values,whereClause,whereArgs)
 long long1 = db.update("newMemorandum", cv, "_ID=" + ID, null);

說明:

修改和新增大部份都相同,就只有寫入資料庫的指令不同

db.update(table,Values,whereClause,whereArgs)

table 表名:相對於SQL from後面的部份

Values :要修改的欄位名稱及修改的值

whereClause:

刪除資料

long long1 = db.delete("newMemorandum", "_ID=" + MID[index], null); 

說明:

和修改大同小異,這裡就不再說明了,看程式碼應該就能了解了

後記:

新增、修改、刪除這樣就算完成了,其實不算太難
資料庫儲存必須考慮記憶體空間及版更後資料必須保留等問題
這個後續我會再做說明,如有不懂請來信,謝謝。

2012-06-12

Android 手機資料庫(一) - SQLite 基本介紹、創建及查詢

開發手機應用程式的人都應該要知道的SQLite

資料庫是程式設計中一種不可或缺的夥伴

我剛開始學寫Android時也是本想打死看能不能不要需要資料庫

結果當然是"不可能"XD,該面對的還是要面對-.-

所以就開始研究起SQLite,後來覺得它一點也不難

總結一下研究後的感想:

1.沒有像MS-SQL有專屬操作介面可以看(網上有其他軟體可以找來用)

2.開發Android時不需要安裝,直接叫用就可以了

3.都是以單一檔案的方式存在,一支應用程式對應一個db檔

4.db存放路徑在:/data/data//databases/DB名稱.db

5.支援大多數的SQL指令

6.最大支援到2T bytes

以上是我研究後的心得,感覺上不是很難,只是沒介面使用上有點難而已

不過應該也還好。

基本介紹完了,下面我們來實作看看怎麼使用SQLite在Android應用程式內

創建資料庫:
必須先建立一個SQLiteOpenHelper的class類別

package jim.memorandum;

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

public class NewListDataSQL extends SQLiteOpenHelper {

         //資料庫版本關係到App更新時,資料庫是否要調用onUpgrade()
  private static final int VERSION = 1;//資料庫版本  
  
                //建構子
  public NewListDataSQL(Context context, String name, CursorFactory factory,int version) {
   super(context, name, factory, version);
  }

  public NewListDataSQL(Context context,String name) { 
   this(context, name, null, VERSION); 
   } 
  
   public NewListDataSQL(Context context, String name, int version) {  
    this(context, name, null, version);  
      }  
   
  //輔助類建立時運行該方法
  @Override
  public void onCreate(SQLiteDatabase db) {
   String DATABASE_CREATE_TABLE =
     "create table newMemorandum("
       + "_ID INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL,"
             + "date VARCHAR,"
             + "note VARCHAR,"
             + "pw VARCHAR,"
             + "reminder INT,"
             + "type VARCHAR,"
             + "memo VARCHAR"
         + ")";
            db.execSQL(DATABASE_CREATE_TABLE);
  }

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
   //oldVersion=舊的資料庫版本;newVersion=新的資料庫版本
   db.execSQL("DROP TABLE IF EXISTS newMemorandum"); //刪除舊有的資料表
   onCreate(db);
  }
  
  @Override    
   public void onOpen(SQLiteDatabase db) {     
           super.onOpen(db);       
           // TODO 每次成功打開數據庫後首先被執行     
       } 

   @Override
        public synchronized void close() {
            super.close();
        }

}

當你在activity中調用建構子NewListDataSQL時,程式自己會去判斷databases資料夾中是否有此db檔,如果沒有就會調用onCreate()建立此SQLite資料庫,所以要建立的Table就寫在onCreate()裡面,寫法跟一般SQL的寫法是一樣的。

Activity中呼叫資料庫

package jim.memorandum;
//import進兩個database需要用到的
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;


public class MemorandumActivity extends Activity {
               //SQLiteDatabase對象
          SQLiteDatabase db;
  //資料庫名
  public String db_name = "MemorandumSQL";
  
  //表名
  public String table_name = "newMemorandum";

  //輔助類名
  NewListDataSQL helper = new NewListDataSQL(MemorandumActivity.this, db_name);



                @Override
                public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
        
                //以輔助類獲得資料庫對象
    db = helper.getReadableDatabase();

注意:一個應用程式只允許對應一個db檔,所以資料庫名稱新增後就不能修改,不然程式會自動創立另一個db檔。

資料庫查詢指令

 
        //取得備忘資料
   public String[] myNote(){
    
    Cursor cursor = db.rawQuery("select note from newMemorandum ORDER BY _ID DESC", null);
    //用陣列存資料
    String[] sNote = new String[cursor.getCount()];
    
    int rows_num = cursor.getCount();//取得資料表列數
    if(rows_num != 0) {
     cursor.moveToFirst();   //將指標移至第一筆資料
     for(int i=0; i<rows_num; i++) {
      String strCr = cursor.getString(0);
      sNote[i]=strCr;
      
      cursor.moveToNext();//將指標移至下一筆資料
     }
    }
    cursor.close(); //關閉Cursor
    //dbHelper.close();//關閉資料庫,釋放記憶體,還需使用時不要關閉
    

    return sNote;
   }

我是寫個function去資料庫中查詢資料,"_ID"是PRIMARY KEY

基本上SQLite資料庫應用的建立及查詢就是這樣而已,還蠻簡單的,後面再介紹新增、修改、刪除的資料庫操作。




複製請註明出處,Android 手機資料庫(一) - SQLite  基本介紹、創建及查詢,謝謝。