還是在上一篇中的例子基礎上寫的,綠色部分就是實現事務的代碼:
核心代碼如下:
activity_main.xml
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
android:id="@+id/btn_replace_data"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="替換"
/>
android:id="@+id/create_btn_database"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="創建數據庫" />
android:id="@+id/btn_adddata"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="添加數據" />
android:id="@+id/btn_updatedata"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="更新數據" />
android:id="@+id/btn_deletedata"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="刪除數據" />
android:id="@+id/btn_query_data"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="查詢數據" />
MainActivity
/**
* 本項目是對事務的使用
* 事務的特性就是可以保證讓某一系列的操作要么全部完成,要么都不完成。(就是要么提交,要么回滾)
*
*/
public class MainActivity extends Activity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* 創建數據庫
*/
// 指定數據庫的名稱BookStore.db,版本號是1
dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 2);
Button createDatabase_btn = (Button) findViewById(R.id.create_btn_database);
createDatabase_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 得到一個能寫的數據庫
dbHelper.getWritableDatabase();
}
});
/**
* 添加數據
*/
Button addData_btn = (Button) findViewById(R.id.btn_adddata);
addData_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
/* SQLiteDatabase類才能對數據庫操作,即增刪改查 */
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
// 開始組裝第一條數據
values.put("name", "The Da Vinci code");
values.put("author", "Dan Brown");
values.put("pages", 454);
values.put("price", 16.96);
db.insert("Book", null, values);// 插入第一條數據
values.clear();
// 開始組裝第二條數據
values.put("name", "The Lost Symbol");
values.put("author", "Dan Brown");
values.put("pages", 510);
values.put("price", 19.95);
db.insert("Book", null, values);// 插入第二條數據
Toast.makeText(MainActivity.this, "數據已添加", 10).show();
///**除了可以用android分裝的方法進行增刪該查,還可以直接用sql語句
//* 下面是用方法實現相同功能,增刪改都調用execSQL兩個參數的方法,查詢調用rawQuery方法*/
增加
//db.execSQL("insert into Book(name,author,pages,price)values(?,?,?,?)",new String[]{"The Da Vinci Code","Dan Brown","454","16.96"});
//db.execSQL("insert into Book(name,author,pages,price)values(?,?,?,?)",new String[]{"The Lost Symbol","Dan brown","510","19.95"});
刪除
//db.execSQL("delete from Book where pages >?", new String[]{"500"});
更新
//db.execSQL("update Book set price=?where name=?", new String[]{"10.99","The Da Vinci Code"});
查詢
//db.rawQuery("select*from Book", null);
}
});
/**
* 更新數據
*/
Button updatedata_btn = (Button) findViewById(R.id.btn_updatedata);
updatedata_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price", 10.99);
db.update("Book", values, "name=?",
new String[] { "The Da Vinci code" });
/* 上述代碼的意思是:將名字是The Da Vinci Code 這本書的價格改成10.99 */
Toast.makeText(MainActivity.this, "修改成功", 10).show();
}
});
/**
* 刪除數據
*/
Button deletedata_btn = (Button) findViewById(R.id.btn_deletedata);
deletedata_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("Book", "pages>?", new String[] { "500" });
/* 刪除頁數超過500的書籍 */
Toast.makeText(MainActivity.this, "刪除成功", 10).show();
}
});
/**
* 查詢數據
*/
Button querydata_btn = (Button) findViewById(R.id.btn_query_data);
querydata_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.query("Book", null, null, null, null, null,
null);
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(cursor
.getColumnIndex("name"));
String author = cursor.getString(cursor
.getColumnIndex("author"));
int pages = cursor.getInt(cursor
.getColumnIndex("pages"));
double price = cursor.getDouble(cursor
.getColumnIndex("price"));
Log.d("1", "name。。。" + name);
Log.d("1", "author。。。" + author);
Log.d("1", "pages。。。" + pages);
Log.d("1", "price。。。" + price);
} while (cursor.moveToNext());
cursor.close();
}
Toast.makeText(MainActivity.this, "查詢成功", 10).show();
}
});
/**
* 替換,事務的使用
*/
Button replaceData = (Button) findViewById(R.id.btn_replace_data);
replaceData.setOnClickListener(new OnClickListener() {
/*事務的標准用法
* 1開啟事務db.beginTransaction();
* 2事務已經執行成功db.setTransactionSuccessful()
* 3結束事務db.endTransaction();
* 下面的代碼,注意觀察,在刪除舊數據的操作完成后手動拋出一個NullPointerException()
* 這樣添加新數據的代碼就執行不到了(如果沒有事務就屬於,刪除數據,但是沒有添加)。
* 不過由於事務的存在,中途出現的異常會導致事務失敗,此時舊數據是刪不掉的
* 如果手動將拋出異常的代碼去掉,在重新運行一下程序,點擊按鈕就發現數據更新了
* */
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.beginTransaction();//開啟事務
try {
db.delete("Book", null, null);
if (true) {
//這里手動拋出一個異常,讓事務失敗
throw new NullPointerException();
}
ContentValues values =new ContentValues();
values.put("name", "Game of Thrones");
values.put("author", "George Martin");
values.put("pages", 720);
values.put("price", 20.85);
db.insert("Book", null, values);
db.setTransactionSuccessful();//事務已經執行成功
} catch (Exception e) {
e.printStackTrace();
}finally{
db.endTransaction();//結束事務
Toast.makeText(MainActivity.this, "替換成功", 10).show();
}
}
});
}// onCreate
}// class
MyDatabaseHelper
/**
*SQLiteOpenHelper是用來創建數據庫和表的
*
*/
public class MyDatabaseHelper extends SQLiteOpenHelper {
/*
*autoincrement表示id列是自增長的
*integer表示整型
*real表示浮點
*text表示文本類型
*blob表示二進制類型
*
* */
public static final String CREATE_BOOK="create table Book(" +
"id integer primary key autoincrement," +
"author text," +
"price real," +
"pages integer," +
"name text)";
public static final String CREATE_CATEGORY="create table Category(" +
"id integer primary key autoincrement," +
"category_name text" +
"category_code integer)";
private Context mContext;
public MyDatabaseHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
mContext=context;
}
/**
*這個方法在創建數據庫的時候,系統只調用一次
*/
@Override
public void onCreate(SQLiteDatabase db) {
//數據庫創建完成,同時創建book表
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATEGORY);
Toast.makeText(mContext, "創建成功", Toast.LENGTH_LONG).show();
}
/**
* 要想執行這個方法只要在new MyDatabaseHelper(this, "BookStore.db", null, 1);
* 傳入的版本號大於之前傳的,系統就可以調用此方法
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists Book");
db.execSQL("drop table if exists Category");
onCreate(db);
/*如果數據庫中已經存在Book,Category的表了,就將這兩張表刪掉,然后調用onCreate();方法
* 重新創建,這里現將存在的表刪掉,是因為如果在創建表示發現這張表已經存在了,就會直接報錯
* */
}
}//class
如果沒有明白,下載我的例子: