java中sqlite生命周期,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快。

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是从SQLite数据库获取问题并在Android应用程序显示的基本代码: 首先,创建一个SQLiteOpenHelper子类,用于管理数据库: ```java public class DatabaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "quiz.db"; private static final int DATABASE_VERSION = 1; private static final String TABLE_NAME = "questions"; private static final String COLUMN_ID = "_id"; private static final String COLUMN_QUESTION = "question"; private static final String COLUMN_ANSWER = "answer"; public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { String query = "CREATE TABLE " + TABLE_NAME + " (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_QUESTION + " TEXT, " + COLUMN_ANSWER + " TEXT" + ")"; db.execSQL(query); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); } public Cursor getAllQuestions() { SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME, null); return cursor; } } ``` 接下来,在你的Activity,调用getAllQuestions()方法来获取问题: ```java public class QuizActivity extends AppCompatActivity { private ListView listView; private ArrayList<String> questionsList; private ArrayAdapter<String> adapter; private DatabaseHelper dbHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_quiz); listView = findViewById(R.id.list_view); questionsList = new ArrayList<>(); adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, questionsList); listView.setAdapter(adapter); dbHelper = new DatabaseHelper(this); Cursor cursor = dbHelper.getAllQuestions(); if (cursor.moveToFirst()) { do { String question = cursor.getString(cursor.getColumnIndex("question")); questionsList.add(question); } while (cursor.moveToNext()); } adapter.notifyDataSetChanged(); } @Override protected void onDestroy() { super.onDestroy(); if (dbHelper != null) { dbHelper.close(); } } } ``` 在这个例子,我们将问题存储在一个ListView,但你可以根据你的需求进行更改。注意在Activity生命周期结束时关闭数据库连接

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值