Android 数据库操作过程分析
2014-09-03 18:51
447 查看
打开数据库
android.database.sqlite.SQLiteDatabase
android.database.sqlite.SQLiteConnectionPool
android.database.sqlite.SQLiteConnection
至此数据已经完成打开,之后操作数据库只需要将拿到SQLiteConnectionPool对象中的mAvailablePrimaryConnection成员变量即可。
查询数据库
查询方法最终都需要执行SQLiteDatabase.rawQueryWithFactory方法
android.database.sqlite.SQLiteDatabase
android.database.sqlite.SQLiteDirectCursorDriver
一般用以下方式获取查询出的数据
cursor.moveToNext();
cursor.getXXX()获取数据。那么跟踪这些方法看看到底如何查询数据的。
--android.database.Cursor(C)
-- android.database.AbstractCursor(AC)
--android.database.AbstractWindowedCursor(AWC)
--android.database.sqlite.SQLiteCursor(SQLC)
android.database.sqlite.SQLiteQuery(SQLQ)
C.moveToNext()-->AC.moveToNext()-->SQLC.getCount()-->SQLC.fillwindow()
-->AWC.clearOrCreateWindow()-->SQLQ.fillWindow()
android.database.sqlite.SQLiteQuery
android.database.sqlite.SQLiteSession
获取连接继续跟踪下去最终到
android.database.sqlite.SQLiteConnectionPool
android.database.sqlite.SQLiteDatabase
public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags, DatabaseErrorHandler errorHandler) { SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler); db.open(); return db; }
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); } }
android.database.sqlite.SQLiteConnectionPool
public static SQLiteConnectionPool open(SQLiteDatabaseConfiguration configuration) { if (configuration == null) { throw new IllegalArgumentException("configuration must not be null."); } // Create the pool. SQLiteConnectionPool pool = new SQLiteConnectionPool(configuration); pool.open(); // might throw return pool; }
private void open() { //这个地方比较重要,打开一个主连接保存在mAvailablePrimaryConnection成员变量中,以便操作数据时获取连接对象。 // Open the primary connection. // This might throw if the database is corrupt. mAvailablePrimaryConnection = openConnectionLocked(mConfiguration, true /*primaryConnection*/); // might throw // Mark the pool as being open for business. mIsOpen = true; mCloseGuard.open("close"); }
private SQLiteConnection openConnectionLocked(SQLiteDatabaseConfiguration configuration, boolean primaryConnection) { final int connectionId = mNextConnectionId++; return SQLiteConnection.open(this, configuration, connectionId, primaryConnection); // might throw }
android.database.sqlite.SQLiteConnection
// Called by SQLiteConnectionPool only. static SQLiteConnection open(SQLiteConnectionPool pool, SQLiteDatabaseConfiguration configuration, int connectionId, boolean primaryConnection) { SQLiteConnection connection = new SQLiteConnection(pool, configuration, connectionId, primaryConnection); try { connection.open(); return connection; } catch (SQLiteException ex) { connection.dispose(false); throw ex; } }
private void open() { //使用了 native方法打开数据库。 mConnectionPtr = nativeOpen(mConfiguration.path, mConfiguration.openFlags, mConfiguration.label, SQLiteDebug.DEBUG_SQL_STATEMENTS, SQLiteDebug.DEBUG_SQL_TIME); setPageSize(); setForeignKeyModeFromConfiguration(); setWalModeFromConfiguration(); setJournalSizeLimit(); setAutoCheckpointInterval(); setLocaleFromConfiguration(); // Register custom functions. final int functionCount = mConfiguration.customFunctions.size(); for (int i = 0; i < functionCount; i++) { SQLiteCustomFunction function = mConfiguration.customFunctions.get(i); nativeRegisterCustomFunction(mConnectionPtr, function); } }
至此数据已经完成打开,之后操作数据库只需要将拿到SQLiteConnectionPool对象中的mAvailablePrimaryConnection成员变量即可。
查询数据库
查询方法最终都需要执行SQLiteDatabase.rawQueryWithFactory方法
android.database.sqlite.SQLiteDatabase
public Cursor rawQueryWithFactory( CursorFactory cursorFactory, String sql, String[] selectionArgs, String editTable, CancellationSignal cancellationSignal) { acquireReference(); try { SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable, cancellationSignal); return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory, selectionArgs); } finally { releaseReference(); } }
android.database.sqlite.SQLiteDirectCursorDriver
public Cursor query(CursorFactory factory, String[] selectionArgs) { final SQLiteQuery query = new SQLiteQuery(mDatabase, mSql, mCancellationSignal); final Cursor cursor; try { query.bindAllArgsAsStrings(selectionArgs); if (factory == null) { //新建了cursor对象,这时还没有进行数据查询,只是创建了一个空壳。 cursor = new SQLiteCursor(this, mEditTable, query); } else { cursor = factory.newCursor(mDatabase, this, mEditTable, query); } } catch (RuntimeException ex) { query.close(); throw ex; } mQuery = query; return cursor; }
一般用以下方式获取查询出的数据
cursor.moveToNext();
cursor.getXXX()获取数据。那么跟踪这些方法看看到底如何查询数据的。
--android.database.Cursor(C)
-- android.database.AbstractCursor(AC)
--android.database.AbstractWindowedCursor(AWC)
--android.database.sqlite.SQLiteCursor(SQLC)
android.database.sqlite.SQLiteQuery(SQLQ)
C.moveToNext()-->AC.moveToNext()-->SQLC.getCount()-->SQLC.fillwindow()
-->AWC.clearOrCreateWindow()-->SQLQ.fillWindow()
android.database.sqlite.SQLiteQuery
int fillWindow(CursorWindow window, int startPos, int requiredPos, boolean countAllRows) { acquireReference(); try { window.acquireReference(); try { //这里真正开始数据库操作 int numRows = getSession().executeForCursorWindow(getSql(), getBindArgs(), window, startPos, requiredPos, countAllRows, getConnectionFlags(), mCancellationSignal); return numRows; } catch (SQLiteDatabaseCorruptException ex) { onCorruption(); throw ex; } catch (SQLiteException ex) { Log.e(TAG, "exception: " + ex.getMessage() + "; query: " + getSql()); throw ex; } finally { window.releaseReference(); } } finally { releaseReference(); } }
android.database.sqlite.SQLiteSession
public int executeForCursorWindow(String sql, Object[] bindArgs, CursorWindow window, int startPos, int requiredPos, boolean countAllRows, int connectionFlags, CancellationSignal cancellationSignal) { if (sql == null) { throw new IllegalArgumentException("sql must not be null."); } if (window == null) { throw new IllegalArgumentException("window must not be null."); } if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) { window.clear(); return 0; } //获取连接 acquireConnection(sql, connectionFlags, cancellationSignal); // might throw try { return mConnection.executeForCursorWindow(sql, bindArgs, window, startPos, requiredPos, countAllRows, cancellationSignal); // might throw } finally { releaseConnection(); // might throw } }
获取连接继续跟踪下去最终到
android.database.sqlite.SQLiteConnectionPool
private SQLiteConnection waitForConnection(String sql, int connectionFlags, CancellationSignal cancellationSignal) { final boolean wantPrimaryConnection = (connectionFlags & CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY) != 0; final ConnectionWaiter waiter; final int nonce; synchronized (mLock) { throwIfClosedLocked(); // Abort if canceled. if (cancellationSignal != null) { cancellationSignal.throwIfCanceled(); } // Try to acquire a connection. SQLiteConnection connection = null; if (!wantPrimaryConnection) { connection = tryAcquireNonPrimaryConnectionLocked( sql, connectionFlags); // might throw } if (connection == null) { //尝试获取主连接 connection = tryAcquirePrimaryConnectionLocked(connectionFlags); // might throw } if (connection != null) { return connection; } // No connections available. Enqueue a waiter in priority order. final int priority = getPriority(connectionFlags); final long startTime = SystemClock.uptimeMillis(); waiter = obtainConnectionWaiterLocked(Thread.currentThread(), startTime, priority, wantPrimaryConnection, sql, connectionFlags); ConnectionWaiter predecessor = null; ConnectionWaiter successor = mConnectionWaiterQueue; while (successor != null) { if (priority > successor.mPriority) { waiter.mNext = successor; break; } predecessor = successor; successor = successor.mNext; } if (predecessor != null) { predecessor.mNext = waiter; } else { mConnectionWaiterQueue = waiter; } nonce = waiter.mNonce; }
// Might throw. private SQLiteConnection tryAcquirePrimaryConnectionLocked(int connectionFlags) { // If the primary connection is available, acquire it now. //拿出主连接 SQLiteConnection connection = mAvailablePrimaryConnection; if (connection != null) { mAvailablePrimaryConnection = null; finishAcquireConnectionLocked(connection, connectionFlags); // might throw return connection; } // Make sure that the primary connection actually exists and has just been acquired. for (SQLiteConnection acquiredConnection : mAcquiredConnections.keySet()) { if (acquiredConnection.isPrimaryConnection()) { return null; } } // Uhoh. No primary connection! Either this is the first time we asked // for it, or maybe it leaked? connection = openConnectionLocked(mConfiguration, true /*primaryConnection*/); // might throw finishAcquireConnectionLocked(connection, connectionFlags); // might throw return connection; }
相关文章推荐
- android Xutils 数据库操作源码分析
- Android camera fw学习(二)-open camera操作过程&准备工作分析。
- Android中数据库常见操作实例分析
- android数据库操作使用过程说明
- Android SQLite数据库增删改查操作的案例分析
- 一个典型的数据库操作事务死锁分析
- 数据库操作_连接SQL Server数据库示例;连接ACCESS数据库;连接到 Oracle 数据库示例;SqlCommand 执行SQL命令示例;SqlDataReader 读取数据示例;使用DataAdapter填充数据到DataSet;使用DataTable存储数据库表;将数据库数据填充到 XML 文件;10 使用带输入参数的存储过程;11 使用带输入、输出参数的存储过程示;12 获得数据库中表的数目和名称;13 保存图片到SQL Server数据库示例;14 获得插入记录标识号;Exce
- 一个常见数据库操作错误的分析(六)
- 存储过程跨系统跨数据库操作
- 一个常见数据库操作错误的分析(二)
- 分析Android 根文件系统启动过程(init守护进程分析)
- SQL2K数据库开发二十九之存储过程操作查看存储过程 推荐
- 一个常见数据库操作错误的分析(一)
- 谈谈在开发过程中关于数据库操作的问题
- Mysql 数据库自动恢复的简单操作过程
- 关于在存储过程中使用游标操作数据库
- Hibernate 自动生成数据库表过程分析
- 一个常见数据库操作错误的分析(五)
- JSP数据库操作例程-存储过程
- 利用Java存储过程简化数据库操作