Android学习笔记-数据库开发-4:SQLiteDataBase基本用法(1):获取一个SQLiteDataBase
来源:互联网 发布:优道网络骗局揭秘 编辑:程序博客网 时间:2024/06/06 05:21
上一篇:我们学习了如何用AndroidStudio和SQLiteExpertPro方便的查看SQLite数据库。
本篇我们开始学习,SQLiteDatabase的基本用法:
我们可以通过SQLiteOpenHelper获取一个SQLiteDataBase:
具体方法如下:
public SQLiteDatabase getWritableDatabase() { synchronized (this) { return getDatabaseLocked(true); }}
或者:
public SQLiteDatabase getReadableDatabase() { synchronized (this) { return getDatabaseLocked(false); } }
看着两个方法,都是调用了getDatabaseLocked方法:
private SQLiteDatabase getDatabaseLocked(boolean writable) { if (mDatabase != null) { if (!mDatabase.isOpen()) { // Darn! The user closed the database by calling mDatabase.close(). mDatabase = null; } else if (!writable || !mDatabase.isReadOnly()) { // The database is already open for business. return mDatabase; } } if (mIsInitializing) { throw new IllegalStateException("getDatabase called recursively"); } SQLiteDatabase db = mDatabase; try { mIsInitializing = true; if (db != null) { if (writable && db.isReadOnly()) { db.reopenReadWrite(); } } else if (mName == null) { db = SQLiteDatabase.create(null); } else { try { if (DEBUG_STRICT_READONLY && !writable) { final String path = mContext.getDatabasePath(mName).getPath(); db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY, mErrorHandler); } else { db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ? Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0, mFactory, mErrorHandler); } } catch (SQLiteException ex) { if (writable) { throw ex; } Log.e(TAG, "Couldn't open " + mName + " for writing (will try read-only):", ex); final String path = mContext.getDatabasePath(mName).getPath(); db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY, mErrorHandler); } } onConfigure(db); final int version = db.getVersion(); if (version != mNewVersion) { if (db.isReadOnly()) { throw new SQLiteException("Can't upgrade read-only database from version " + db.getVersion() + " to " + mNewVersion + ": " + mName); } db.beginTransaction(); try { if (version == 0) { onCreate(db); } else { if (version > mNewVersion) { onDowngrade(db, version, mNewVersion); } else { onUpgrade(db, version, mNewVersion); } } db.setVersion(mNewVersion); db.setTransactionSuccessful(); } finally { db.endTransaction(); } } onOpen(db); if (db.isReadOnly()) { Log.w(TAG, "Opened " + mName + " in read-only mode"); } mDatabase = db; return db; } finally { mIsInitializing = false; if (db != null && db != mDatabase) { db.close(); } } }
主要我们看到:
SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY, mErrorHandler);
该方法返回了一个SQLiteDatabase
我们再看一下opendatabase方法。
opendatabase:
public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags, DatabaseErrorHandler errorHandler) { SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler); db.open(); return db; }i
初始化了一些本地信息,然后调用 open方法,返回SQLiteDatabase 。
open方法:
private void open() { try { try { openInner(); } catch (SQLiteDatabaseCorruptException ex) { onCorruption(); openInner(); } } catch (SQLiteException ex) { Log.e(TAG, "Failed to open database '" + getLabel() + "'.", ex); close(); throw ex; } }
private void openInner() { synchronized (mLock) { assert mConnectionPoolLocked == null; mConnectionPoolLocked = SQLiteConnectionPool.open(mConfigurationLocked); mCloseGuardLocked.open("close"); } synchronized (sActiveDatabases) { sActiveDatabases.put(this, null); } }
可以看到最终open了一个SQLiteConnectionPool对象
private SQLiteConnectionPool mConnectionPoolLocked;
该类是一个类似管理SQLiteConnection的线程池对象,
SQLiteDatabase会该对象进行操纵,从而达到数据库操作的目的。
如何管理 mConnectionPoolLocked呢?
原来SQLiteDatabase使用了一个叫SQLiteSession来管理和使用该SQLiteConnectionPool。
上源码:
private final ThreadLocal<SQLiteSession> mThreadSession = new ThreadLocal<SQLiteSession>() { @Override protected SQLiteSession initialValue() { return createSession(); } };
SQLiteSession getThreadSession() { return mThreadSession.get(); // initialValue() throws if database closed }
SQLiteSession createSession() { final SQLiteConnectionPool pool; synchronized (mLock) { throwIfNotOpenLocked(); pool = mConnectionPoolLocked; } return new SQLiteSession(pool); }可以看到:SQLiteDatabase使用ThreadLocal来定义了一个SQLiteSession,这样可以保证单线程中只有一个ThreadSession。
而重写了initialValue方法:保证每次get的时候会new 一个SQLiteSession,并传入mConnectionPoolLocked。这样多个ThreadSession其实是共享了一个线程池。
(可以猜到:SQLiteDatabase应该在执行SQL时候都会使用这个getThreadSession来 获取SQLiteConnection的。)
这时候就需要知道SQLiteSession的工作原理了。
下一篇:Android学习笔记-数据库开发-4:SQLiteDataBase基本用法(3):SQLiteSession的工作原理
阅读全文
0 0
- Android学习笔记-数据库开发-4:SQLiteDataBase基本用法(1):获取一个SQLiteDataBase
- Android获取操作数据库的SQLiteDatabase实例
- [android]数据库SQLiteDatabase简介
- Android 数据库SQLiteDatabase
- android sqlitedatabase 数据库
- Android SQLiteDatabase 数据库存储
- Android数据库SQLiteDatabase
- Android 创建数据库 SQliteDatabase
- Android sqlitedatabase 数据库创建
- Android开发总结笔记 SQLiteDataBase 2-3
- Android:SQLiteOpenHelper,SqliteDatabase学习
- Android:Sqlitedatabase学习小结
- Android:Sqlitedatabase学习小结
- Android:Sqlitedatabase学习小结
- Android系列学习:SQLiteDatabase
- Android 创建数据库(使用SqliteDataBase)
- Android数据库(SQLiteDatabase)使用小结
- Android 数据库SQLiteDatabase的使用
- 素数环问题(分支限界法)
- Java--servlet--目录
- 大数据正式27
- leetcode 第5题 Longest Palindromic Substring
- Java调用C语言编写的简单函数库
- Android学习笔记-数据库开发-4:SQLiteDataBase基本用法(1):获取一个SQLiteDataBase
- Python.CVXPY学习指南一
- YII2.0 接入阿里云的OSS对象存储
- UVA839
- 一致性哈希算法
- java多线程(2) 循环调用三个线程
- OBD-II接口定义
- 如何解决JWplayer下报Error loading media: File could not be played错误
- Hadoop SequenceFile 详解