在实现我的数据库的save- / loadfunction时,我删除了表,看看我的应用程序是否可以在必要时处理表的创建 - 好吧它不能
所以在我的testactivity的onCreate中,我创建了一个DB实例,它在它的构造函数中创建了一个DBOpenHelper实例。 基本上当DBOpenHelper实例调用getWritableDatabase()时,应该执行DBOpenHelper的onCreate,在我的数据库中创建表。 我认为问题是,getWritableDatabase()没有被调用,因为数据库本身已经存在 - 想想我已经阅读过这样的方法吸收了openOrCreateDatabase的功能。
如何在不必每次都删除和重新创建数据库的情况下重新创建表时重新创建表?
DBOpenhelper:
public class DBOpenHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 1;
public static String DATABASE_NAME = "RTDB";
public static final String DB_TABLE_NAME1 = "playertable";
public static final String DB_TABLE_NAME2 = "itemtable";
public static String TAG = "openhelper";
private static final String DB_CREATE_TABLE_PT = "CREATE TABLE IF NOT EXISTS "
+ DB_TABLE_NAME1
+ " ("
+ "ID INT(2) PRIMARY KEY AUTOINCREMENT,"
+ "Name VARCHAR(30) ,"
+ "HP INT(3) ,"
+ "Satisfaction INT(3) ,"
+ "Hygiene INT(1) , " + "IsAlive INT(1) " + " )";
private static final String DB_CREATE_TABLE_IT = "CREATE TABLE IF NOT EXISTS "
+ DB_TABLE_NAME2
+ " ("
+ "Money INT(3) ,"
+ "Gas INT(3) ,"
+ "Food INT(3) ,"
+ "Toiletries INT(3) ,"
+ "Spareparts INT(3) ,"
+ "Meds INT(3) ,"
+ "Tents INT(3) ,"
+ "Ration INT(1) ,"
+ "Trabbihp INT(3) ," + "Trabbispeed INT(2)" + " )";
public DBOpenHelper(Context context, String databaseName) {
super(context, databaseName, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d("TAG", "PT :" + DB_CREATE_TABLE_PT);
db.execSQL(DB_CREATE_TABLE_PT);
Log.d(TAG, "PT create" + DB_CREATE_TABLE_PT);
db.execSQL(DB_CREATE_TABLE_IT);
Log.d(TAG, "IT create" + DB_CREATE_TABLE_IT);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE_NAME1);
db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE_NAME2);
onCreate(db);
}
}
DB:
public class DB {
private Context context;
private SQLiteDatabase db;
private static String TAG = "save";
private static ContentValues itemValues = new ContentValues();
private static ContentValues playerValues = new ContentValues();
public DB(Context context) {
this.context = context;
DBOpenHelper dbHelper = new DBOpenHelper(this.context, "RTDB");
this.db = dbHelper.getWritableDatabase();
}
public void savePlayer(Player player[]) {
for (int i = 0; i <= 3; i++) {
playerValues.put("Name", player[i].getName());
playerValues.put("HP", player[i].getHp());
playerValues.put("Satisfaction", player[i].getsatisfaction());
playerValues.put("Hygiene", player[i].isHygieneInt());
playerValues.put("IsAlive", player[i].isAliveInt());
}
db.insert("playertable", null, playerValues);
}
// Speichern der Items
// TODO Position fehlt noch
public void saveItems() {
itemValues.put("Money", Resource.money);
itemValues.put("Gas", Resource.gas);
itemValues.put("Food", Resource.food);
itemValues.put("Toiletries", Resource.toiletries);
itemValues.put("Spareparts", Resource.spareparts);
itemValues.put("Meds", Resource.meds);
itemValues.put("Tents", Resource.tents);
itemValues.put("Ration", Resource.ration);
itemValues.put("Trabbihp", Resource.trabbihp);
itemValues.put("Trabbispeed", Resource.trabbispeed);
db.insert("itemtable", null, itemValues);
}
// Hier werden die Items aus der Datenbank abgefragt, der zurueckgelieferte
// Cursor vie cursorToIntArray() in einen Int Array umgewandelt und dessen
// Inhalt in die Ressource Klasse geschrieben
public void loadItems() {
Cursor itemCursor = db.query("itemtable", null, null, null, null, null,
null);
int[] itemIntArray = cursorToInt(itemCursor, 9);
Resource.money = itemIntArray[0];
Resource.gas = itemIntArray[1];
Resource.food = itemIntArray[2];
Resource.toiletries = itemIntArray[3];
Resource.meds = itemIntArray[4];
Resource.tents = itemIntArray[5];
Resource.ration = itemIntArray[6];
Resource.trabbihp = itemIntArray[7];
Resource.trabbispeed = itemIntArray[8];
}
// Name und Restliche Int-Werte der Playerobjekte werden separat aus der
// Datenbank geholt und gesetzt
public void loadPlayer() {
String[] namecolumn = { "Name" };
String[] intcolumn = { "ID, Name, HP, Satisfaction, Hygiene, IsAlive" };
String[] namesToString = new String[4];
Cursor playerCursor = db.query("playertable", intcolumn, null, null,
null, null, "ID");
playerCursor.moveToPosition(-1);
int i = 0;
while (i <= 3) {
playerCursor.moveToNext();
String temp = playerCursor.getString(1);
Resource.playerArray[i].setName(temp);
int tempint = playerCursor.getInt(2);
Resource.playerArray[i].setHp(tempint);
tempint = playerCursor.getInt(3);
Resource.playerArray[i].setsatisfaction(tempint);
tempint = playerCursor.getInt(4);
Resource.playerArray[i].setHygieneInt(tempint);
tempint = playerCursor.getInt(5);
Resource.playerArray[i].setAliveInt(tempint);
i++;
}
}
public void dropTables() {
db.execSQL("DROP TABLE 'playertable';");
db.execSQL("DROP TABLE 'itemtable';");
}
private int[] cursorToInt(Cursor cursor, int n) {
int[] results = new int[n];
for (int i = 0; i <= n - 1; i++) {
results[i] = cursor.getInt(i + 1);
}
return results;
}
private String[] cursorToString(Cursor cursor) {
String[] results = new String[4];
int columnIndex = cursor.getColumnIndex("Name");
for (int i = 0; i <= 3; i++) {
results[i] = cursor.getString(columnIndex);
}
return results;
}
}
onCreate instancing DB的测试活动:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.myDB = new DB(this);
initUI();
testcase1();
答案 0 :(得分:1)
不确定您对getWritableDatabase
函数如何正确的描述:查看您的代码似乎正在做正确的事情,因为我在许多已部署的应用程序中使用非常相似的结构而没有任何错误。它正确地处理创建/升级所有表,无论它们是否存在或数据库是否存在。您可能想尝试将DBOpenHelper
设为静态类:这对我有用。或者仔细检查您的日志:如果发生了其他一些乍看之下可能看起来不相关的异常,那么这可能会指向您找到解决方案。
编辑:尝试private static class DBOpenHelper extends SQLiteOpenHelper
。我还建议更改数据库版本以强制调用onUpgrade
方法。通常,在您删除表但文件存在的情况下,您需要调用信息模式来检查数据库文件是否已定义表。仅当文件不存在时才会调用onCreate
,并且只有在更改数据库版本时才会调用onUpdate
。
编辑:有关使用信息架构表检查表是否存在的更多详细信息,请参阅http://www.sqlite.org/faq.html#q7。您可以只针对SQLITE_MASTER表运行查询,然后如果找不到特定的表,则运行CREATE语句。