android自动更新列表,Android数据库表结构自动升级

Android App开发如果涉及过数据库的朋友们肯定会碰到数据库升级的工作,Android官方的建议办法是override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)并在其中通过数据库版本比较写SQL增加表字段、创建新表等操作来达到数据库升级的功能,思路非常OK,但是项目做久了发现这块代码变超级庞大,仔细一看全是流水账代码,自己项目中曾经也是如此,时间久了代码量十分恐怖,关键的是无法通过重构减少代码量,类似如下:

8eb1622feace

db_upgrade.png

其实,之前写过一个轻量级的SQLite ORM,已经做到数据库自动创建,通过以面向对象方式进行增删改查,非常缺少自动升级这个功能。

通过查阅相关资料,得知sqlite数据库里默认会生成两个表分别是:sqlite_sequence和sqlite_master,今天看的是sqlite_master,里面存放了每张表结构(创建表的SQL):

8eb1622feace

sqlite_master.png

所以,思路就很简单了,同过检索此表可以知道新建的表是否在其中存在:

不存表在则创建新表;

存在表再检查所有字段是否存在,不存在则加字段(数据库升级的原则就是只增不减);

所以,写两个工具方法即可:

static boolean isTableExist(SQLiteDatabase db, String tableName) {

Cursor cursor = null;

try {

cursor = db.rawQuery("SELECT count(*) FROM sqlite_master WHERE type='table' AND name=?", new String[]{tableName});

boolean hasNext = cursor.moveToNext();

return hasNext && cursor.getInt(0) > 0;

} finally {

if (cursor != null) {

cursor.close();

}

}

}

static boolean isColumnExist(SQLiteDatabase db, String tableName, String columnName) {

Cursor cursor = null;

try {

cursor = db.rawQuery("SELECT count(*) FROM sqlite_master WHERE tbl_name = ? AND (sql LIKE ? OR sql LIKE ?);",

new String[]{tableName, "%(" + columnName + "%", "%, " + columnName + " %"});

boolean hasNext = cursor.moveToNext();

return hasNext && cursor.getInt(0) > 0;

} finally {

if (cursor != null) {

cursor.close();

}

}

}

如何运用2个方法自动升级呢:

@Override

public final void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

autoMigrate(db, mTableClasses);

}

private void autoMigrate(SQLiteDatabase db, List> tableClasses) {

for (Class extends Entity> clazz : tableClasses) {

String tableName = ReflectTools.getTableName(clazz);

boolean exist = ReflectTools.isTableExist(db, tableName);

if (exist) {

Field[] fields = ReflectTools.getClassFields(clazz);

for (Field field : fields) {

Column column = field.getAnnotation(Column.class);

if (column == null) {

continue;

}

String columnName = !TextUtils.isEmpty(column.name()) ? column.name() : field.getName();

String dataType = ReflectTools.getDataTypeByField(field);

boolean columnExist = ReflectTools.isColumnExist(db, tableName, columnName);

if (!columnExist) {

db.execSQL("ALTER TABLE " + tableName + " ADD " + columnName + " " + dataType);

}

}

} else {

db.execSQL(SQLBuilder.buildCreateSQL(clazz).getSql());

}

}

}

可能你们已经注意到这里有几个外来方法和变量,它们来自于上面所说的轻量级SQLite ORM,还有请注意onUpgrade()是加了final修饰的,意味着子类无需手动升级了。

所以,关于数据库升级,你所需要做的事情就是该创建表对象的就创建表对象,该加字段的就加字段,最后别忘记把数据库版本号升级下就好了,因为只有当Android检测出你的数据库版本好变了才会走进onUpgrade()。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值