Sqlite

前言

SQLite是一个轻量的、跨平台的、开源的数据库引擎。SQLite每个数据库都是以单个文件(.db)的形式存在,这些数据都是以B-Tree的数据结构形式存储在磁盘上。

使用SQLiteDatabase的insert,delete等方法或者execSQL方法默认都开启了事务,如果操作的顺利完成才会更新.db数据库。事务的实现是依赖于名为rollback journal文件,借助这个临时文件来完成原子操作和回滚功能。

大家可以在/data/data//databases/目录下看到一个和数据库同名的.db-journal文件。

SQLite是文件级别的锁:多个线程可以同时读,但是同时只能有一个线程写。Android提供了SqliteOpenHelper类,加入Java的锁机制以便调用。


模板

public class DbOpenHelper extends SQLiteOpenHelper {
 private static final String DB_NAME = "book_provider.db";
 public static final String BOOK_TABLE_NAME = "book";
 public static final String USER_TALBE_NAME = "user";

 private static final int DB_VERSION = 3;

 private String CREATE_BOOK_TABLE = "CREATE TABLE IF NOT EXISTS "
         + BOOK_TABLE_NAME + "(_id INTEGER PRIMARY KEY," + "name TEXT)";

 private String CREATE_USER_TABLE = "CREATE TABLE IF NOT EXISTS "
         + USER_TALBE_NAME + "(_id INTEGER PRIMARY KEY," + "name TEXT," + "sex INT)";

 public DbOpenHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); }

 @Override    
 public void onCreate(SQLiteDatabase db) {    //如果创建了,就不会回调这个方法。
     db.execSQL(CREATE_BOOK_TABLE);
     db.execSQL(CREATE_USER_TABLE);
 }

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

线程问题

SQLite的同步锁精确到数据库级,粒度比较大,不像别的数据库有表锁,行锁。同一个时间只允许一个连接进行写入操作。

如果多线程同时读写(这里的指不同的线程用使用的是不同的Helper实例),后面的就会遇到android.database.sqlite.SQLiteException: database is locked这样的异常。对于这样的问题,解决的办法就是keep single sqlite connection,保持单个SqliteOpenHelper实例,同时对所有数据库操作的方法添加synchronized关键字。

我们常常在多线程中只使用一个SQLiteDatabase引用,在用SQLiteDataBase.close()的时需要注意调是否还有别的线程在使用这个实例。如果一个线程操作完成后就直接close了,别一个正在使用这个数据库的线程就会异常。所以有些人会直接把SQLiteDatabase的实例放在Application中,让它们的生命周期一致。也有的做法是写一个计数器,当计数器为0时才真正关闭数据库。


使用ORM的问题

目前网上有很多开源的ORM(对象关系数据映射)框架,如greenDAO、ormlite等等。在使用这些框架有必要很了解一下它们的利弊,特别是一些使用反射的框架,对性能的影响会比较大。有些框架在多线程同步方面也会产生一些问题,所以使用时要有所顾虑。

Realm 是最近兴起的一个专注于移动设备数据库的库,其核心是使用C++编写,号称很多时候数据的存取速度比SQLite要快很多。不过在我的一些项目中,发现它读取并不比SQLite快。


参考资料

  • Android面试一天一题(Day 18:SQLite数据库)
  • SQLite多线程读写实践及常见问题总结

你可能感兴趣的:(Sqlite)