XML帮你轻松升级改写数据库——让你摆脱不停改写onUpgrade痛苦

转载请标明出处:
http://blog.csdn.net/liuzg1220;
本文出自:【HugeBug的博客】


简介

在项目研发过程中我们经常会遇到,数据库字段没有定义全,之后版本迭代的过程中不停的删除、增加、修改字段的情况。经常改写代码去维护数据库,这样的是我可是不愿干,于是我自己想了一个不知道算不算办法的办法。

分析

1.我们先定义好要维护的xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<tables xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.xmlupdateBb.org/testtable" >
<!-- 修改该的表名 -->
            <!-- 操作 -->
            <!-- 操作的字段名 -->
            <!-- 字段修改后的类型 -->
            <!-- 字段默认值 -->
    <table tableName="Student">
        <column 
            operation = "add"
            columnName="isPeer"
            type="String"
            defValue=""></column>
    </table>
    
    <table tableName="Student">
        <column 
            operation = "add"
            columnName="siteCode"
            type="String"
            defValue=""></column>
    </table>
</tables>

2.然后根据xml配置文件中"table"标签定义好对应的实体类DbConfigBean:

package com.lzg.xmlupdatedb.updatedbutils;

/**
 * 数据库升级dbConfig.xml的bean类
 * 
 * @author lzg
 *
 */
public class DbConfigBean {

	private String table;
	private String column;
	/**
	 * 1 add, 2 del, 3 rename需要其他的操作可以自己定义
	 */
	private byte operation;
	private String type;
	private String defValue;

	public DbConfigBean() {
		super();
	}

	public DbConfigBean(String table, String column, byte operation,
			String type, String defValue) {
		super();
		this.table = table;
		this.column = column;
		this.operation = operation;
		this.type = type;
		this.defValue = defValue;
	}

	public String getTable() {
		return table;
	}

	public String getColumn() {
		return column;
	}

	public byte getOperation() {
		return operation;
	}

	public String getType() {
		return type;
	}

	public void setTable(String table) {
		this.table = table;
	}

	public void setColumn(String column) {
		this.column = column;
	}

	public void setOperation(byte operation) {
		this.operation = operation;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getDefValue() {
		return defValue;
	}

	public void setDefValue(String defValue) {
		this.defValue = defValue;
	}

}

3.接下来带看一下我们是如何根据xml的配置知道如何升级数据库的,根据xml配置文件解析生成DBConfigBean的数据集进行数据库的onUpgrade操作。

