对SqliteDatabase.findEditTable的改进

1. 目的

      我们在严谨地操作数据库的时候,总会遇到这种情况,程序重新启动后,已经建立的数据库表,不需再次建立。在项目之初,用到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_master出现在我的视线。于是就有了我们以下的解决方案。


//根据表明取得表
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 于郑州

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值