Android SQLite数据库之事务的学习

SQLite是Android系统内置的一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百K的内存就足够了。SQLite不仅支持标准的SQL语法,还遵循了数据库的ACID事务。

模拟一个应用场景:进行一次转账操作,银行会将转账的金额先从你的账户中扣除,然后再向收款方的账户中添加等量的金额。看上去好像没有什么问题,可是当你的账户的金额刚刚被扣除,这是由于一些异常原因导致对方收款失败(比如突然断电),这一部分钱就凭空消失了,当然银行自然会考虑到这个问题,它会保证扣钱和收款的操作要么一起完成,要么都不会成功,而使用的技术就是事物了。

Android为了让我们能够更加方便的管理数据库,专门提供了一个SQLiteOpenHelper辅助类,借助这个类我们可以很方便的对数据库进行创建和升级。由于SQLiteOpenHelper是一个抽象类,我们需要自己创一个辅助类去继承他。

创建MyDatabaseHelper

package com.tonycheng.databasetest;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;

/**
 * Created by tonycheng on 2015/6/27.
 */
public class MyDatabaseHelper extends SQLiteOpenHelper {

    public static final String CREATE_BOOK = "create table book(" +
            "id integer primary key autoincrement," +
            "author text," +
            "price real," +
            "pages integer," +
            "name text," +
            "category_id integer)";

    private Context mContext;

    public MyDatabaseHelper(Context context, String name,
                            SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK);
        Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }

}

写一个简单的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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/create_database"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Create Database"
        />
    <Button
        android:id="@+id/replace_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Replace data"
        />

</LinearLayout>

最后在MainActivity中修改代码:

第一步创建一个数据库:

package com.tonycheng.databasetest;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends ActionBarActivity {
    private MyDatabaseHelper dbHelper;
    private Button btn_createDatabase;
    private Button btn_raplaceData;

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,1);
        btn_createDatabase = (Button) findViewById(R.id.create_database);
        btn_raplaceData = (Button) findViewById(R.id.replace_data);
        btn_createDatabase.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dbHelper.getWritableDatabase();
            }
        });
    }
}

onCreat()方法中构建了一个MyDatabaseHelper对象,并通过构造函数的参数将数据库名指定为BookStore.db,版本号指定为1。然后在按钮的onClick事件中调用getWritableDatabase()方法创数据库。

向BookStore.db数据库中添加一条数据:在添加一个Add Data按钮

 btn_addData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbHelper.getWritableDatabase();//第一种方法:
                ContentValues values = new ContentValues();
                //开始组装第一条数据
                values.put("name","The Da Vinci Code ");
                values.put("author","Dan Brown");
                values.put("pages",510);
                values.put("price", 19.95);
                db.insert("book", null, values);//第二种方法
                //使用SQL插入数据(同理设用于其他集中操作)
//两种添加数据的方法,如果你觉得上面一种方法太繁琐,就是用SQL语句来创建,他们的效果是一样的
                db.execSQL("insert into book(name,author,pages,price) values(?,?,?,?)",new String[]{
                        "The Da Vinci Code","Dan Brown","510","19.95"
                });
            }
        });

这样数据库中就有一条数据了,我们老进行事物操作:我们从book表中删除这条数据,再添加一条新的数据:

 /**
         * 使用事物来进行数据库操作,两种操作要么都完成,要么都失败(事物)
         */
        btn_raplaceData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbHelper.getWritableDatabase();
                db.beginTransaction();//开启事物
                try {
                    db.delete("book",null,null);
                    if (true){
                        //这里手动抛出一个异常,让事物失败
                      //  throw new NullPointerException();//由于我们手动抛出了一个异常,这样添加数据的代码就无法执行了,但是由于事物的存在,此时旧数据也无法删除
                    }
                    db.execSQL("insert into book(name,author,pages,price) values(?,?,?,?)", new String[]{
                            "android ", "tonycheng", "550", "79"
                    });
                    db.setTransactionSuccessful();
                }finally {
                    db.endTransaction();
                }
            }
        });