  a.先看一下如何解析xml的吧:

/**
     * 解析xml配置,将xml中配置解析为对应的DBConfigBean数据集
     * 
     * @param fileName
     * @return
     */
    public static List<DbConfigBean> parserConfig(String fileName) {
        /**
         * 
         */
        StringBuilder sb = new StringBuilder(Const.PATH);
        List<DbConfigBean> list = null;
        if (!"".equals(fileName)) {
            String url = sb.append(fileName).toString();
            BufferedInputStream in = new BufferedInputStream(
                    XMLParserUtils.class.getClassLoader().getResourceAsStream(
                            url));

            XmlPullParserFactory factory = null;
            XmlPullParser parser = null;
            DbConfigBean dbConfigBean = null;
            /**
             * 根据xml配置文件解析生成对应的DbConfigBean实例对象。
             */
            try {
                factory = XmlPullParserFactory.newInstance();
                factory.setNamespaceAware(true);
                parser = factory.newPullParser();
                parser.setInput(in, "UTF-8");

                for (int type = parser.getEventType(); type != XmlPullParser.END_DOCUMENT; type = parser
                        .next()) {
                    switch (type) {
                    case XmlPullParser.START_DOCUMENT:
                        list = new ArrayList<DbConfigBean>();
                        break;
                    case XmlPullParser.START_TAG:
                        if ("table".equals(parser.getName())) {

                            String table = parser.getAttributeValue(null,
                                    "tableName");
                            if (table != null) {
                                dbConfigBean = new DbConfigBean();
                                dbConfigBean.setTable(parser.getAttributeValue(
                                        null, "tableName"));
                            }
                        }
                        if (dbConfigBean != null) {
                            if ("column".equals(parser.getName())) {
                                /* 解析操作 */
                                String operation = parser.getAttributeValue(
                                        null, "operation");
                                if (operation != null && !operation.equals("")) {
                                    if (operation.equals(Const.ADD_DESCRIPTION)) {
                                        dbConfigBean.setOperation(Const.ADD);
                                    }
                                    /*
                                     * else if (条件) { .......
                                     * }......大家可以根据需要增加操作
                                     */

                                }

                                String column = parser.getAttributeValue(null,
                                        "columnName");
                                if (column != null && !operation.equals("")) {
                                    dbConfigBean.setColumn(parser
                                            .getAttributeValue(null,
                                                    "columnName"));
                                }

                                String datatype = parser.getAttributeValue(
                                        null, "type");
                                if (datatype != null && !operation.equals("")) {
                                    dbConfigBean.setType(parser
                                            .getAttributeValue(null, "type"));
                                }

                                dbConfigBean.setDefValue(parser
                                        .getAttributeValue(null, "defValue"));
                            }
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        if ("column".equals(parser.getName())) {
                            list.add(dbConfigBean);
                            dbConfigBean = null;
                        }
                        break;
                    default:
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (list != null) {
            return list;
        } else {
            return null;
        }

    }

  b.接着看一下如何改写数据库更新方法"onUpgrade":

/**
     * 更新数据库操作
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource,
            int oldVersion, int newVersion) {
        String sqlStr = null;
        String sqlRename = null;
        String sqlInsert = null;
        String sqlDrop = null;
        List<DbConfigBean> beanList = XMLParserUtils
                .parserConfig(Const.DBCONFIG_NAME);
        if (beanList != null) {
            for (DbConfigBean bean : beanList) {
                if (bean != null) {
                    byte operation = bean.getOperation();
                    /* 根据要求进行数据库更新操作 */
                    switch (operation) {
                    case Const.ADD:
                        sqlStr = "ALTER TABLE " + bean.getTable()
                                + " ADD COLUMN " + bean.getColumn() + " "
                                + bean.getType();
                        break;
                    }
                    /* ........大家可以根据自己的需要增加操作 */
                    try {
                        db.execSQL(sqlStr);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            }
        }
    }

OK!到这里基本思路已经出来了,我们在梳理一下,总思路:我们为了减少对"onUpgrade"方法的修改,方便数据库升级使用的是xml配置进行数据库升级操:

   NO.1 定义自己的xml配置文件

   NO.2 根据xml配置定义对应的数据实体类

   NO.3 解析xml得到数据操作集,同时重写数据库升级方法"onUpgrade"

说了这么多废话你是不是已经有点烦了,迫不及待的想看到效果,等等别急,我们还不能忘记在进行数据库升级时要同时修改xml中涉及的到数据表!

看一下效果吧:

1.我定义了一张Sudent表:

package com.lzg.xmlupdatedb.entity;

import java.io.Serializable;

import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;

@DatabaseTable(tableName = "Student")
public class Student implements Serializable {

	/**
	 * 学生表测试类
	 */
	private static final long serialVersionUID = -118421523502838450L;
	@DatabaseField(generatedId = true)
	private Integer id;
	@DatabaseField
	private String name;
	@DatabaseField
	private String sex;
	@DatabaseField
	private String no;
	@DatabaseField
	private String num;
	

	public Student() {
		super();
	}

	public Student(String name, String sex, String no, String num) {
		super();
		this.name = name;
		this.sex = sex;
		this.no = no;
		this.num = num;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public String getNo() {
		return no;
	}

	public void setNo(String no) {
		this.no = no;
	}

	public String getNum() {
		return num;
	}

	public void setNum(String num) {
		this.num = num;
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	}

}

2.我添加了一个AndroidTestCase的类在里面用test()方法进行测试。使用AndroidTestCase 需要在AndroidManifest.xml的manifest标签中增加这个说明:


   <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="包名" />

 在application标签中加上这行:

<uses-library android:name="android.test.runner" />

运行完test()方法之后我们用RE看一下Student表中如下图:

public class TestClass extends AndroidTestCase {

	/**
	 * 测试方法
	 */
	public void test() {

		DatbaseHelper datbaseHelper = DatbaseHelper.getHelper(getContext());
		Student student = new Student("草泥马领导", "nv", "22", "33");
		try {
			datbaseHelper.createStudent(getContext(), student);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


接下来我对xml配置文件改成这样:

<?xml version="1.0" encoding="UTF-8"?>
<tables xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.xmlupdateBb.org/testtable" >
<!-- 修改该的表名 -->
            <!-- 操作 -->
            <!-- 操作的字段名 -->
            <!-- 字段修改后的类型 -->
            <!-- 字段默认值 -->
    <table tableName="Student">
        <column 
            operation = "add"
            columnName="greed"
            type="String"
            defValue=""></column>
    </table>
</tables>

再次运行test()我们在看看Student表,当然不要忘记修改Student类还有数据库的版本号:


是不是成功的实现了修改xml就可以进行数据库升级操作了!!!


如果你觉得有用就关注我吧,在这里将不定期的发表原创文章!如果你觉得有用就留个言,点个赞吧!

下面是我微信公众号:如果你喜欢就扫扫看吧!


完整源码下载


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值