如何在安卓SQLite数据库中修改结构且不丢失原有数据
Android SQLite数据库无丢失升级操作步骤
你需要按以下4个步骤修改代码即可实现保留原有数据的结构升级:
- 第一步:提升数据库版本号
原代码中构造方法传入的版本号是1,你需要将其改为更高的整数(比如2),SQLite会自动检测版本变化触发onUpgrade回调。 - 第二步:修改
onCreate方法中的建表语句
给新安装应用的用户直接创建包含新增LAST_NO字段的表结构,避免新用户出现字段不存在的错误。 - 第三步:重写
onUpgrade逻辑,禁止直接删表
按版本号分支处理升级逻辑,旧版本用户升级时执行ALTER TABLE语句新增字段,原有数据会完整保留。 - 第四步:补充新增的字段定义和操作方法
把你准备好的LAST_NO常量和updateNumber方法添加到DBHelper类中即可。
修改后的完整代码
public class DBHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "DATABASE_NAME.db"; public static final String TABLE_NAME = "POSITION_TABLE"; private static final String _ID = "_id"; private static final String RADIO_BUTTON_POSITION = "radio_button_position"; // 新增字段常量 private static final String LAST_NO = "LAST_NO"; // 版本号从1改为2 public DBHelper(@Nullable Context context) { super(context, DATABASE_NAME, null, 2); } @Override public void onCreate(SQLiteDatabase db) { // 建表语句新增LAST_NO字段,默认值可根据业务需求调整 String create_table = "CREATE TABLE " + TABLE_NAME + "( " + "ID INTEGER PRIMARY KEY ," + RADIO_BUTTON_POSITION + " TEXT NOT NULL, " + _ID + " TEXT NOT NULL, " + LAST_NO + " INTEGER DEFAULT 0)"; db.execSQL(create_table); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 按版本差分支处理,避免跨版本升级出错 if (oldVersion < 2) { // 给旧表新增字段,原有数据全部保留 db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN " + LAST_NO + " INTEGER DEFAULT 0"); } // 后续如果有版本3、4的升级需求,继续往下加if分支即可 // if (oldVersion <3) { 处理版本2到3的变更 } } public boolean updateButtonPosition(String _id,String radio_button_position){ SQLiteDatabase database = this.getWritableDatabase(); ContentValues contentValues = new ContentValues(); contentValues.put(_ID,_id); contentValues.put(RADIO_BUTTON_POSITION,radio_button_position); long result = database.update(TABLE_NAME , contentValues , _ID + " =? " , new String[]{_id}); return result != -1; } public int readButtonPosition(String _id) { SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.rawQuery("SELECT " + RADIO_BUTTON_POSITION + " FROM " +TABLE_NAME+" WHERE " + _ID +" =? " , new String[] {_id}); int position = 0; if(cursor.moveToFirst()){ position = cursor.getInt(cursor.getColumnIndexOrThrow(RADIO_BUTTON_POSITION)); } cursor.close(); return position; } // 你新增的更新方法 public boolean updateNumber(String _id,int last_no){ SQLiteDatabase database = this.getWritableDatabase(); ContentValues contentValues = new ContentValues(); contentValues.put(_ID,_id); contentValues.put(LAST_NO,last_no); long result = database.update(TABLE_NAME , contentValues , _ID + " =? " , new String[]{_id}); return result != -1; } }
注意事项
- 后续版本迭代继续叠加
onUpgrade的版本判断分支即可,确保跨版本升级的用户也能正常更新结构 - 新增字段时建议设置默认值,避免旧数据插入新字段时出现非空约束报错
- 操作完Cursor后记得调用
close()方法,避免内存泄露,示例代码中已经补充了该逻辑
内容的提问来源于stack exchange,提问作者user16566034
相关产品推荐
相关产品推荐

