Android SQLite資料庫使用,androidsqlite

來源:互聯網
上載者:User

Android SQLite資料庫使用,androidsqlite

  又是一段時間過去了,堅持不是說說而已啊,表示UC瀏覽器電腦版一堆小bug,真是受不了啊。雖然有些小功能做的很人性化。

  SQLite作為系統內預設的資料庫,作為平常儲存一些資料來說是足夠了。並且也有對應的api來進行操作還是很方便的。官方的推薦是使用類加上SQLiteOpenHelper來對資料庫進行管理。將表中的欄位當做類的成員屬性,並讓表結構這個類實現BaseColumns,該介面中有_COUNT和_ID兩個欄位。_COUNT是系統統計所有的行。_ID是每一行的獨特id。這裡我要設計一個儲存每次定位資訊的一個表。對應的類為LocinfoTable.java.

  

 1 package com.example.sqlitetest.db; 2  3 import android.provider.BaseColumns; 4  5 public final class Locinfo { 6     private static final String SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS " 7             + LocinfoTable.TABLE_NAME; 8  9     public static abstract class LocinfoTable implements BaseColumns {10         //定位資訊表,某一次定位的基本資料11         public static final String TABLE_NAME = "locinfo";12         //記錄是第幾次定位13         public static final String COLUMN_NAME_LOC_COUNT = "LOC_COUNT";14         //起始位置經度,即起點的經度15         public static final String COLUMN_NAME_START_LONGITUDE = "START_LONGITUDE";16         //起始位置緯度,即起點的緯度17         public static final String COLUMN_NAME_START_LATITUDE = "START_LATITUDE";18         //結束位置經度,即起點的緯度19         public static final String COLUMN_NAME_END_LONGITUDE = "END_LONGITUDE";20         //結束位置緯度,即起點的緯度21         public static final String COLUMN_NAME_END_LATITUDE = "END_LATITUDE";22         //起始位置的時間23         public static final String COLUMN_NAME_START_TIME = "START_TIME";24         //結束位置的時間25         public static final String COLUMN_NAME_END_TIME = "END_TIME";26         //起點到終點的距離27         public static final String COLUMN_NAME_DISTANCE = "DISTANCE";28         //本次定位的類型29         public static final String COLUMN_NAME_LOCTYPE = "LOCTYPE";30         //備忘資訊31         public static final String COLUMN_NAME_REMARKS = "REMARKS";32     }33 }

  有了資料庫表的結構,接下來就是對資料庫進行管理。按照官方的推薦,要繼承SQLiteOpenHelper,並重新寫其建構函式。SQLiteOpenHelper中主要有兩個函數需要重點注意,也是繼承後必須實現的。分別是onCreate,onUpgrade。onCreat函數在資料庫沒有建立時調用,即建立資料庫時會調用該函數,onUpgrade函數則是在資料庫版本進行升級時調用,常見的資料庫升級比如修改表結構等。並且在繼承SQLiteOpenHelper時必須添加以下建構函式

  

public LocinfoDBHelper(Context context, String name, CursorFactory factory,            int version) {        super(context, name, factory, version);    }

  咋一看好像函數非常多,不過我們真要建立資料庫時其實不用這麼麻煩,所以我們可以再寫一個建構函式來重載。上下文環境是必須的,還有資料庫名字是必須的,所以可以重載一個只有兩個參數的建構函式

1 public LocinfoDBHelper(Context context, String dbname) 

  那麼我們來看看這個SQLiteOpenhelper都有什麼方法來讓我們方便的操作資料庫。

函數名 函數說明
public synchronized void close () 關閉任何一個已開啟的資料庫
public String getDatabaseName () 擷取當前一開啟的資料庫的名字
public SQLiteDatabase getReadableDatabase () 擷取一個可讀的資料庫執行個體,如果想要擷取的資料庫執行個體不存在則會建立一個資料庫。
public SQLiteDatabase getWritableDatabase () 擷取一個可寫的資料庫執行個體,同上,如果不存在則建立。
public abstract void onCreate (SQLiteDatabase db) 在第一次建立資料庫時調用,通常將建表語句放在這裡。
public void onDowngrade (SQLiteDatabase db, int oldVersion, int newVersion) 資料庫版本降級是時調用,通常較少使用。
public abstract void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) 資料庫版本升級時使用,比如更新表結構時。

 

  看了上面的函數之後大概有個瞭解了。SQLiteOpenHelper只是提供一個資料庫管理的類,最後操作資料庫是還是通過其getWritableDatabase ()返回的SQLiteDataBase來進行操作。

  於是我們再來看看這個SQLiteDataBase類。對於資料庫來說,最基本的當然是增刪改查這類DML語句,所以我們來著重講講這些API是怎麼麼使用的。

  1.插入函數:

public long insert (String table, String nullColumnHack, ContentValues values)Added in API level 1Convenience method for inserting a row into the database.Parameterstable//表名    the table to insert the row intonullColumnHack//通常為null    optional; may be null. SQL doesn't allow inserting a completely empty row without naming at least one column name. If your provided values is empty, no column names are known and an empty row can't be inserted. If not set to null, the nullColumnHack parameter provides the name of nullable column name to explicitly insert a NULL into in the case where your values is empty.values//要插入的欄位和其值    this map contains the initial column values for the row. The keys should be the column names and the values the column valuesReturnsthe row ID of the newly inserted row, or -1 if an error occurred

  2.更新操作

