Android入門筆記之Sqlite
<1>簡介
SQLite是D.Richard Hipp用C語言編寫的開源嵌入式數據庫引擎。它支持大多數的SQL92標準,並且可以在所有主要的操作系統上運行。
SQLite由以下幾個部分組成:SQL編譯器、內核、後端以及附件。SQLite通過利用虛擬機和虛擬數據庫引擎(VDBE),是調試、修改和擴展SQLite的內核變得更加方便。所有SQL語句都被編譯成易讀的、可以在SQLite虛擬機中執行的程序集。
值得一提的是,袖珍型的SQLite竟然可以支持高達2TB大小的數據庫,每個數據庫都是以單個文件的形式存在,這些數據都是以B-Tree的數據結構形式存儲在磁盤上。
在事務處理方面,SQLite通過數據庫級上的獨佔性和共享鎖來實現獨立事務處理。這意味着多個進程可以在同一時間從同一數據庫讀取數據,但只有一個可以寫入數據。在某個進程或線程想數據庫執行寫操作之前,必須獲得獨佔鎖。在獲得獨佔鎖之後,其他的讀或寫操作將不會再發生。
SQLite採用動態數據類型,當某個值插入到數據庫時,SQLite將會檢查它的類型,如果該類型與關聯的列不匹配,SQLite則會嘗試將該值轉換成該列的類型,如果不能轉換,則該值將作爲本身的類型存儲,SQLite稱這爲“弱類型”。但有一個特例,如果是INTEGER PRIMARY KEY,則其他類型不會被轉換,會報一個“datatype missmatch”的錯誤。
概括來講,SQLite支持NULL、INTEGER、REAL、TEXT和BLOB數據類型,分別代表空值、整型值、浮點值、字符串文本、二進制對象。
<2>關鍵步驟
一、 創建數據庫
通過openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory factory)方法創建數據庫。
iteDatabase db=this.openOrCreateDatabase("test_db.db",
Context.MODE_PRIVATE, null);
或者SQLiteDatabasedb2 =
SQLiteDatabase.openOrCreateDatabase("/data/data/com.test/databases/test_db2.db3",null);
如上兩種方式均能創建數據庫,this.openOrCreateDatabase是對SQLiteDatabase.openOrCreateDatabase而來,如代碼所見,原生的SQLiteDatabase.openOrCreateDatabase()方法第一參數要求輸入絕對路勁,而所有的數據庫都是儲存於“data/data/應用報名/databases”目錄下,所以輸入完全的絕對路勁是一件重複且繁雜的工作。採用this.openOrCreateDatabase則省去了此操作。
另外還可以通過寫一個繼承SQLiteOpenHelper類的方式創建數據庫,此種方式是一種更加進階的創建方式。
SQLiteOpenHelper的使用方法
SQLiteOpenHelper是一個輔助類來管理數據庫的創建和版本。
可以通過繼承這個類,實現它的一些方法來對數據庫進行一些操作。
所有繼承了這個類的類都必須實現下面這樣的一個構造方法:
public DatabaseHelper(Context context, Stringname, CursorFactory factory, int version)
第一個參數:Context類型,上下文對象。
第二個參數:String類型,數據庫的名稱
第三個參數:CursorFactory類型
第四個參數:int類型,數據庫版本
下面是這個類的幾個方法:
方法名 返回類型 描述 備註
getReadableDatabase() synchronized SQLiteDatabase 創建或打開一個數據庫可以通過這兩個方法返回的SQLiteDatabase對象對數據庫進行一系列的操作,如新建一個表,插入一條數據等
getWritableDatabase() synchronized SQLiteDatabase 創建或打開一個可以讀寫的數據庫
onCreate(SQLiteDatabase db) abstract void 第一次創建的時候調用
onOpen(SQLiteDatabase db) void 打開數據庫
onUpgrade(SQLiteDatabase db,int oldVersion,intnewVersion) abstract void 升級數據庫
close() synchronized void 關閉所有打開的數據庫對象
<3>出現的問題
可從DDMS中導出db文件。
<4>代碼及解釋
Activity_sqlite.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/dbcreate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="create" />
<Button
android:id="@+id/dbupgrade"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="upgrade" />
<Button
android:id="@+id/dbinsert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="insert" />
<Button
android:id="@+id/dbdelete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="delete" />
<Button
android:id="@+id/dbselect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="select" />
<Button
android:id="@+id/dbupdate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="update" />
<TextView
android:id="@+id/dbview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="view" />
</LinearLayout>
SqliteActivity.java:
package com.func;
import android.app.Activity;
import android.content.ContentValues;
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.TextView;
import com.test.R;
public class SqliteActivity extends Activity{
/**
* @ProjectName: [androidtest]
* @Package: [com.func.SqliteActivity.java]
* @ClassName: [SqliteActivity]
* @Description:
* @Author: [gmj]
* @CreateDate: [2013-9-7 下午8:00:49]
* @Version: [v1.0]
*/
private Button createDatabaseButton = null;
private Button updateDatabaseButton = null;
private Button insertButton = null;
private Button updateButton = null;
private Button selectButton = null;
private Button deleteButton = null;
private TextView tv = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sqlite);
createDatabaseButton = (Button) findViewById(R.id.dbcreate);
updateDatabaseButton = (Button) findViewById(R.id.dbupgrade);
insertButton = (Button) findViewById(R.id.dbinsert);
updateButton = (Button) findViewById(R.id.dbupdate);
selectButton = (Button) findViewById(R.id.dbselect);
deleteButton = (Button) findViewById(R.id.dbdelete);
tv = (TextView) findViewById(R.id.dbview);
createDatabaseButton.setOnClickListener(new CreateDatabaseOnClickListener());
updateDatabaseButton.setOnClickListener(new UpdateDatabaseOnClickListener());
insertButton.setOnClickListener(new InsertOnClickListener());
updateButton.setOnClickListener(new UpdateOnClickListener());
selectButton.setOnClickListener(new SelectOnClickListener());
deleteButton.setOnClickListener(new DeleteOnClickListener());
}
class CreateDatabaseOnClickListener implements OnClickListener {
public void onClick(View v) {
// 創建了一個DatabaseHelper對象,只執行這句話是不會創建或打開連接的
SqliteHelper dbHelper = new SqliteHelper(SqliteActivity.this , "test_db");
SQLiteDatabase sqliteDatabase = dbHelper.getReadableDatabase();
}
}
// updateDatabaseButton點擊事件監聽器
class UpdateDatabaseOnClickListener implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
SqliteHelper dbHelper = new SqliteHelper(SqliteActivity.this , "test_db" , 2);
// 得到一個只讀的SQLiteDatabase對象
SQLiteDatabase sqliteDatabase = dbHelper.getReadableDatabase();
}
}
// insertButton點擊事件監聽器
class InsertOnClickListener implements OnClickListener {
public void onClick(View v) {
// 創建ContentValues對象
ContentValues values = new ContentValues();
// 向該對象中插入鍵值對,其中鍵是列名,值是希望插入到這一列的值,值必須和數據庫當中的數據類型一致
values.put("id", 1);
values.put("name", "abc");
// 創建DatabaseHelper對象
SqliteHelper dbHelper = new SqliteHelper(SqliteActivity.this , "test_db" , 2);
// 得到一個可寫的SQLiteDatabase對象
SQLiteDatabase sqliteDatabase = dbHelper.getWritableDatabase();
// 調用insert方法,就可以將數據插入到數據庫當中
// 第一個參數:表名稱
// 第二個參數:SQl不允許一個空列,如果ContentValues是空的,那麼這一列被明確的指明爲NULL值
// 第三個參數:ContentValues對象
sqliteDatabase.insert("user", null, values);
}
}
// updateButton點擊事件監聽器
class UpdateOnClickListener implements OnClickListener {
public void onClick(View v) {
// 創建一個DatabaseHelper對象
SqliteHelper dbHelper = new SqliteHelper(SqliteActivity.this , "test_db" , 2);
// 得到一個可寫的SQLiteDatabase對象
SQLiteDatabase sqliteDatabase = dbHelper.getWritableDatabase();
// 創建一個ContentValues對象
ContentValues values = new ContentValues();
values.put("name", "ggg");
// 調用update方法
// 第一個參數String:表名
// 第二個參數ContentValues:ContentValues對象
// 第三個參數String:where字句,相當於sql語句where後面的語句,?號是佔位符
// 第四個參數String[]:佔位符的值
sqliteDatabase.update("user", values, "id=?", new String[] { "1" });
System.out.println("-----------update------------");
}
}
// selectButton點擊事件監聽器
class SelectOnClickListener implements OnClickListener {
public void onClick(View v) {
String id = null;
String name = null;
//創建DatabaseHelper對象
SqliteHelper dbHelper = new SqliteHelper(SqliteActivity.this , "test_db" , 2);
// 得到一個只讀的SQLiteDatabase對象
SQLiteDatabase sqliteDatabase = dbHelper.getReadableDatabase();
// 調用SQLiteDatabase對象的query方法進行查詢,返回一個Cursor對象:由數據庫查詢返回的結果集對象
// 第一個參數String:表名
// 第二個參數String[]:要查詢的列名
// 第三個參數String:查詢條件
// 第四個參數String[]:查詢條件的參數
// 第五個參數String:對查詢的結果進行分組
// 第六個參數String:對分組的結果進行限制
// 第七個參數String:對查詢的結果進行排序
Cursor cursor = sqliteDatabase.query("user", new String[] { "id",
"name" }, "id=?", new String[] { "1" }, null, null, null);
// 將光標移動到下一行,從而判斷該結果集是否還有下一條數據,如果有則返回true,沒有則返回false
while (cursor.moveToNext()) {
id = cursor.getString(cursor.getColumnIndex("id"));
name = cursor.getString(cursor.getColumnIndex("name"));
}
tv.setText("id: "+id + "\nname: "+name);
System.out.println("-------------select------------");
System.out.println("id: "+id);
System.out.println("name: "+name);
}
}
// deleteButton點擊事件監聽器
class DeleteOnClickListener implements OnClickListener {
public void onClick(View v) {
//創建DatabaseHelper對象
SqliteHelper dbHelper = new SqliteHelper(SqliteActivity.this , "test_db" , 2);
//獲得可寫的SQLiteDatabase對象
SQLiteDatabase sqliteDatabase = dbHelper.getWritableDatabase();
//調用SQLiteDatabase對象的delete方法進行刪除操作
//第一個參數String:表名
//第二個參數String:條件語句
//第三個參數String[]:條件值
sqliteDatabase.delete("user", "id=?", new String[]{"1"});
System.out.println("----------delete----------");
}
}
}
SqliteHelper.java:
package com.func;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
public class SqliteHelper extends SQLiteOpenHelper{
public SqliteHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
}
public SqliteHelper(Context context, String name, int version){
this(context,name,null,version);
}
public SqliteHelper(Context context, String name){
this(context,name,1);
}
@Override
public void onCreate(SQLiteDatabase arg0) {
// TODO Auto-generated method stub
System.out.println("create a db");
arg0.execSQL("create table user(id int , name varchar(20))");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
System.out.println("upgrade a db");
}
}