android sql前10条,android SQL数据库操作心得

最近由嵌入式转到Android开发,在学习Android SQL数据库的使用时遇到了一些问题,并分析Android源码明白了其中的原因,想记录下来与大家分享。

在《第一行代码》第六章:SQLite数据库存储,在没有删除数据库或者卸载程序的情况下,连续创建2次相同的数据库,只会执行一次onCreate()。但是只要在创建SQLiteOpenHelper对象实例时修改一下本版号就会执行onUpgrade()方法。下面我们将从源代码的角度分析为什么会这样。

书上的源代码:

`

public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {

super(context, name, factory, version);

mContext = context;

}

`

其中MyDatabaseHelper继承于SQLiteOpenHelpe

public class MyDatabaseHelper extends SQLiteOpenHelpe

首先,我们看一下在创建SQLiteOpenHelper对象实例时会发生什么。

`

public SQLiteOpenHelper(@Nullable Context context, @Nullable String name,

@Nullable CursorFactory factory, int version) {

this(context, name, factory, version, null);

}

`

继续深究下去,下面就是不断的跟踪下去执行的代码:

`

public SQLiteOpenHelper(@Nullable Context context, @Nullable String name,

@Nullable CursorFactory factory, int version,

@Nullable DatabaseErrorHandler errorHandler) {

this(context, name, factory, version, 0, errorHandler);

}

public SQLiteOpenHelper(@Nullable Context context, @Nullable String name,

@Nullable CursorFactory factory, int version,

int minimumSupportedVersion, @Nullable DatabaseErrorHandler errorHandler) {

this(context, name, version, minimumSupportedVersion,

new SQLiteDatabase.OpenParams.Builder());

mOpenParamsBuilder.setCursorFactory(factory);

mOpenParamsBuilder.setErrorHandler(errorHandler);

}

private SQLiteOpenHelper(@Nullable Context context, @Nullable String name, int version,

int minimumSupportedVersion,

@NonNull SQLiteDatabase.OpenParams.Builder openParamsBuilder) {

Objects.requireNonNull(openParamsBuilder);

if (version < 1) throw new IllegalArgumentException("Version must be >= 1, was " + version);

mContext = context;

mName = name;

mNewVersion = version;

mMinimumSupportedVersion = Math.max(0, minimumSupportedVersion);

setOpenParamsBuilder(openParamsBuilder);

}

`

从上面就可以看出,在执行SQLiteOpenHelper构造方法时还没有创建数据库,只是保存一些参数值而已。

而创建和打开数据库主要通过2个方法:getWritableDatabase()和getWritableDatabase(),那么我们跟踪其中一个方法,以getWritableDatabase()为例。

`

public SQLiteDatabase getWritableDatabase() {

synchronized (this) {

return getDatabaseLocked(true);

}

}

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.createInMemory(mOpenParamsBuilder.build());

} else {

final File filePath = mContext.getDatabasePath(mName);

SQLiteDatabase.OpenParams params = mOpenParamsBuilder.build();

try {

db = SQLiteDatabase.openDatabase(filePath, params);

// Keep pre-O-MR1 behavior by resetting file permissions to 660

setFilePermissionsForDb(filePath.getPath());

} catch (SQLException ex) {

if (writable) {

throw ex;

}

Log.e(TAG, "Couldn't open " + mName

+ " for writing (will try read-only):", ex);

params = params.toBuilder().addOpenFlags(SQLiteDatabase.OPEN_READONLY).build();

db = SQLiteDatabase.openDatabase(filePath, params);

}

}

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);

}

if (version > 0 && version < mMinimumSupportedVersion) {

File databaseFile = new File(db.getPath());

onBeforeDelete(db);

db.close();

if (SQLiteDatabase.deleteDatabase(databaseFile)) {

mIsInitializing = false;

return getDatabaseLocked(writable);

} else {

throw new IllegalStateException("Unable to delete obsolete database "

+ mName + " with version " + version);

}

} else {

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();

}

}

}

`

代码比较长,我们只截取其中代码片段分析,可以参考上面的完整代码,好理解我讲的是什么。

`

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;

}

}

`

从这里我们可以看出,如果之前已经创建了数据库对象实例mDatabase且权限是可读可写则之间返回之前已经创建号的对象实例。

从之前跟踪SQLiteOpenHelper构造方法时我们就知道,version和mMinimumSupportedVersion已经被设置为0。那么根据以下代码片段:

`

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);

}

** if (version > 0 && version < mMinimumSupportedVersion) {File databaseFile = new File(db.getPath());

onBeforeDelete(db);

db.close();

if (SQLiteDatabase.deleteDatabase(databaseFile)) {

mIsInitializing = false;

return getDatabaseLocked(writable);

} else {

throw new IllegalStateException("Unable to delete obsolete database "

+ mName + " with version " + version);

}

} else {

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();

}

}**

}`

**此时version == 0条件成立,则说明在第一次创建SQLiteOpenHelper对象实例时会执行一次onCreate()方法,当下次不改变版本号时再次调用getWritableDatabase()方法时,则不会执行onCreate()了。**当下次改变版本号时再次调用getWritableDatabase()方法,此时version不再为0,且当新版本号增大时则会调用:onUpgrade()方法。否则调用onDowngrade()方法。

总结,在多次构造SQLiteOpenHelper对象实例时,如果版本号不变则只会执行一次onCreate()方法,当将新版本号增大后,则会调用onUpgrade()方法,否则调用onDowngrade()方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值