Android数据库表的创建和数据升级操作

之前的文章有提到,可以在xml文件中配置数据库信息:http://www.cnblogs.com/wenjiang/p/4492303.html,现在就讲如何利用这些信息类构建数据库。

xml文件大概如下:

<?xml version="1.0" encoding="utf-8"?>
<database>
    <!-- 数据库名称 -->
    <dbname value="zwb.db"></dbname>

    <!-- 数据库版本 -->
    <version value="1"></version>

    <!-- 数据库表 -->
    <list>
        <mapping class="com.zwb.args.dbpratice.model.Status"></mapping>
        <mapping class="com.zwb.args.dbpratice.model.User"></mapping>
    </list>
</database>

读取出来的信息其实很简单:数据库名字,数据库版本和数据库表。

Android原本就提供了SQLiteOpenHelper来帮助我们完成数据库的一些基本操作,所以这里还是需要实现SQLiteOpenHelper的。

定义一个SQLiteOpenHelper,在初始化的时候将数据库名字和数据库版本传进去:

 public BaseSQLiteOpenHelper(Context context, String name, int version) {
    super(context, name, null, version);
}

接下来就是在onCreate方法中实现创建表的动作:

考虑到数据升级的问题,我将有关数据升级的操作都放在一个方法中,然后在onUpgrade方法中调用onCreate就行了。

这里只考虑数据升级的问题,当然,降级也是可以的,不过一般这种情况在移动端比较少见。

之前将包含数据库的表名的List存储进SharedPreferencesManager中,当然,一般的SharedPreferencesManager是不能存储容器类的,但这里我进行了扩展,具体的实现后面有需要再拿出来。

数据库是在xml文件中配置数据库表的信息,所以必须判断从xml文件中读取出来的数据库信息是否还是和之前一致,如果原先的配置信息没有的话,就要创建表(哪怕只是修改表名,都当做是重新创建表,这是无可置疑的,因为修改旧表后还指望能够将数据迁移到新表中,说明一开始建表时候实在是太草率了。。。),如果原先的配置有,现在没有,说明是要删除旧表。

List<String> oldTableList = SharedPreferencesManager.getInstance().getListString("tables");
if (oldTableList.size() != 0) {

     for (String table : oldTableList) {
          if (!DatabaseCache.tableSet.contains(table)) {
                dropTable(db, table);
          }
     }

     for (String table : DatabaseCache.tableSet) {
           if (!oldTableList.contains(table)) {
                createTable(db, table);
           }
      }
}

dropTable的实现非常简单:

 String deleteSql = "drop table if exists " + table;
 db.execSQL(deleteSql);

createTable的实现也不复杂,同样是拼接SQL语句:

    private void createTable(SQLiteDatabase db, String table) {
        try {
            StringBuilder sql = new StringBuilder("create table if not exists ");
            BaseTable entity = (BaseTable) (Class.forName(table).newInstance());
            String tableName = getTableName(entity);
            sql.append(tableName);
            sql.append(" (id integer primary key autoincrement, ");
            List<String> columnList = getColumns(entity);
            for (int i = 0, length = columnList.size(); i < length; i++) {
                sql.append(columnList.get(i) + " ");
                if (i == length - 1) {
                    break;
                }
                sql.append(", ");
            }
            sql.append(");");
            db.execSQL(sql.toString());
        } catch (InstantiationException e) {
            LogUtil.e(e.toString());
        } catch (IllegalAccessException e) {
            LogUtil.e(e.toString());
        } catch (ClassNotFoundException e) {
            LogUtil.e(e.toString());
        } catch (NoSuchTableException e) {
            LogUtil.e(e.toString());
        }
    }

Android本身也提供了对SQL语句的封装,但实际上,使用Android的API还是不如自己写SQL。。。

如果应用是第一次安装,那么数据库的创建动作就结束了,最后只要将新的配置信息存储到SharedPreferencesManager中就行。

但如果是数据库升级,在执行完上面的操作,表是该删的删,该建的的建,但如果要做数据迁移,比如说,某张表增加了一些字段(这里不做删除字段的处理,就算有多余字段的数据保留也并不是个问题,比起丢失数据的严重性来说,一定程度的冗余字段还是可以接受的)。

实现也是比较简单,就是几个步骤:将旧表重命名为一个临时表保存数据,创建旧表,将临时表的数据迁移到旧表中,删除临时表,每个步骤都是SQL语句的拼接而已:

       for (String tableEntity : DatabaseCache.tableSet) {
            try {
                BaseTable entity = (BaseTable) (Class.forName(tableEntity).newInstance());
                db.beginTransaction();
                String table = getTableName(entity);
                String selectSql = "select * from " + table;
                Cursor cursor = db.rawQuery(selectSql, null);
                List<String> oldColumns = new ArrayList<>();
                for (String column : cursor.getColumnNames()) {
                    oldColumns.add(column);
                }
                String alterSql = "alter table " + table + " rename to " + table + "_temp";
                db.execSQL(alterSql);

                createTable(db, tableEntity);

                List<String> newColumns = getColumnFrom(tableEntity);
                StringBuilder upgradeSqlBuilder = new StringBuilder("insert into " + table + " select id, ");
                int i = 0;
                for (String column : newColumns) {
                    if (oldColumns.contains(column)) {
                        upgradeSqlBuilder.append(column + ", ");
                        i++;
                    }
                }

                if ((i != 0) && (i < newColumns.size())) {
                    for (int j = 0, length = newColumns.size() - i; j < length; j++) {
                        upgradeSqlBuilder.append("‘‘, ");
                    }
                }

                String upgradeStr = upgradeSqlBuilder.toString();
                String upgradeSql = upgradeStr.substring(0, upgradeStr.length() - 2) + " from " + table + "_temp";
                db.execSQL(upgradeSql);
                dropTable(db, table + "_temp");
                db.setTransactionSuccessful();
                db.endTransaction();
            } catch (InstantiationException e) {
                LogUtil.e(e.toString());
            } catch (IllegalAccessException e) {
                LogUtil.e(e.toString());
            } catch (ClassNotFoundException e) {
                LogUtil.e(e.toString());
            } catch (NoSuchTableException e) {
                LogUtil.e(e.toString());
            }
        }

