Andrid数据库框架——greenDAO(三)
来源:互联网 发布:全国十大域名提供商 编辑:程序博客网 时间:2024/06/05 01:53
版权声明:本文为博主原创文章,未经博主允许不得转载。
上一篇Andrid数据库框架——greenDAO(二)对greenDao进行了封装。用起来已经很方便了,还有一个问题就是数据库升级的问题。我们的数据库中的表或者表的字段可能不是一成不变的,数据库的升级也是非常重要的一环。
如果要数据库升级我们只要在build.gradle文件中把版本号改了就可以了
看一下源码:
/** WARNING: Drops all table on Upgrade! Use only during development. */ public static class DevOpenHelper extends OpenHelper { public DevOpenHelper(Context context, String name) { super(context, name); } public DevOpenHelper(Context context, String name, CursorFactory factory) { super(context, name, factory); } @Override public void onUpgrade(Database db, int oldVersion, int newVersion) { Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables"); dropAllTables(db, true);//删除所有表 onCreate(db);//创建新表 } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
这种方式升级的方式是:先删除数据库中所有的表,然后创建新的表。意思就是我们以前的数据都没有了得重新开始。如果我们队以前数据要求不高的话可以这样。但更多时候我们需要保存用户的数据升级完之后再还原。所以我们就得重写这个onUpgrade方法了。
先建个临时表保存数据,在创建新表,然后把数据移到新表,最后删除临时表。思路还是挺清晰的 做起来就比较麻烦了
下面的升级方法是在网上寻找的方法已测试没问题:
收先建一个类集成自动生成的代码中的DaoMaster.OpenHelper
package com.chs.greendaotext;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import com.chs.greendaotext.db.CarDao;import com.chs.greendaotext.db.DaoMaster;import com.chs.greendaotext.db.NoteDao;import org.greenrobot.greendao.database.Database;/** * 类名:HMROpenHelper * 类描述:用于数据库升级的工具类 */public class MyOpenHelper extends DaoMaster.OpenHelper { public MyOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) { super(context, name, factory); } /** * 数据库升级 * @param db * @param oldVersion * @param newVersion */ @Override public void onUpgrade(Database db, int oldVersion, int newVersion) { //操作数据库的更新 有几个表升级都可以传入到下面 MigrationHelper.migrate(db,NoteDao.class, CarDao.class); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
然后我们把以前用到DaoMaster.OpenHelper的地方改成MyOpenHelper
关键就是onUpgrade中的MigrationHelper了
package com.chs.greendaotext;import android.database.Cursor;import android.support.annotation.NonNull;import android.text.TextUtils;import org.greenrobot.greendao.AbstractDao;import org.greenrobot.greendao.database.Database;import org.greenrobot.greendao.internal.DaoConfig;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Arrays;import java.util.List;/** * 类名:MigrationHelper * 类描述:用于数据库升级的工具类 */public class MigrationHelper { /** * 调用升级方法 * @param db * @param daoClasses 一系列dao.class */ public static void migrate(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) { //1 新建临时表 generateTempTables(db, daoClasses); //2 创建新表 createAllTables(db, false, daoClasses); //3 临时表数据写入新表,删除临时表 restoreData(db, daoClasses); } /** * 生成临时表,存储旧的表数据 * @param db * @param daoClasses */ private static void generateTempTables(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) { for (int i=0;i<daoClasses.length;i++){ DaoConfig daoConfig = new DaoConfig(db,daoClasses[i]); String tableName = daoConfig.tablename; if (!checkTable(db,tableName)) continue; String tempTableName = daoConfig.tablename.concat("_TEMP"); StringBuilder insertTableStringBuilder = new StringBuilder(); insertTableStringBuilder.append("alter table ") .append(tableName) .append(" rename to ") .append(tempTableName) .append(";"); db.execSQL(insertTableStringBuilder.toString()); } } /** * 检测table是否存在 * @param db * @param tableName */ private static Boolean checkTable(Database db,String tableName){ StringBuilder query = new StringBuilder(); query.append("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='").append(tableName).append("'"); Cursor c = db.rawQuery(query.toString(), null); if (c.moveToNext()){ int count = c.getInt(0); if(count>0){ return true; } return false; } return false; } /** * 删除所有旧表 * @param db * @param ifExists * @param daoClasses */ private static void dropAllTables(Database db, boolean ifExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) { reflectMethod(db, "dropTable", ifExists, daoClasses); } /** * 创建新的表结构 * @param db * @param ifNotExists * @param daoClasses */ private static void createAllTables(Database db, boolean ifNotExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) { reflectMethod(db, "createTable", ifNotExists, daoClasses); } /** * 创建根删除都在NoteDao声明了,可以直接拿过来用 * dao class already define the sql exec method, so just invoke it */ private static void reflectMethod(Database db, String methodName, boolean isExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) { if (daoClasses.length < 1) { return; } try { for (Class cls : daoClasses) { //根据方法名,找到声明的方法 Method method = cls.getDeclaredMethod(methodName, Database.class, boolean.class); method.invoke(null, db, isExists); } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } /** * 临时表的数据写入新表 * @param db * @param daoClasses */ private static void restoreData(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) { for (int i = 0; i < daoClasses.length; i++) { DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]); String tableName = daoConfig.tablename; String tempTableName = daoConfig.tablename.concat("_TEMP"); if (!checkTable(db,tempTableName)) continue; // get all columns from tempTable, take careful to use the columns list List<String> columns = getColumns(db, tempTableName); //新表,临时表都包含的字段 ArrayList<String> properties = new ArrayList<>(columns.size()); for (int j = 0; j < daoConfig.properties.length; j++) { String columnName = daoConfig.properties[j].columnName; if (columns.contains(columnName)) { properties.add(columnName); } } if (properties.size() > 0) { final String columnSQL = TextUtils.join(",", properties); StringBuilder insertTableStringBuilder = new StringBuilder(); insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" ("); insertTableStringBuilder.append(columnSQL); insertTableStringBuilder.append(") SELECT "); insertTableStringBuilder.append(columnSQL); insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";"); db.execSQL(insertTableStringBuilder.toString()); } StringBuilder dropTableStringBuilder = new StringBuilder(); dropTableStringBuilder.append("DROP TABLE ").append(tempTableName); db.execSQL(dropTableStringBuilder.toString()); } } private static List<String> getColumns(Database db, String tableName) { List<String> columns = null; Cursor cursor = null; try { cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 0", null); if (null != cursor && cursor.getColumnCount() > 0) { columns = Arrays.asList(cursor.getColumnNames()); } } catch (Exception e) { e.printStackTrace(); } finally { if (cursor != null) cursor.close(); if (null == columns) columns = new ArrayList<>(); } return columns; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
OK 然后我们在去配置文件中更改版本 升级之后原来的数据就不会丢失了。
简单demo地址
0 0
- Andrid数据库框架——greenDAO(三)
- Andrid数据库框架——greenDAO(三)
- Andrid数据库框架——greenDAO(一)
- Andrid数据库框架——greenDAO(二)
- Android 数据库ORM框架——GreenDao
- Android ORM数据库框架之-greenDao(三)
- Andrid数据库——可视化工具
- Android 操作数据库的框架——greenDAO的学习
- Android 操作数据库的框架——greenDAO的学习
- 数据库框架GreenDao——比Realm好一点
- android GreenDao数据库框架学习(1)
- android GreenDao数据库框架学习(2)
- 数据库框架之Greendao从无到有(一)
- greenDAO配置环境(数据库框架)
- greendao数据库框架
- greenDao 数据库框架 使用
- 数据库框架之GreenDao
- Android开源:数据库ORM框架GreenDao学习(三)封装工具类使用
- FastDFS+Nginx+fastdfs-nginx-module分布式存储环境搭建
- 关于ES6的Promise的使用深入理解
- unit12
- MT7688路由器开发板添加Mac白名单
- 解决eclipse的自动换行问题 【安装wordWrap插件】
- Andrid数据库框架——greenDAO(三)
- 代理模式(Proxy pattern)
- linux命令中cd / 和 cd ~
- SimpleDateFormat格式字符对应表
- 访问服务器地址,默认添加项目后缀名
- hiho一下 第145周
- mysql 里面 group_concat函数设置最大字符长度
- 批量上传图片前展示
- BZOJ4816 [Sdoi2017]数字表格