SqliteDatabase.findEditTableの改良
8509 ワード
1.目的
私たちがデータベースを厳格に操作するとき、プログラムが再起動された後、すでに確立されたデータベーステーブルは、再構築する必要はありません.プロジェクトの初めにAndroidローカルデータベースSQLiteDatabaseを使用したときも、この状況に遭遇しました.その方法はfindEditTableのみで可能であるため,以下の実験を行った.
注意:private static final TABLENAME="user";
私たちがデータベースを厳格に操作するとき、プログラムが再起動された後、すでに確立されたデータベーステーブルは、再構築する必要はありません.プロジェクトの初めにAndroidローカルデータベースSQLiteDatabaseを使用したときも、この状況に遭遇しました.その方法はfindEditTableのみで可能であるため,以下の実験を行った.
String tableName = "";
tableName= mSqliteDatabase.findEditTable(TABLENAME);// bug
Log.i("ln","result = " + tableName);
if (tableName == null || tableName.equals("")){
mSqliteDatabase.execSQL("create TABLE "+ TABLENAME +"(_id INTEGER PRIMARY KEY AUTOINCREMENT, "+COLUMN_USERNAME +" VARCHAR(50) NOT NULL,"+ COLUMN_USERADDRESS +" VARCHAR(50))");
}else {
Log.i("ln","The table has been created.");
}
注意:private static final TABLENAME="user";
2. 问题可多次实验,在表格 user尚未建立时,调用findEditTable方法,程序坚定地返回 “user”。这就导致表格无法真实在数据库中建立,后续的数据库操作无法进行。
05-10 02:45:59.124 3649-3649/com.ln.dbstorage I/ln: result = user 05-10 02:45:59.125 3649-3649/com.ln.dbstorage I/ln: The table has been created.
3.缘由
理由がソースコードの中にある可能性があると予感したので、SQLiteDatabaseのソースコードを開けてみました.ソースコードのfindEditTableに関する部分を見てください.ここを見ると、状況は一目瞭然です./** * Finds the name of the first table, which is editable. * * @param tables a list of tables * @return the first table listed */ public static String findEditTable(String tables) { if (!TextUtils.isEmpty(tables)) { // find the first word terminated by either a space or a comma int spacepos = tables.indexOf(' '); int commapos = tables.indexOf(','); if (spacepos > 0 && (spacepos < commapos || commapos < 0)) { return tables.substring(0, spacepos); } else if (commapos > 0 && (commapos < spacepos || spacepos < 0) ) { return tables.substring(0, commapos); } return tables; } else { throw new IllegalStateException("Invalid tables"); } }
4.シナリオ
コード友たちは、sqliteの「.tables」コマンドが、すべての既存のテーブル名を調べることができることを知っているに違いない.データベースにすべてのテーブル情報を保存するテーブルがあるかもしれないと思います.幸いなことにsqlite_マスターが私の視線に現れた.そこで私たちの以下の解決策があります.// Cursor cursor = mSqliteDatabase.rawQuery("SELECT * FROM sqlite_master where tbl_name = ? ",new String[]{TABLENAME}); Log.i("ln","table num : " + cursor.getCount());
実行結果は次のとおりです.05-10 03:01:52.711 30008-30008/com.ln.dbstorage I/ln: table num : 0
5.解決Cursor cursor = mSqliteDatabase.rawQuery("SELECT * FROM sqlite_master where tbl_name = ? ",new String[]{TABLENAME}); Log.i("ln","table num : " + cursor.getCount()); if (cursor.getCount()!= 1){ mSqliteDatabase.execSQL("create TABLE "+ TABLENAME +"(_id INTEGER PRIMARY KEY AUTOINCREMENT, "+COLUMN_USERNAME +" VARCHAR(50) NOT NULL,"+ COLUMN_USERADDRESS +" VARCHAR(50))"); }else { Log.i("ln","The table has been created."); }
——2016.5.10鄭州で