运行上面的代码,发现表中的数据没有被删除,这是由于我们启用了事务,故意手动抛出了一个异常,导致旧数据也无法删除,如果没有启用事务,book表中的旧数据时会被删除的,而由于异常,添加数据的代码就无法执行。而这样在一些场合下是会出大问题的。由此,事务的重要性就体现出来了。至此,我们事务的一个简单的模拟就完成了。

时间: 2024-10-26 11:05:14

Android SQLite数据库之事务的学习的相关文章

赵雅智_使用SQLiteDatabase操作SQLite数据库及事务

知识点详解:http://blog.csdn.net/zhaoyazhi2129/article/details/9025995 具体代码: MainActivity.java package com.example.android_sqlite; import android.app.Activity; import android.os.Bundle; import com.example.android_sqlite.dao.impl.UserDaoImpls; import com.ex

Android SQLite数据库操作示例

SQLite介绍 SQLite是一个非常流行的嵌入式数据库,它支持SQL语言,并且只利用很少的内存就有很好的性能.此外,它还是开源的,任何人都可以使用它. SQLite由以下几个组件组成:SQL编译器.内核.后端以及附件.SQLite通过利用虚拟机和虚拟数据库引擎(VDBE),使调试.修改和扩展SQLite的内核变得更加方便. SQLite支持的数据类型参考链接:http://blog.csdn.net/wzy_1988/article/details/36005947 Android在运行时(

Android Sqlite数据库加密

Android使用的是开源的SQLite数据库,数据库本身没有加密,加密思路通常有两个: 1. 对几个关键的字段使用加密算法,再存入数据库 2. 对整个数据库进行加密 SQLite数据库加密工具: 收费工具: SSE(SQLite Encryption Extension) 免费工具: SQLCipher SQLCipher使用: SQLCipher是完全开源的软件,提供256-bit AES加密 源码编译: 1. OpenSSL编译 SQLCipher源码编译需要依赖OpenSSL提供的lib

Android学习笔记(8)——Sqlite数据库的事务问题

事务(Transaction)是并发控制的基本单位.所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位. 一个浅显的例子,例如银行转账工作:从一个账号扣款并使另一个账号增款,这两个操作要么都执行,要么都不执行.不能说如果执行完一个账号的扣款之后,突然停电了,另外一个账号没有进行增款操作. 类似这样的情况,我们都应该把它们看成一个事务.事务是数据库维护数据一致性的单位,并且在每个事务结束时,都能保持数据一致性. 事务应该遵循ACID特征,即: Atomic(

无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)

1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.example.demo1" /> 上面targetPackage指定的包要和应用的package相同. (2)在清单文件中ap

Android——SQLite数据库(二)升级数据库、增、删、改、查、事务

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="match_parent" android

Android SQLite数据库增删改查操作

一.使用嵌入式关系型SQLite数据库存储数据 在Android平台上,集成了一个嵌入式关系型数据库——SQLite,SQLite3支持NULL.INTEGER.REAL(浮点数字). TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型只有五种,但实际上sqlite3也接受varchar(n). char(n).decimal(p,s) 等数据类型,只不过在运算或保存时会转成对应的五种数据类型. SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段

Android Sqlite 数据库版本更新

http://87426628.blog.163.com/blog/static/6069361820131069485844/ 1.自己写一个类继承自SqliteOpenHelper 2.会实现SqliteOpenHelper的两个方法 onCreate与onUpgrade,google文档对两个回调方法的解释是创建数据库的时候调用与更新数据库的版本的时候调用 3.Sqlite数据库主要是用来缓存应用的数据,而应用却是一直在更新版本,相应的数据的表的字段也会一直增加会改变或减少 4.这个时候就

[Android] SQLite数据库之增删改查基础操作

    在编程中常常会遇到数据库的操作,而Android系统内置了SQLite,它是一款轻型数据库,遵守事务ACID的关系型数据库管理系统,它占用的资源非常低,可以支持Windows/Linux/Unix等主流操作系统,同一时候可以跟非常多程序语言如C#.PHP.Java等相结合.以下先回想SQL的基本语句,再讲述Android的基本操作. 一. adb shell回想SQL语句     首先,我感觉自己整个大学印象最深的几门课就包含<数据库>,所以想先回想SQL增删改查的基本语句.而在And