LitePal源码学习(2)——更新表流程(更新数据库)

add 2018/6/14

上一篇我讲述了LitePal建立表(创建数据库的流程),链接戳这里。这一篇看看LitePal是如何做到简便的升级数据库的。

加入你两张表Singer和Musiic,并且已经存了数据,结果发现Music表名字多打了一个 i ,Singer多了一个字段,并且想添加一张表Album,那么应该怎么做呢?使用过系统原生SQLite的人应该知道这将非常麻烦,但用LitePal却很简单,只需要按照“直觉”做:把Musiic类改名,把Singer类中多的字段删除,新建Album类并在litepal.xml中注册,最后将version加1并进行任何数据库操作就可以了。那么我们看他是如何实现的吧。

如上做过之后调用LitePal.getDataBase()会更新数据库,我在上一篇中讲过这个调用流程,这次由于在xml解析后得到的version比原version高,所以会在LitePalOpenHelper中执行onUpgrade:

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		Generator.upgrade(db);
		SharedUtil.updateVersion(LitePalAttr.getInstance().getExtraKeyName(), newVersion);
	}

第二行我就不展开了,很显然是将当前version以SharedPreferences进行存储,我们看Generator.upgrade(db):

	static void upgrade(SQLiteDatabase db) {
		drop(db);
		create(db, false);
		updateAssociations(db);
		upgradeTables(db);
		addAssociation(db, false);
	}

简单的一行代码LitePal要进行五项操作,我先总体描述他们所做的工作:

(1)drop:将原本在mapping中声明但本次不在的表删除(最后总要更新Table_Schema,之后我不会再提了);

(2)create:将原本不在mapping中但本次添加的表创建;

(3)updateAssociations:若关联的两张表有任意一张被删除,将它们之间的关联删除;

(4)upgradeTables:更新实体类做了修改的表,如上面提到的删除某个字段;

(5)addAssociation:添加新产生的关联。

看似内容很多,但和创建表有很多相似之处,先来看

(1)Generator.drop(db):

	private static void drop(SQLiteDatabase db) {
		Dropper dropper = new Dropper();
		dropper.createOrUpgradeTable(db, false);
	}

Dropper.createOrUpgradeTable(db, false):

	@Override
	protected void createOrUpgradeTable(SQLiteDatabase db, boolean force) {
		mTableModels = getAllTableModels();
		mDb = db;
		dropTables();
	}

getAllTableModels这样的在上一篇提到过的方法就直接略过了,接下来是dropTables():

	private void dropTables() {
		List<String> tableNamesToDrop = findTablesToDrop();
		dropTables(tableNamesToDrop, mDb);
		clearCopyInTableSchema(tableNamesToDrop);
	}

按照顺序,先看看如何判别哪些表需要删除:

	private List<String> findTablesToDrop() {
		List<String> dropTableNames = new ArrayList<String>();
		Cursor cursor = null;
		try {
			cursor = mDb.query(Const.TableSchema.TABLE_NAME, null, null, null, null, null, null);//查询Table_Schema表所有数据
			if (cursor.moveToFirst()) {
				do {
					String tableName = cursor.getString(cursor
							.getColumnIndexOrThrow(Const.TableSchema.COLUMN_NAME));//表名
					int tableType = cursor.getInt(cursor
							.getColumnIndexOrThrow(Const.TableSchema.COLUMN_TYPE));//0普通表,1中间表
					if (shouldDropThisTable(tableName, tableType)) {
						// need to drop tableNameDB
						LogUtil.d(TAG, "need to drop " + tableName);
						dropTableNames.add(tableName);
					}
				} while (cursor.moveToNext());
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			if (cursor != null) {
				cursor.close();
			}
		}
		return dropTableNames;
	}
	private boolean shouldDropThisTable(String tableName, int tableType) {
		return !BaseUtility.containsIgnoreCases(pickTableNamesFromTableModels(), tableName)
				&& tableType == Const.TableSchema.NORMAL_TABLE;
	}

findTablesToDrop()这个方法通过查询Table_Schema表,对存储的每个表名进行判断是否删除,将要删除表的表名全部放入一个List返回。判断的方法是shouldDropThisTable(String tableName, int tableType),会删除xml中不再存在且是普通类型的表。实际进行删除表的方法贴一下,我就不解释了,之前有类似的:

	protected void dropTables(List<String> dropTableNames, SQLiteDatabase db) {
		if (dropTableNames != null && !dropTableNames.isEmpty()) {
            List<String> dropTableSQLS = new ArrayList<String>();
			for (int i = 0; i < dropTableNames.size(); i++) {
                dropTableSQLS.add(generateDropTableSQL(dropTableNames.get(i)));
			}
			execute(dropTableSQLS, db);
		}
	}

最后更新一下Table_Schema,一个drop操作就结束了。

(2)create(db, false):和创建表操作的create使用的是同一个方法,只是第二个参数不再是true而是false,还有印象的话,false表示对已经存在的表不做任何操作,只新建不存在的表。

(3)updateAssociations(db):

	private static void updateAssociations(SQLiteDatabase db) {
		AssociationUpdater associationUpgrader = new Upgrader();
		associationUpgrader.addOrUpdateAssociation(db, false);
	}

可能会觉得addOrUpdateAssociation这个方法比较眼熟&

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值