数据库是Android的一种数据存储方式,但是SQLiteOpenHelper是抽象类,我们需要自己写一个实现类来实现onCreate方法和onUpgrade方法,这两个方法分别会在数据库创建和更新的时候调用到。
getWritableDatabase方法和getReadableDatabase方法分别返回一个可写的数据库和一个可读的数据库。如果发现数据库不存在,就会调用onCreate方法创建一个数据库,如果版本号升级就调用onUpgrade升级数据库。创建的数据库在/data/data/xxx(package)/xxx.dbSQLiteOpenHelper:如下是一个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:从以上日志可以发现数据库创建和升级的流程。
创建之后对数据库的增删改查可以用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最基础的操作。
新闻热点
疑难解答