Android SQLite使用

数据库是Android的一种数据存储方式,但是SQLiteOpenHelper是抽象类,我们需要自己写一个实现类来实现onCreate方法和onUpgrade方法,这两个方法分别会在数据库创建和更新的时候调用到。

getWritableDatabase方法和getReadableDatabase方法分别返回一个可写的数据库和一个可读的数据库。如果发现数据库不存在,就会调用onCreate方法创建一个数据库,
如果版本号升级就调用onUpgrade升级数据库。创建的数据库在/data/data/xxx(package)/xxx.db

SQLiteOpenHelper:


如下是一个SQLiteOpenHelper的实现类,创建的时候生成两张表,更新的时候生成一张表。
package com.example.sql.sql;

import android.content.Context;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

/**
 * Created by hongbin on 17-3-6.
 */

public class MyOpenHelper extends SQLiteOpenHelper {
    //数据库版本号
    private static final int DATABASE_VERSION = 1;
    //数据库名
    private static final String DATABASE_NAME = "Test.db";
    //数据库表名
    public static final String[] TABLE_NAMES = {"TABLE_0", "TABLE_1", "TABLE_2"};

    public MyOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        Log.d("dbLog","MyOpenHelper");
    }

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

    public MyOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {
        super(context, name, factory, version, errorHandler);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        Log.d("dbLog","onCreate");
        //创建表一语句
        StringBuffer sBuffer0 = new StringBuffer();
        sBuffer0.append("CREATE TABLE [" + TABLE_NAMES[0] + "] (");
        sBuffer0.append("[_id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ");
        sBuffer0.append("[name] TEXT,");
        sBuffer0.append("[age] INTEGER)");
        //创建表二语句
        StringBuffer sBuffer1 = new StringBuffer();
        sBuffer1.append("CREATE TABLE [" + TABLE_NAMES[1] + "] (");
        sBuffer1.append("[_id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ");
        sBuffer1.append("[name] TEXT,");
        sBuffer1.append("[age] INTEGER)");

        // 执行SQL语句
        sqLiteDatabase.execSQL(sBuffer0.toString());
        sqLiteDatabase.execSQL(sBuffer1.toString());
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        Log.d("dbLog","onUpgrade");

        StringBuffer sBuffer3 = new StringBuffer();
        sBuffer3.append("CREATE TABLE [" + TABLE_NAMES[2] + "] (");
        sBuffer3.append("[_id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ");
        sBuffer3.append("[name] TEXT,");
        sBuffer3.append("[age] INTEGER)");

        sqLiteDatabase.execSQL(sBuffer3.toString());
    }
}

Activity:
public class MainActivity extends AppCompatActivity {

    private MyOpenHelper myOpenHelper;
    private SQLiteDatabase db;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myOpenHelper = new MyOpenHelper(this);
        //获取一个可写的数据库,如果不存在就创建,如果版本更新就升级
        Log.d("dbLog","getWritableDatabase");
        db = myOpenHelper.getWritableDatabase();
    }
}

Log:

从以上日志可以发现数据库创建和升级的流程。

第一次运行的时候版本号为1,执行getWritableDatabase方法没有数据库,所以调用onCreate方法创建了一个数据库,数据库名为Test.db,并且创建了两张表;第二次运行的时候版本号为2,执行getWritableDatabase方法时发现数据库版本升级了,所以调用onUpgrade方法,在Test.db下创建了TABLE_2表。


创建之后对数据库的增删改查可以用execSQL来执行SQL语句,也可以分别用insert、delete、update、query来执行,这里就不细说了。


批量处理

在数据库的使用过程中,常常需要一次性操作大量的数据,如果用循环一次一次的操作肯定是很消耗事件的,这时候我们就需要用到开启一个事务来做批处理。做个实验验证一下一次性插入5000条数据的时间消耗。


public void onClick(View view) {
                int i = 0;
                String sql = "INSERT INTO %s VALUES (null, %s, %s)";
                try {
                    Log.d("dbLog","非批处理");
                    Log.d("dbLog","start");
                    while(i < 5000){
                        db.execSQL(String.format(sql,MyOpenHelper.TABLE_NAMES[0],i,i));
                        i++;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    Log.d("dbLog","finish");
                    Log.d("dbLog","插入" + i + "条数据");
                }
            }

//----------------------------------我是一条分割线------------------------------------//

public void onClick(View view) {
                int i = 0;
                String sql = "INSERT INTO %s VALUES (null, %s, %s)";
                try {
                    Log.d("dbLog","批处理");
                    Log.d("dbLog","start");
                    db.beginTransaction();
                    while(i < 5000){
                        db.execSQL(String.format(sql,MyOpenHelper.TABLE_NAMES[1],i,i));
                        i++;
                    }
                    db.setTransactionSuccessful();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    db.endTransaction();
                    Log.d("dbLog","finish");
                    Log.d("dbLog","插入" + i + "条数据");
                }
            }

不采用事务来执行人5000次的插入操作,从日志中可以看到,start到finish的时间差是34.53秒。

而采用事务来执行人5000次的插入操作,从日志中可以看到,start到finish的时间差是1.16秒。

这里的性能差别真是太大啦。

我们都知道磁盘的读写是很耗时的,简单来说,每一次的插入都是一个事务,执行5000插入操作相当于执行了5000次的磁盘读写,而采用事务包装的话就把5000次的插入操作当作一次事务,也就是一次磁盘读写,时间上当然相差很大啦。


数据库的知识太多了,这里就简单描述一下Android SQLite最基础的操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值