android数据库数据丢失

2017-01-15 12:21:05 fszeng2011 阅读数 906

相信不少人在做项目时会数据库升级,可能涉及到数据结构的变化,下面写了个工具类,可以帮助在数据结构变化时,保留原数据不丢。

/**
 * Created by zeng on 2017/1/13.
 * 为了适用于如greenDao这样的框架,使用反射调用相应的方法
 */
public class DbUtils {
	
	public static class Column {
		public static final String INTEGER = "INTEGER";
		public static final String TEXT = "TEXT";
		public static final String REAL = "REAL";
		public static final String DATE = "DATE";
		public String name;
		public String type;
		public Object defualtValue;

		public Column() {
		}

		public Column(String name, String type, Object defualtValue) {
			this.name = name;
			this.type = type;
			this.defualtValue = defualtValue;
		}
	}
	
	private static void execSQL(Object db, String sql) {
		try {
			db.getClass().getMethod("execSQL", String.class).invoke(db, sql);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private static void execSQL(Object db, String sql, Object[] bindArgs) {
		try {
			db.getClass().getMethod("execSQL", String.class, Object[].class).invoke(db, sql, bindArgs);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private static void invokeVoidNoPrama(Object db, String methodName) {
		try {
			db.getClass().getMethod(methodName).invoke(db);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private static void beginTransaction(Object db) {
		invokeVoidNoPrama(db, "beginTransaction");
	}
	
	private static void endTransaction(Object db) {
		invokeVoidNoPrama(db, "endTransaction");
	}
	
	private static void setTransactionSuccessful(Object db) {
		invokeVoidNoPrama(db, "setTransactionSuccessful");
	}
	
	/**
	 * 重命名表
	 */
	public static void renameTable(Object db, String oldName, String newName) {
		try {
			execSQL(db, "ALTER TABLE " + oldName + " RENAME TO " + newName);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 删除表
	 */
	public static void deleteTable(Object db, String tableName) {
		try {
			execSQL(db, "DROP TABLE " + tableName);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取数据表的所有字段名
	 */
	public static Column[] getColumns(Object db, String tableName) {
		Column[] columns = null;
		Cursor cursor = null;
		try {
			String sql = "PRAGMA table_info(" + tableName + ")";
			Method method = db.getClass().getMethod("rawQuery", String.class, String[].class);
			cursor = (Cursor) method.invoke(db, sql, null);
			int nameIndex = cursor.getColumnIndex("name");
			if (nameIndex == -1) {
				return null;
			}
			int index = 0;
			columns = new Column[cursor.getCount()];
			for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
				columns[index] = new Column();
				columns[index].name = cursor.getString(nameIndex);
				columns[index].type = cursor.getString(cursor.getColumnIndex("type"));
				int defaultValueIndex = cursor.getColumnIndex("dflt_value");
				switch(cursor.getType(defaultValueIndex)) {
				    case Cursor.FIELD_TYPE_BLOB:
						columns[index].defualtValue = cursor.getBlob(defaultValueIndex);
						break;
				    case Cursor.FIELD_TYPE_FLOAT:
						columns[index].defualtValue = cursor.getDouble(defaultValueIndex);
						break;
					case Cursor.FIELD_TYPE_INTEGER:
						columns[index].defualtValue = cursor.getLong(defaultValueIndex);
						break;
					case Cursor.FIELD_TYPE_STRING:
						columns[index].defualtValue = cursor.getString(defaultValueIndex);
						break;
				}
				index++;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (cursor != null) {
				cursor.close();
			}
		}
		return columns;
	}

	/**
	 * 删除列
	 * @param columnNames 要删除的列名
	 */
	public static void deleteColumns(Object db, String tableName, String... columnNames) {
		try {
			beginTransaction(db);
			Column[] columns = getColumns(db, tableName);
			if (columns != null) {
				//重命名原表
				String tmpTableName = "t" + UUID.randomUUID().toString().replaceAll("-", "_");
				execSQL(db, "ALTER TABLE " + tableName + " RENAME TO " + tmpTableName);
				//新建表sql语句
				String newTableSql = "CREATE TABLE " + tableName + "(";
				List<String> list = Arrays.asList(columnNames);
				//复制数据sql语句
				String copySql = "INSERT INTO " + tableName + " SELECT ";
				for (Column column : columns) {
					if (!list.contains(column.name)) { 
						newTableSql += column.name + " " + column.type + ",";
						copySql += column.name + ",";
					}
				}
				newTableSql = newTableSql.substring(0, newTableSql.length() - 1) + ")";
				execSQL(db, newTableSql);
				//复制数据到新表
				copySql = copySql.substring(0, copySql.length() - 1) + " FROM " + tmpTableName;
				execSQL(db, copySql);
				//删除临时表
				execSQL(db, "DROP TABLE " + tmpTableName);
			}
			setTransactionSuccessful(db);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			endTransaction(db);			
		}		
	}

	/**
	 * 添加列
	 * @param columns 需要添加的列的信息
	 */
	public static void addColumns(Object db, String tableName, Column... columns) {
		try {
			beginTransaction(db);
			for (Column column : columns) {
				String sql = "ALTER TABLE " + tableName + " ADD " + column.name + " " + column.type;
				Object[] bindArgs = null;
				if (column.defualtValue != null) {
					if (column.defualtValue instanceof String) {
					    sql += " DEFAULT '" + column.defualtValue + "'";
					} else if (column.defualtValue instanceof byte[]) {
						//如果是字节数组,先插入列,再设置默认数据
					    execSQL(db, sql);
						sql = "UPDATE " + tableName + " SET " + column.name + "=?";
						bindArgs = new Object[]{column.defualtValue};
					} else {
					    sql += " DEFAULT " + column.defualtValue;
					}
				}
				if (bindArgs == null) {
				    execSQL(db, sql);
				} else {
					execSQL(db, sql, bindArgs);
				}
			}
			setTransactionSuccessful(db);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			endTransaction(db);
		}
	}

	/**
	 * 更新列名
	 * @param map key为旧列名,value为新列名
	 */
	public static void updateColumnNames(Object db, String tableName, Map<String, String> map) {
		try {
			beginTransaction(db);
			Column[] columns = getColumns(db, tableName);
			if (columns != null) {
				//重命名原表
				String tmpTableName = "t" + UUID.randomUUID().toString().replaceAll("-", "_");
				execSQL(db, "ALTER TABLE " + tableName + " RENAME TO " + tmpTableName);
				//新建表sql语句
				String newTableSql = "CREATE TABLE " + tableName + "(";
				//复制数据sql语句
				String copySql = "INSERT INTO " + tableName + " SELECT ";
				Set<String> keySet = map.keySet();
				for (Column column : columns) {
					if (keySet.contains(column.name)) {
					    newTableSql += map.get(column.name) + " " + column.type + ",";
					} else {
					    newTableSql += column.name + " " + column.type + ",";
					}
					copySql += column.name + ",";
				}
				newTableSql = newTableSql.substring(0, newTableSql.length() - 1) + ")";
				execSQL(db, newTableSql);
				//复制数据到新表
				copySql = copySql.substring(0, copySql.length() - 1) + " FROM " + tmpTableName;
				execSQL(db, copySql);
				//删除临时表
				execSQL(db, "DROP TABLE " + tmpTableName);
			}
			setTransactionSuccessful(db);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			endTransaction(db);
		}
	}
}

源码下载

2015-12-24 11:00:41 shenyuanqing 阅读数 3109

上篇文章讲的是用DatabaseHelper新建一个数据库再进行增删改查,但大多数情景是数据库已经存在了,那怎么去访问呢?思路是先判断data/data/<package_name>/databases目录下数据库是否存在,如果不存在,用流操作把res/raw或assets目录下的数据库拷贝到data/data/<package_name>/databases目录,接下来就跟新建完数据库一样一样了。

核心代码

private void getData(){
        final String DATABASE_PATH="data/data/"+ this.getPackageName() + "/databases/";
        String databaseFile=DATABASE_PATH+"mydb.db";
        //创建databases目录(不存在时)
        File file=new File(DATABASE_PATH);
        if(!file.exists()){
            file.mkdirs();
        }
        //判断数据库是否存在
        if (!new File(databaseFile).exists()) {
            //把数据库拷贝到/data/data/<package_name>/databases目录下
            try {
                FileOutputStream fileOutputStream = new FileOutputStream(databaseFile);
                //数据库放assets目录下
                //InputStream inputStream = getAssets().open("mydb.db");
                //数据库方res/rew目录下
                InputStream inputStream=getResources().openRawResource(R.raw.mydb);
                byte[] buffer = new byte[1024];
                int readBytes = 0;

                while ((readBytes = inputStream.read(buffer)) != -1)
                    fileOutputStream.write(buffer, 0, readBytes);

                    inputStream.close();
                    fileOutputStream.close();
                } catch (IOException e) {
            }
        }
        db = SQLiteDatabase.openOrCreateDatabase(databaseFile, null);
    }





2017-09-26 17:47:05 owenchan1987 阅读数 1030

在我们开发的应用中,一般都会涉及到数据库,使用数据的时候会涉及到数据库的升级、数据的迁移、增加行的字段等。比如,用户定制数据的保存,文件的端点续传信息的保存等都会涉及到数据库。

我们应用第一个版本是V1.0,在迭代版本V1.1 时,我们在数据库中增加了一个字段。因此V1.0的数据库在V1.1版本需要升级,V1.0版本升级到V1.1时原来数据库中的数据不能丢失,那么在V1.1中就要有地方能够检测出来版本的差异,并且把V1.0软件的数据库升级到V1.1软件能够使用的数据库。也就是说,要在V1.0软件的数据库的那个表中增加那个字段,并赋予这个字段默认值。
应用中怎么检测数据库需要升级呢? SQLiteOpenHelper 类中有一个方法

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

当我们创建对象的时候如果传入的版本号大于之前的版本号,该方法就会被调用,通过判断oldVersion 和 newVersion 就可以决定如何升级数据库。在这个函数中把老版本数据库的相应表中增加字段,并给每条记录增加默认值即可。新版本号和老版本号都会作为onUpgrade函数的参数传进来,便于开发者知道数据库应该从哪个版本升级到哪个版本。升级完成后,数据库会自动存储最新的版本号为当前数据库版本号。

数据库升级

SQLite提供了ALTER TABLE命令,允许用户重命名或添加新的字段到已有表中,但是不能从表中删除字段。并且只能在表的末尾添加字段,比如,为Orders 表中添加一个字段:”ALTER TABLE Order ADDCOLUMN Country”

代码如下:

 /**

 * Created by Owen Chan
 * On 2017-09-25.
 */

public class OrderDBHelper extends SQLiteOpenHelper {

    private static final int DB_VERSION = 1;
    private static final String DB_NAME = "Test.db";
    public static final String TABLE_NAME = "Orders";


    public OrderDBHelper(Context context, int version) {
        super(context, DB_NAME, null, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
       String sql = "create table if not exists " + TABLE_NAME + " (Id integer primary key, " +
               "CustomName text, OrderPrice integer)";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.e("owen", "DB onUpgrade");
        if (newVersion == 2) {
            db.execSQL("ALTER TABLE " + TABLE_NAME +  " ADD COLUMN Country");
            Cursor cr = db.rawQuery("select * from " + TABLE_NAME, null);
            while (cr.moveToNext()) {
                String name = cr.getString(cr.getColumnIndex("CustomName"));
                ContentValues values = new ContentValues();
                values.put("CustomName", name);
                values.put("Country", "China");
                db.update(TABLE_NAME, values, "CustomName=?", new String[] {name});
            }
            cr.close();
        }
    }
}
OrderDBHelper orderDBHelper = new OrderDBHelper(this, 2);
SQLiteDatabase db = orderDBHelper.getWritableDatabase();

ContentValues contentValues = new ContentValues();
contentValues.put("OrderPrice", 100);
contentValues.put("CustomName", "OwenChan");
db.insert(OrderDBHelper.TABLE_NAME, null, contentValues);


Log.e("owen", "create finish");

Cursor cr = db.rawQuery("select * from " + OrderDBHelper.TABLE_NAME , null);
while (cr.moveToNext()) {
    String name = cr.getString(cr.getColumnIndex("CustomName"));
    Log.e("owen", "name:" + name);
    String country = cr.getString(cr.getColumnIndex("Country"));
    Log.e("owen", "country:" + country);
}
cr.close();
db.close();

数据库的迁移

可以分一下几个步骤迁移数据库

1、 将表名改成临时表

ALTER TABLE Order RENAME TO _Order;

2、创建新表

CREATETABLE Test(Id VARCHAR(32) PRIMARY KEY ,CustomName VARCHAR(32) NOTNULL , Country VARCHAR(16) NOTNULL);

3、导入数据

INSERTINTO Order SELECT id, “”, Age FROM _Order;

4、删除临时表

DROPTABLE _Order;

通过以上四个步骤,就可以完成旧数据库结构向新数据库结构的迁移,并且其中还可以保证数据不会因为升级而流失。
当然,如果遇到减少字段的情况,也可以通过创建临时表的方式来实现。

实现代码如下

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    if (newVersion == 2) {
        char str = '"';
        db.beginTransaction();
        db.execSQL("ALTER TABLE Order RENAME TO _Order");
        db.execSQL("CREATE TABLE Order(Id integer primary key autoincrement , CustomName VARCHAR(20) NOT NULL,"
                + " Country VARCHAR(32) NOT NULL , OrderPrice VARCHAR(16) NOT NULL)");
        db.execSQL("INSERT INTO Order SELECT Id, " + str + str
                + ", CustomName, OrderPrice FROM _Order");
        db.setTransactionSuccessful();
        db.endTransaction();
    }
}

多个数据库版本的升级

假如我们开发的程序已经发布了两个版本:V1.0,V2.0,我们正在开发V3.0。版本号分别是1,2,3。对于这种情况,我们应该如何实现升级?
用户的选择有:

1) V1.0 -> V3.0 DB 1 -> 2
2) V2.0 -> V3.0 DB 2 -> 3

数据库的每一个版本所代表的数据库必须是定义好的,比如说V1.0的数据库,它可能只有两张表TableA和TableB,如果V2.0要添加一张表TableC,如果V3.0要修改TableC,数据库结构如下:

V1.0 —> TableA, TableB
V1.2 —> TableA, TableB, TableC
V1.3 —> TableA, TableB, TableC (Modify)

代码如下:

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    if (1 == oldVersion) {
        String sql = "Create table C....";
        db.execSQL(sql);
        oldVersion = 2;
    }

    if (2 == oldVersion) {
        //modify C
        oldVersion = 3;
    }
}

导入已有数据库

代码如下

/**
 * Created by Owen Chan
 * On 2017-09-26.
 */

public class DbManager {

    public static final String PACKAGE_NAME = "com.example.sql";
    public static final String DB_NAME = "table.db";
    public static final String DB_PATH = "/data/data/" + PACKAGE_NAME;
    private Context mContext;

    public DbManager(Context mContext) {
        this.mContext = mContext;
    }

    public SQLiteDatabase openDataBase() {
        return SQLiteDatabase.openOrCreateDatabase(DB_PATH + "/" + DB_NAME, null);
    }

    public void importDB() {
        File  file = new File(DB_PATH + "/" + DB_NAME);
        if (!file.exists()) {
            try {
                FileOutputStream out = new FileOutputStream(file);
                int buffer = 1024;

                InputStream in = mContext.getResources().openRawResource(R.raw.xxxx);
                byte[] bts = new byte[buffer];
                int lenght;
                while ((lenght = in.read(bts)) > 0) {
                    out.write(bts, 0, bts.length);
                }
                out.close();
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

调用方式

@Override
protected void onResume() {
    super.onResume();
    DbManager dbManager = new DbManager(this);
    dbManager.importDB();
    SQLiteDatabase db = dbManager.openDataBase();
    db.execSQL("do what you want");
}
2019-04-12 17:37:18 WangRain1 阅读数 659

       正常我们在开发中经常会遇到sqlite数据库升级的问题,比如增加字段/删除字段/表结构重构等等,随着apk版本的升高,不同版本可能需要对数据库进行修改,但是要求是数据库升级不能影响用户的已存数据,所以今天就来看看数据库升级流程是怎样的。

目录

SQLiteDatabase源码调用流程

数据库自动升级流程


  • SQLiteDatabase源码调用流程

  1. 首先我们需要继承 SQLiteOpenHelper, 下面是 SQLiteOpenHelper 的源码注释:
SQLiteOpenHelper is a helper class to manage database creation and version management.

然后会提示让我们去重写他的三个方法:

    public SQLiteOpenHelper(@Nullable Context context, @Nullable String name,
            @Nullable CursorFactory factory, int version) {
        this(context, name, factory, version, null);
        // 传入我们的数据库名称 和 版本号version
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // 创建表
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // 版本升级
    }

       2. 分析以下上述三个方法调用的时机,何时会被调用。

  1. 构造方法--首先我们创建数据库操作类的时候先走构造方法,通过构造方法会把数据库名称和版本号 传 SQLiteOpenHelper
    当然这只是创建了,数据库操作类,数据库还没有创建。
  2. onCreate() 方法是创建表的,只有第一次才会走这个方法,首次创建数据库的时候才会走,之后就不会走了。
  3. onUpgrade()数据库升级,这个方法只有构造方法中传的版本号发生了升级才会走,所以我们升级的逻辑就在这里处理。

                    以上只是常用的方法,还有数据库降级等等方法按需重写。

       3. 方法调用的源码流程图

根据这个流程图配合我们的源码更容易理解 sqlite 整个创建流程,这就是整个数据库版本检测和获得db的过程。对整个流程熟悉了之后,接下来我们就好理解数据库升级。

  • 数据库自动升级流程

对于升级我们就举一个例子,从db version 1 升级到db version 2的过程: 

假如我们的表结构是这样的
* version = 1;
* auto     integer   REAL      REAL
* _id     color     loc_x     loc_y      


* version = 2; 添加了一个 字段 time
* auto     integer   REAL         REAL       REAL
* _id     color     loc_x        loc_y       time

通过分析源码我们知道数据库升级是在 onUpgrade() 方法中的,接下来分析升级流程:

  1. 创建临时缓存表 用于缓存老表里面的数据
  2. 查询老表中的数据并且把数据插入到缓存的表中去
  3. 删除老表,创建新的表结构
  4. 把缓存表数据重新插入到新的表结构中去
  5. 调用查询,插入检测是否升级成功
  6. 升级结束

整个流程就这些,接下来把升级的代码贴上,特别要注意的是升级的流程要放到子线程中去!

@Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //创建临时缓存表 用于缓存老表里面的数据
        String createTable = "CREATE TABLE " + snapCachedTableName
                + " (" + CustomColorEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                + CustomColorEntry.COLUMN_NAME_COLOR + " INTEGER,"
                + CustomColorEntry.COLUMN_NAME_LOCX + " REAL,"
                + CustomColorEntry.COLUMN_NAME_LOCY + " REAL)";
        db.execSQL(createTable);
        //查询所有的老表数据
        List<CustomColor> colors = getCustomColors(CustomColorEntry.TABLE_NAME,db);
        //把数据插入到缓存的表中去
        for (CustomColor color : colors){
            insertCustomColor(color, snapCachedTableName,db);
        }
        db.execSQL("drop table " + CustomColorEntry.TABLE_NAME);
        //创建新的表结构
        String createNewTable = "CREATE TABLE " + CustomColorEntry.TABLE_NAME
                + " (" + CustomColorEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                + CustomColorEntry.COLUMN_NAME_COLOR + " INTEGER,"
                + CustomColorEntry.COLUMN_NAME_LOCX + " REAL,"
                + CustomColorEntry.COLUMN_NAME_LOCY + " REAL,"
                + CustomColorEntry.COLUMN_NAME_TIME + " REAL)";
        db.execSQL(createNewTable);
        //查询所有的缓存表中的数据
        List<CustomColor> cachedColors = getCustomColors(snapCachedTableName,db);
        //把数据插入到新的表中去
        for (CustomColor color : cachedColors){
            insertCustomColor(color, CustomColorEntry.TABLE_NAME,db);
        }
        db.execSQL("drop table " + snapCachedTableName);
    }

传送门github:https://github.com/WangRain1/DbUpgradeDemo 大家给点支持,笑嘻嘻

 

2018-07-16 13:57:31 Jason_HD 阅读数 624

版本迭代时难免需要对数据库字段进行增加,删除与修改操作。这时便需要对原有的数据进行迁移,以保证不丢失数据。对数据库的迁移我们需要做一下几个步骤:

  • ① 创建临时表,将原来的数据复制到临时表中。
  • ② 删除原表,原表数据已经备份至临时表中,不再需要,进行删除。
  • ③ 创建新表,调用创建新表的方法,创建所有的新表。
  • ④ 恢复原表的数据,将临时表中的数据恢复至新表中。
  • ⑤ 删除临时表,完成所有的步骤。

具体步骤:

1.引入GreenDaoUpgradeHelper

compile 'com.github.yuweiguocn:GreenDaoUpgradeHelper:v2.0.2'

2.在新建DaoManager类


public class DaoManager {


    private DaoMaster mDaoMaster;

    private DaoSession mDaoSession;

    private static volatile DaoManager mInstance = null;

    public static final String DATABASE_NAME = "greendao";


    private DaoManager(Context context) {


        MySQLiteOpenHelper helper = new MySQLiteOpenHelper(context, DATABASE_NAME, null);

        mDaoMaster = new DaoMaster(helper.getWritableDatabase());

       /* AppOpenHelper helper = new AppOpenHelper(CCApplication.getInstance().getApplicationContext(), DATABASE_NAME);

        Database db = helper.getWritableDb();

        mDaoMaster = new DaoMaster(db);*/

        mDaoSession = mDaoMaster.newSession();

    }


    public static DaoManager getInstance(Context context) {

        if (mInstance == null) {

            synchronized (DaoManager.class) {

                if (mInstance == null) {

                    mInstance = new DaoManager(context);

                }

            }

        }

        return mInstance;

    }


    public DaoMaster getMaster() {

        return mDaoMaster;

    }


    public DaoSession getSession() {

        return mDaoSession;

    }


    public DaoSession getNewSession() {

        mDaoSession = mDaoMaster.newSession();

        return mDaoSession;

    }


    /*private static class AppOpenHelper extends DaoMaster.OpenHelper {

        public AppOpenHelper(Context context, String name) {

            super(context, name);

        }

        public AppOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {

            super(context, name, factory);

        }

        @Override

        public void onUpgrade(Database db, int oldVersion, int newVersion) {

            DaoSession daoSession = new DaoMaster(db).newSession();

            // TODO: do something before recreate tables

            DaoMaster.dropAllTables(db, true);

            onCreate(db);

        }

        @Override

        public void onCreate(Database db) {

            Log.i("greenDAO", "Creating tables for schema version " + DaoMaster.SCHEMA_VERSION);

            DaoMaster.createAllTables(db, true);

        }

    }*/


    public class MySQLiteOpenHelper extends DaoMaster.OpenHelper {

        public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {

            super(context, name, factory);

        }

        @Override

        public void onUpgrade(Database db, int oldVersion, int newVersion) {

            MigrationHelper.migrate(db, new MigrationHelper.ReCreateAllTableListener() {


                @Override

                public void onCreateAllTables(Database db, boolean ifNotExists) {

                    DaoMaster.createAllTables(db, ifNotExists);

                }


                @Override

                public void onDropAllTables(Database db, boolean ifExists) {

                    DaoMaster.dropAllTables(db, ifExists);

                }

            },DBCurrentUserDao.class, DBCurrentUserSettingDao.class, DBTextChatMessageDao.class,RelationUserDao.class);

        }

    }

}



主要代码:

public class MySQLiteOpenHelper extends DaoMaster.OpenHelper {
    public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
        super(context, name, factory);
    }
    @Override
    public void onUpgrade(Database db, int oldVersion, int newVersion) {
        MigrationHelper.migrate(db, new MigrationHelper.ReCreateAllTableListener() {

            @Override
            public void onCreateAllTables(Database db, boolean ifNotExists) {
                DaoMaster.createAllTables(db, ifNotExists);
            }

            @Override
            public void onDropAllTables(Database db, boolean ifExists) {
                DaoMaster.dropAllTables(db, ifExists);
            }
        },DBCurrentUserDao.class, DBCurrentUserSettingDao.class, DBTextChatMessageDao.class,RelationUserDao.class);
    }
}