由于涉及到的数据库操作比较多,我就将这些操作放在事务中执行。

到了这里,根据读取的xml配置信息,应用的数据库信息就创建出来了。

时间: 2024-12-23 18:24:10

Android数据库表的创建和数据升级操作的相关文章

数据库表的创建、管理和数据操作(实验一),数据库创建

数据库表的创建.管理和数据操作(实验一),数据库创建 今天我们就以实验的形式对表的创建.管理和数据操作进行学习,上课吧. [实验目的]:了解SQL语言的使用,进一步理解关系运算,巩固数据库的基础知识.[实验要求]:利用SQL语言进行数据库表的各种操作:1.数据库表的创建.修改和删除操作.2.向表中进行数据的插入.删除和修改操作.[实验内容]1. 利用数据定义语句在实验一创建的stu_DB库中建立学生管理系统的三个表:Student.Course.SC.2.利用INSERT.UPDATE和DELE

Android数据库更新并保留原来数据的实现

Android应用程序更新的时候如果数据库修改了字段需要更新数据库,并且保留原来的数据库数据: 这是原有的数据库表 CREATE_BOOK = "create table book(bookId integer primarykey,bookName text);"; 然后我们增加一个字段: CREATE_BOOK = "create table book(bookId integer primarykey,bookName text,bookContent text);&q

oracle数据库表中,插入数据的时候如何产生一个 字母+数字 编号?

Oracle 语句中"||"代表什么啊? oracle数据库表中,插入数据的时候如何产生一个 字母+数字 编号? 排序的话,用order by来处理即可.比如:cola123a234b999b335select * from tablename order by col; 结果就是 cola123a234b335b999 如果按倒序排列:select * from tablename order by col desc; 结果就是 colb999b335a234a123 其他回答 先创

电子商城开发之目录与数据库表的创建

1.前台功能---首页---品牌页面---商品详情---商品评论管理---购物车管理---结算页面---用户登陆和退出---个人中心管理---订单提交页面 2.后台功能---登陆系统---用户管理---分类管理---品牌管理---商品管理---订单状态管理---订单管理 ----------------------------------------------------------------------------------------- 数据库表的创建: user表: //用户管理表-

修改SQL Server数据库表的创建时间最简单最直接有效的方法

说明:这篇文章是几年前我发布在网易博客当中的原创文章,但由于网易博客现在要停止运营了,所以我就把这篇文章搬了过来,因为这种操作方式是通用的,即使是对现在最新的SQL Server数据库里面的操作也是一样的,相信很多朋友都会使用到. ----------------------分割线-------------------- 网络上曾经有很多人询问怎么修改SQL Server数据库表的创建时间,但得到的回答多种多样,有的说需要使用某些软件进行修改,有的说需要修改注册表等等,其实这些方法实施起来不但麻

EF 学习系列二 数据库表的创建和表关系配置(Fluent API、Data Annotations、约定)

上一篇写了<Entity Farmework领域建模方式 3种编程方式>,现在就Code First 继续学习 1.数据库表的创建 新建一个MVC的项目,在引用右击管理NuGet程序包,点击浏览搜索EF安装,我这里主要是EF6.0 以上的学习 所以都安装6.0 以上的版本 接下来在Model文件夹下面创建一个Customer类 public class Customer { public int ID { get; set; } public string Name { get; set; }

Android数据库高手秘籍(三)——使用LitePal升级表

在上一篇文章中,我们学习了LitePal的基本用法,体验了使用框架来进行创建表操作的便利.然而大家都知道,创建表只是数据库操作中最基本的一 步而已,我们在一开始创建的表结构,随着需求的变更,到了后期是极有可能需要修改的.因此,升级表的操作对于任何一个项目也是至关重要的,那么今天我们就 一起来学习一下,在Android传统开发当中升级表的方式,以及使用LitePal来进行升级表操作的用法.如果你还没有看过前一篇文章,建议先去参考 一下 Android数据库高手秘籍(二)——创建表和LitePal的

oracle数据库表空间创建&amp;导入&amp;导出

1.表空间创建 --删除表空间 drop tablespace EVPBDMGIS including contents and datafiles; --删除用户 drop user EVPBDMGIS cascade; --创建表空间 create tablespace EVPBDMGIS datafile 'D:\app\Administrator\oradata\orcl\EVPBDMGIS.DBF' size 500m reuse autoextend on next 16m maxs

Oracle数据库——表的创建与管理

一.涉及内容 1.掌握使用OEM工具创建.修改和删除表. 2.掌握使用SQL语句创建.修改和删除表. 3.掌握使用SQL语句插入.修改和删除数据. 4.理解各种约束的作用,并能够使用OEM工具和SQL命令为表创建各种约束. 二.具体操作 (一)分别使用OEM和SQL语句完成下面的内容. 1.创建表并添加相应的约束.要求: (1)创建名为student(学生信息)的表,表中各列要求如下: 字段名称 字段类型 大小 说明 sno CHAR 10 主键 sname VARCHAR 8 sex CHAR