我面临一个非常奇怪的问题。我正在开发一个具有sqlite DB作为其数据库的android应用程序。我正在使用扩展SQLiteOpenHelper的DBAdapter类。我在互联网上搜索但找不到解决方案。
这是我的SQLiteOpenHelper类
public class DBAdapter extends SQLiteOpenHelper{
private static DBAdapter mInstance = null;
/**The Android's default system path of your application database. */
private static String DB_PATH = "/data/data/com.mydbapp.android/databases/";
private final static String DB_NAME = "mydb.sqlite";
private static final int DATABASE_VERSION = 1;
private static Context myContext;
public static DBAdapter getInstance(Context ctx) {
if (mInstance == null) {
mInstance = new DBAdapter(ctx);
}
return mInstance;
}
private DBAdapter(Context context) {
super(context, DB_NAME, null, DATABASE_VERSION);
DBAdapter.myContext = context;
DB_PATH = "/data/data/" +
context.getPackageName()+
"/databases/";
}
public void deleteDB()
{
myContext.deleteDatabase(DB_NAME);
}
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist )
{
this.getWritableDatabase();
}
if(!dbExist){
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
e.printStackTrace();
throw new Error("Error copying database");
}
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
if (newVersion > oldVersion)
{
System.out.println("DB Upgrade logic")
}
}
现在,当我更改private static final int DATABASE_VERSION = 2;
时,不会调用onUpgrade()
方法,但是当我更改private static final int DATABASE_VERSION = 3;
时,onUpgrade()会起作用。
所以我的问题是,当我将数据库版本从1更改为2时,为什么不调用onUpgrade()
方法。
请帮我解决这个问题。
我注意到了一个更奇怪的行为。当我最初使用数据库版本1运行应用程序然后再次使用理智的数据库版本(1)安装应用程序时,现在如果我将数据库版本1更改为2,则调用onUpgrade()。我的意思是说我必须使用相同的数据库版本安装应用程序2次然后如果我更改数据库版本,则调用onUpgrade()。
答案 0 :(得分:1)
试试这种方式
当您使用DBHelper
类时,更改db版本时将自动调用onUpgrade()
mehtod。您无需与旧版本和新版本进行比较。你可以删除版本的比较。它会帮助你。检查下面的代码以获得更多清晰。
public class DBHelper extends SQLiteOpenHelper {
// Static Final Variable database meta information
static final String DATABASE = "empapp.db";
static final int VERSION = 1;
static final String TABLE = "emp";
static final String TABLE_DEPT = "dept";
static final String C_ID = "_id";
static final String C_ENAME = "ename";
static final String C_DESIGNATION = "designation";
static final String C_SALARY = "salary";
// Override constructor
public DBHelper(Context context) {
super(context, DATABASE, null, VERSION);
}
// Override onCreate method
@Override
public void onCreate(SQLiteDatabase db) {
// Create Employee table with following fields
// _ID, ENAME, DESIGNATION and SALARY
db.execSQL("CREATE TABLE " + TABLE + " ( " + C_ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + C_ENAME + " text, "
+ C_DESIGNATION + " text, " + C_SALARY + " text )");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop old version table
db.execSQL("Drop table " + TABLE);
// Create New Version table
onCreate(db);
}
}
答案 1 :(得分:0)
可能是您要复制的数据库,因为初始数据库已经将其模式版本设置为2。
其他一些问题:
完成后,您应该将getWritableDatabase()
或getReadableDatabase()
及close()
的结果存储起来。
此
DB_PATH = "/data/data/" +
context.getPackageName()+
"/databases/"
不会在所有设备上工作。不要硬编码数据库路径。请改用getDatabasePath()
。
答案 2 :(得分:0)
好的,你所描述的行为是正确的: 如果DB没有退出,则运行onCreate 如果DB存在 - 它将获取它的版本并将onUpdate运行到您在构造函数中指定的版本。
显然,您希望在创建方法中创建最新版本的数据库以进行全新安装,并且如果用户正在更新应用程序,则在onUpgrade中部分复制代码... 如果你像我一样认为这不是一个很好的代码方法,我建议你这样做:
public const int VERSION = 2;
@Override
public void onCreate(SQLiteDatabase db) {
// create a first version of your DB in this method only
db.execSQL("CREATE TABLE " + TABLE + " ( " + C_ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + C_ENAME + " text, "
+ C_DESIGNATION + " text, " + C_SALARY + " text )");
this.onUpgrade(db, 1, VERSION); // run onUpgrade manually
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Deal with all other versions separatelly
for(int i = oldVersion + 1; i <= newVersion; i++) {
switch(i) {
case 2:
db.execSQL("ALTER TABLE " + TABLE + " ADD COLUMN " + C_TAXES + " text;");
break;
}
}
}
如果您不想丢失数据,这种方法很有用。如果您不关心数据 - 那么只需在onCreate和onUpgrade中创建最新版本的数据库 - 删除旧数据库并运行onCreate。