public int update (String table, ContentValues values, String whereClause, String[] whereArgs)Added in API level 1Convenience method for updating rows in the database.Parameterstable//表名    the table to update invalues//要更新的欄位和其屬性群組成的映射    a map from column names to new column values. null is a valid value that will be translated to NULL.whereClause//where子句    the optional WHERE clause to apply when updating. Passing null will update all rows.whereArgs//wehere條件,用來替換子句中的"?"    You may include ?s in the where clause, which will be replaced by the values from whereArgs. The values will be bound as Strings.Returnsthe number of rows affected

  3.查詢操作

  

public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)Added in API level 1Query the given table, returning a Cursor over the result set.Parameterstable//表名    The table name to compile the query against.columns//希望查詢的列名    A list of which columns to return. Passing null will return all columns, which is discouraged to prevent reading data from storage that isn't going to be used.selection//查詢子句,相當於where中的欄位名    A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given table.selectionArgs//查詢條件    You may include ?s in selection, which will be replaced by the values from selectionArgs, in order that they appear in the selection. The values will be bound as Strings.groupBy//排序欄位    A filter declaring how to group rows, formatted as an SQL GROUP BY clause (excluding the GROUP BY itself). Passing null will cause the rows to not be grouped.having//    A filter declare which row groups to include in the cursor, if row grouping is being used, formatted as an SQL HAVING clause (excluding the HAVING itself). Passing null will cause all row groups to be included, and is required when row grouping is not being used.orderBy//排序欄位    How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.limit//返回的    Limits the number of rows returned by the query, formatted as LIMIT clause. Passing null denotes no LIMIT clause.Returns//傳回值是遊標對象,通過遊標來對返回的記錄逐行進行操作A Cursor object, which is positioned before the first entry. Note that Cursors are not synchronized, see the documentation for more details.

  4.刪除函數

  

public int delete (String table, String whereClause, String[] whereArgs)Added in API level 1Convenience method for deleting rows in the database.Parameterstable//表名    the table to delete fromwhereClause//where子句中欄位部分    the optional WHERE clause to apply when deleting. Passing null will delete all rows.whereArgs//where子句條件    You may include ?s in the where clause, which will be replaced by the values from whereArgs. The values will be bound as Strings.Returnsthe number of rows affected if a whereClause is passed in, 0 otherwise. To remove all rows and get a count pass "1" as the whereClause.

  經過上面的幾個函數我們能看出來API是將原來的sql語句中的每一段拆成一個參數,能基本滿足一些簡單的查詢。但是如果複雜的語句怎麼處理呢,所以就提供了一個原始的方法,即直接執行sql語句的函數(這個也是有局限的,不過在手機上一般不會有什麼複雜的sql語句,畢竟手機也不是伺服器):

public void execSQL (String sql)Added in API level 1Execute a single SQL statement that is NOT a SELECT or any other SQL statement that returns data.//執行的只能是不要求返回資料的sql語句It has no means to return any data (such as the number of affected rows). Instead, you're encouraged to use insert(String, String, ContentValues), update(String, ContentValues, String, String[]), et al, when possible.When using enableWriteAheadLogging(), journal_mode is automatically managed by this class. So, do not set journal_mode using "PRAGMA journal_mode'" statement if your app is using enableWriteAheadLogging()Parameterssql    the SQL statement to be executed. Multiple statements separated by semicolons are not supported.ThrowsSQLException//sql異常    if the SQL string is invalid

  介紹了上面的這些函數的使用方法,接下來我們來看看一些我學習時遇到的問題:

  如果資料庫欄位太多,我們往往容易寫錯欄位名或者欄位類型。那麼這個時候就要刪除表再重新來建表,在這個時候就會觸發onUpgrade函數,資料庫的version就會升級,如果我們此時繼續用version=1作為參數去擷取協助類的執行個體,然後通過這個執行個體去擷取資料庫物件進行資料庫操作,就會報錯:

android.database.sqlite.SQLiteException: Can't downgrade database from version 2 to 1
 所以我們需要去把version也升級到2.但是這樣手動升級感覺很不合適,每次要是更新一下就去升級,豈不是很麻煩,所以我想去通過sharedpreferences記住這個version,每次需要的時候去取出來,並且如果資料庫發生更新,則在onUpgrade函數中更新sharedpreferences中的version。

  擴充知識:

  SQLite基礎資料型別 (Elementary Data Type)

    1.NULL:空值。
    2.INTEGER:帶符號的整型,具體取決有存入數位範圍大小。
    3.REAL:浮點數字,儲存為8-byte IEEE浮點數。
    4.TEXT:字串文本。
    5.BLOB:二進位對象。

  怎麼查看Android模擬器中的sqlite資料庫:

  1.在cmd中進入模擬器:adb shell 或者指定裝置名稱。

  

  2.進入應用程式的目錄下:cd /data/data/application package name

  

  3.可以看到連個檔案夾,那個databases自然就是我們需要的,進去,然後sqlite3 database_name 

  

  4.接下來就可以進行一些常用的操作了。比如: .schema,select

  

  不知不覺一下午又快沒了,寫部落格果然很要時間。看別人的部落格和自己寫完全是兩回事啊,藉此不斷鞭策自己吧。如果您有什麼問題可以一起討論。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.