SQLite資料庫是android系統內嵌的資料庫,小巧強大,能夠滿足大多數SQL語句的處理工作,而SQLite資料庫僅僅是個檔案而已。雖然SQLite的有點很多,但並不是如同PC端的mysql般強大,而且android系統中不允許通過JDBC操作遠端資料庫,所以只能通過webservice等手段於php、servlet互動擷取資料。
基礎
SQLiteDatabase類,代表了一個資料庫物件,通過SQLiteDatabase來操作管理資料庫。
一些基本的用法:
- static SQLiteDatabase openDatabase(String path,SQLiteDatabase.CUrsorFactory factory,int flag);
- static SQLiteDatabase openOrCreateDatabase(File file,SQLiteDatabase.CursorFactory factory);
- static SQLiteDatabase openOrCreateDatabase(String path,SQLiteDatabse.CursorFactory factory);
通過這些靜態方法可以很方便的開啟和建立一個資料庫。
- execSQL(String sql,Object[] bindArgs)
- execSQL(String sql)
- rawQuery(String sql,String[] selectionArgs);
- beginTransaction()
- endTransaction()
這些函數可以完成SQL功能,對於查詢出來的結果是用Cursor表示的,類似於JDBC中的ResultSet類,在這些類中通過方法move(int offset)、moveToFirst()、moveToLast()、moveToNext()、moveToPosition(int position)、moveToPrivious()擷取需要的結果行。
下面通過一個執行個體來說明一下SQLiteDatabase的基本使用:
main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".Main" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="key" /> <EditText android:id="@+id/keys" android:layout_width="100sp" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="value" /> <EditText android:id="@+id/values" android:layout_width="100sp" android:layout_height="wrap_content" /> <Button android:id="@+id/btn" android:layout_width="100sp" android:layout_height="wrap_content" android:text="submit" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout>
用於填充資料的mytextview.xml:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/listkey" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" /> <TextView android:id="@+id/listvalue" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="300sp" /> </LinearLayout>
Main.java
package com.app.main; import android.annotation.SuppressLint;import android.app.Activity;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.CursorAdapter;import android.widget.EditText;import android.widget.ListView;import android.widget.SimpleCursorAdapter; public class Main extends Activity { EditText ed1 = null; EditText ed2 = null; Button btn = null; ListView lv = null; SQLiteDatabase db = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ed1 = (EditText) this.findViewById(R.id.keys); ed2 = (EditText) this.findViewById(R.id.values); btn = (Button) this.findViewById(R.id.btn); lv = (ListView) this.findViewById(R.id.lv); db = SQLiteDatabase.openOrCreateDatabase(this.getFilesDir().toString() + "/my.db3", null); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { String key = ed1.getText().toString(); String value = ed2.getText().toString(); try { insertData(db, key, value); Cursor cursor = db.rawQuery("select * from tb_info", null); inflateListView(cursor); } catch (Exception e) { String sql = "create table tb_info(_id integer primary key autoincrement,db_key varchar(20),db_value varchar(50))"; db.execSQL(sql); insertData(db, key, value); Cursor cursor = db.rawQuery("select * from tb_info", null); inflateListView(cursor); } } }); } // 向資料庫中插入資料 private void insertData(SQLiteDatabase db, String key, String value) { db.execSQL("insert into tb_info values (null,?,?)", new String[] { key, value }); System.out.println("------------------"); } // 向ListView中填充資料 @SuppressLint("NewApi") public void inflateListView(Cursor cursor) { SimpleCursorAdapter adapter = new SimpleCursorAdapter(Main.this, R.layout.mytextview, cursor, new String[] { "db_key", "db_value" }, new int[] { R.id.listkey, R.id.listvalue }, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); lv.setAdapter(adapter); } @Override protected void onDestroy() { super.onDestroy(); if (db != null && db.isOpen()) { db.close(); } } }
實現的效果:
需要特別指出,在用SimpleCursorAdapter封裝Cursor的時候,要求底層資料庫表的主鍵列的列名為_id,因為SimpleCursorAdapter只能識別主鍵列名為_id的表。
進階
直接使用SQLiteDatabase的openOrCreateDatabase可以直接開啟或者是建立一個SQLiteDatabase,但是這裡存在一個缺點。在每次執行SQL語句的時候都需要在try catch語句中進行,如果在try中直接操作的資料庫或者表不存在,就需要在catch中重新建立表並且執行CRUD操作,並且有關資料庫的每一個方法都要這麼做,重複的代碼太多了,所以實際的開發中大都選用SQLiteOpenHelper類。
主要方法:
- synchronized SQLiteDatabase getReadableDatabase():以讀寫的方式開啟資料庫。
- synchronized SQLiteDatabase getWritableDatabase();以寫的方式開啟資料庫。
- abstract void onCreate(SQLiteDatabase db) 當第一次建立資料庫的時候回調該方法。
- abstract void onUprade(SQLiteDatabase db,int oldversion,int newVersion) 資料庫版本更新的時候回調該方法。
- abstract void close() 關閉所有開啟的SQLiteDatabase.
使用方法:
1)繼承SQLiteOpenHelper。在構造方法中的參數String name就是資料庫的名稱。
2)重寫onCreate和onUpgrade方法。
MySQLiteOpenHelper類:
package com.app.db; import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper; public class MySQLiteOpenHelper extends SQLiteOpenHelper { String createSQL = "create table tb_test(_id integer primary key autoincrement ,name,age )"; public MySQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(createSQL); } @Override public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) { } }
Main.java
package com.app.main; import android.app.Activity;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.os.Bundle;import android.view.Menu;import android.widget.Toast; import com.app.db.MySQLiteOpenHelper; public class Main extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); MySQLiteOpenHelper helper = new MySQLiteOpenHelper(this, "my.db3", null, 1); String insertSQL = "insert into tb_test values(null,'wx',18)"; SQLiteDatabase db = helper.getReadableDatabase(); db.execSQL(insertSQL); Cursor cursor = db.rawQuery("select * from tb_test", null); cursor.moveToFirst(); int id = cursor.getInt(0); Toast.makeText(this, id+"",Toast.LENGTH_SHORT).show(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } }
實現效果: