<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                Android系統內建“SQLite”數據庫,它是一個開放的小型數據庫,它跟一般商用的大型數據庫有類似的架構與用法,例如MySQL數據庫。應用程式可以建立自己需要的數據庫,在數據庫中使用Android API執行資料的管理和查詢的工作。儲存資料的數量是根據裝置的儲存空間決定的,所以如果空間足夠的話,應用程式可以儲存比較大量的資料,在需要的時候隨時可以執行數據庫的管理和查詢的工作。 一般商用的大型數據庫,可以提供快速存取與儲存非常大量的資料,也包含網絡通訊和復雜的存取權限管理,不過它們都會使用一種共通的語言“SQL”,不同的數據庫產品都可以使用SQL這種數據庫語言,執行資料的管理和查詢的工作。SQLite數據庫雖然是一個小型數據庫,不過它跟一般大型數據庫的架構與用法也差不多,同樣可以使用SQL執行需要的工作,Android另外提供許多數據庫的API,讓開發人員使用API執行數據庫的工作。 這一章會從了解應用程式數據庫的需求開始,介紹如何建立數據庫與表格,在應用程式運作的過程中,如何執行數據庫的新增、修改、刪除與查詢的工作。 ## 11-1 設計數據庫表格 在數據庫的技術中,一個數據庫(Database)表示應用程式儲存與管理資料的單位,應用程式可能需要儲存很多不同的資料,例如一個購物網站的數據庫,就需要儲存與管理會員、商品和訂單資料。每一種在數據庫中的資料稱為表格(Table),例如會員表格可以儲存所有的會員資料。 SQLite 數據庫的架構也跟一般數據庫的概念類似,所以應用程式需要先建立好需要的數據庫與表格后,才可以執行儲存與管理資料的工作。建立表格是在Android應用程式中,唯一需要使用SQL執行的工作。其它執行數據庫管理與查詢的工作,Android都提供執行各種功能的API,使用這些API就不需要了解太多SQL這種數據庫語言。 建立數據庫表格使用SQL的“CREATE TABLE”指令,這個指令需要指定表格的名稱,還有這個表格用來儲存每一筆資料的字段(Column)。這些需要的表格字段可以對應到主要類別中的字段變量,不過SQLite數據庫的資料型態只有下面這幾種,使用它們來決定表格字段可以儲存的資料型態: * INTEGER – 整數,對應Java 的byte、short、int 和long。 * REAL – 小數,對應Java 的float 和double。 * TEXT – 字串,對應Java 的String。 在設計表格字段的時候,需要設定字段名稱和型態,表格字段的名稱建議就使用主要類別中的字段變量名稱。表格字段的型態依照字段變量的型態,把它們轉換為SQLite提供的資料型態。通常在表格字段中還會加入“NOT NULL”的指令,表示這個表格字段不允許空值,可以避免資料發生問題。 表格的名稱可以使用主要類別的類別名稱,一個SQLite表格建議一定要包含一個可以自動為資料編號的字段,字段名稱固定為“_id”,型態為“INTEGER”,后面加上“PRIMARY KEY AUTOINCREMENT”的設定,就可以讓SQLite自動為每一筆資料編號以后儲存在這個字段。 ## 11-2 建立SQLiteOpenHelper類別 Android 提供許多方便與簡單的數據庫API,可以簡化應用程式處理數據庫的工作。這些API都在“android.database.sqlite”套件,它們可以用來執行數據庫的管理和查詢的工作。在這個套件中的“SQLiteOpenHelper”類別,可以在應用程式中執行建立數據庫與表格的工作,應用程式第一次在裝置執行的時候,由它負責建立應用程式需要的數據庫與表格,后續執行的時候開啟已經建立好的數據庫讓應用程式使用。還有應用程式在運作一段時間以后,如果增加或修改功能,數據庫的表格也增加或修改了,它也可以為應用程式執行數據庫的修改工作,讓新的應用程式可以正常的運作。 接下來設計建立數據庫與表格的類別,在“net.macdidi.myandroidtutorial”套件按鼠標右鍵,選擇“New -> Java CLass”,在Name輸入“MyDBHelper”后選擇“OK”。參考下列的內容先完成部份的程式碼: ~~~ package net.macdidi.myandroidtutorial; 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 final int VERSION = 1; // 數據庫物件,固定的字段變量 private static SQLiteDatabase database; // 建構子,在一般的應用都不需要修改 public MyDBHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); } // 需要數據庫的元件呼叫這個方法,這個方法在一般的應用都不需要修改 public static SQLiteDatabase getDatabase(Context context) { if (database == null || !database.isOpen()) { database = new MyDBHelper(context, DATABASE_NAME, null, VERSION).getWritableDatabase(); } return database; } @Override public void onCreate(SQLiteDatabase db) { // 建立應用程式需要的表格 // 待會再回來完成它 } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 刪除原有的表格 // 待會再回來完成它 // 呼叫onCreate建立新版的表格 onCreate(db); } } ~~~ ## 11-3 數據庫功能類別 在Android應用程式中使用數據庫功能通常會有一種狀況,就是Activity或其它元件的程式碼,會因為加入處理數據庫的工作,程式碼變得又多、又復雜。一般程式設計的概念,一個元件中的程式碼如果很多的話,在撰寫或修改的時候,都會比較容易出錯。所以這里說明的作法,會采用在一般應用程式中執行數據庫工作的設計方式,把執行數據庫工作的部份寫在一個獨立的Java類別中。 接下來設計應用程式需要的數據庫功能類別,提供應用程式與數據庫相關功能。在“net.macdidi.myandroidtutorial”套件按鼠標右鍵,選擇“New -> Java CLass”,在Name輸入“ItemDAO”后選擇“OK”。參考下列的內容先完成部份的程式碼: ~~~ package net.macdidi.myandroidtutorial; import java.util.ArrayList; import java.util.Date; import java.util.List; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; // 資料功能類別 public class ItemDAO { // 表格名稱 public static final String TABLE_NAME = "item"; // 編號表格字段名稱,固定不變 public static final String KEY_ID = "_id"; // 其它表格字段名稱 public static final String DATETIME_COLUMN = "datetime"; public static final String COLOR_COLUMN = "color"; public static final String TITLE_COLUMN = "title"; public static final String CONTENT_COLUMN = "content"; public static final String FILENAME_COLUMN = "filename"; public static final String LATITUDE_COLUMN = "latitude"; public static final String LONGITUDE_COLUMN = "longitude"; public static final String LASTMODIFY_COLUMN = "lastmodify"; // 使用上面宣告的變量建立表格的SQL指令 public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + DATETIME_COLUMN + " INTEGER NOT NULL, " + COLOR_COLUMN + " INTEGER NOT NULL, " + TITLE_COLUMN + " TEXT NOT NULL, " + CONTENT_COLUMN + " TEXT NOT NULL, " + FILENAME_COLUMN + " TEXT, " + LATITUDE_COLUMN + " REAL, " + LONGITUDE_COLUMN + " REAL, " + LASTMODIFY_COLUMN + " INTEGER)"; // 數據庫物件 private SQLiteDatabase db; // 建構子,一般的應用都不需要修改 public ItemDAO(Context context) { db = MyDBHelper.getDatabase(context); } // 關閉數據庫,一般的應用都不需要修改 public void close() { db.close(); } // 新增參數指定的物件 public Item insert(Item item) { // 建立準備新增資料的ContentValues物件 ContentValues cv = new ContentValues(); // 加入ContentValues物件包裝的新增資料 // 第一個參數是字段名稱, 第二個參數是字段的資料 cv.put(DATETIME_COLUMN, item.getDatetime()); cv.put(COLOR_COLUMN, item.getColor().parseColor()); cv.put(TITLE_COLUMN, item.getTitle()); cv.put(CONTENT_COLUMN, item.getContent()); cv.put(FILENAME_COLUMN, item.getFileName()); cv.put(LATITUDE_COLUMN, item.getLatitude()); cv.put(LONGITUDE_COLUMN, item.getLongitude()); cv.put(LASTMODIFY_COLUMN, item.getLastModify()); // 新增一筆資料并取得編號 // 第一個參數是表格名稱 // 第二個參數是沒有指定字段值的默認值 // 第三個參數是包裝新增資料的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(DATETIME_COLUMN, item.getDatetime()); cv.put(COLOR_COLUMN, item.getColor().parseColor()); cv.put(TITLE_COLUMN, item.getTitle()); cv.put(CONTENT_COLUMN, item.getContent()); cv.put(FILENAME_COLUMN, item.getFileName()); cv.put(LATITUDE_COLUMN, item.getLatitude()); cv.put(LONGITUDE_COLUMN, item.getLongitude()); cv.put(LASTMODIFY_COLUMN, item.getLastModify()); // 設定修改資料的條件為編號 // 格式為“字段名稱=資料” 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 getAll() { List result = new ArrayList<>(); Cursor cursor = db.query( TABLE_NAME, null, null, null, null, null, null, null); 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.setDatetime(cursor.getLong(1)); result.setColor(ItemActivity.getColors(cursor.getInt(2))); result.setTitle(cursor.getString(3)); result.setContent(cursor.getString(4)); result.setFileName(cursor.getString(5)); result.setLatitude(cursor.getDouble(6)); result.setLongitude(cursor.getDouble(7)); result.setLastModify(cursor.getLong(8)); // 回傳結果 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, new Date().getTime(), Colors.RED, "關于Android Tutorial的事情.", "Hello content", "", 0, 0, 0); Item item2 = new Item(0, new Date().getTime(), Colors.BLUE, "一只非常可愛的小狗狗!", "她的名字叫“大熱狗”,又叫\n作“奶嘴”,是一只非常可愛\n的小狗。", "", 25.04719, 121.516981, 0); Item item3 = new Item(0, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", 0, 0, 0); Item item4 = new Item(0, new Date().getTime(), Colors.ORANGE, "儲存在數據庫的資料", "Hello content", "", 0, 0, 0); insert(item); insert(item2); insert(item3); insert(item4); } } ~~~ 完成數據庫功能類別以后,里面也宣告了一些SQLiteOpenHelper類別會使用到的資料,開啟“MyDBHelper”類別,完成之前還沒有完成的工作: ~~~ @Override public void onCreate(SQLiteDatabase db) { // 建立應用程式需要的表格 db.execSQL(ItemDAO.CREATE_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 刪除原有的表格 db.execSQL("DROP TABLE IF EXISTS " + ItemDAO.TABLE_NAME); // 呼叫onCreate建立新版的表格 onCreate(db); } ~~~ ## 11-4 使用數據庫中的記事資料 完成與數據庫相關的類別以后,其它的部份就簡單多了,Activity元件也可以保持比較簡潔的程式架構。開啟在“net.macdidi.myandroidtutorial”套件下的“MainActivity”類別,修改原來自己建立資料的作法,改由數據庫提供記事資料并顯示在畫面。由于所有執行數據庫工作的程式碼都寫在“ItemDAO”類別,所以要宣告一個ItemDAO的字段變量,“onCreate”方法也要執行相關的修改: ~~~ // 宣告數據庫功能類別字段變量 private ItemDAO itemDAO; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); processViews(); processControllers(); // 建立數據庫物件 itemDAO = new ItemDAO(getApplicationContext()); // 如果數據庫是空的,就建立一些范例資料 // 這是為了方便測試用的,完成應用程式以后可以拿掉 if (itemDAO.getCount() == 0) { itemDAO.sample(); } // 取得所有記事資料 items = itemDAO.getAll(); itemAdapter = new ItemAdapter(this, R.layout.single_item, items); item_list.setAdapter(itemAdapter); } ~~~ 完成這個部份的修改以后,執行應用程式,如果畫面上顯示像這樣的畫面,數據庫的部份應該就沒有問題了。 [![AndroidTutorial5_03_03_01](http://www.codedata.com.tw/wp-content/uploads/2015/02/AndroidTutorial5_03_03_01-190x300.png)](http://www.codedata.com.tw/wp-content/uploads/2015/02/AndroidTutorial5_03_03_01.png) 接下來需要處理新增與修改的部份,同樣在“MainActivity”類別,找到“onActivityResult”方法,參考下列的內容修改程式碼: ~~~ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { Item item = (Item) data.getExtras().getSerializable( "net.macdidi.myandroidtutorial.Item"); if (requestCode == 0) { // 新增記事資料到數據庫 item = itemDAO.insert(item); items.add(item); itemAdapter.notifyDataSetChanged(); } else if (requestCode == 1) { int position = data.getIntExtra("position", -1); if (position != -1) { // 修改數據庫中的記事資料 itemDAO.update(item); items.set(position, item); itemAdapter.notifyDataSetChanged(); } } } } ~~~ 最后是刪除記事資料的部份,同樣在“MainActivity”類別,找到“clickMenuItem”方法,參考下列的內容修改程式碼: ~~~ public void clickMenuItem(MenuItem item) { int itemId = item.getItemId(); switch (itemId) { ... case R.id.delete_item: if (selectedCount == 0) { break; } AlertDialog.Builder d = new AlertDialog.Builder(this); String message = getString(R.string.delete_item); d.setTitle(R.string.delete) .setMessage(String.format(message, selectedCount)); d.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 取得最后一個元素的編號 int index = itemAdapter.getCount() - 1; while (index > -1) { Item item = itemAdapter.get(index); if (item.isSelected()) { itemAdapter.remove(item); // 刪除數據庫中的記事資料 itemDAO.delete(item.getId()); } index--; } itemAdapter.notifyDataSetChanged(); } }); d.setNegativeButton(android.R.string.no, null); d.show(); break; case R.id.googleplus_item: break; case R.id.facebook_item: break; } } ~~~ 完成這一章所有的工作了,執行應用程式,試試看新增、修改和刪除記事資料的功能。因為記事資料都保存在數據庫,完成測試以后,關閉應用程式再重新啟動,記事資料還是會顯示在畫面。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看