Android SQLite之类的查询具有多个可选条件作为预处理语句

时间:2015-10-03 13:29:20

标签: java android sqlite select

我对Android很陌生,我试图查询数据库表" Houses"列大小,所有者和城市。

我正在尝试实现一种方法

getHousesFromDatabase(String owner, String city, Integer size) 

其中 city size 可以为null。该方法应返回 size,location,city 字段与参数匹配的所有行,但仅当参数不为null时才返回。 即

getHousesFromDatabase("John", null, null);应返回所有者为John的所有行,而不管其他列。

getHousesFromDatabase("John", "San Francisco", null);应返回所有者为John且位于旧金山的所有行,依此类推。

我目前的实施方式是这样的

   public House getHousesFromDatabase(String owner, String city, Integer size) {
        if (city == null && size == null) {
            Cursor cursor = database.rawQuery("select * from " + SQLiteHelper.TABLE_HOUSES + " where "
                    + COLUMN_OWNER + " like '" + owner + "%" + "'", null);
        }
        else if (city == null) {
            Cursor cursor = database.rawQuery("select * from " + TABLE_HOUSES + " where "
                    + COLUMN_OWNER + " like '" + owner + "%" + "'" +" and where " + COLUMN_SIZE + "like '"+ size +"%'", null);
        }
        else if (size == null) {
            ...
        }
        else {
           ...
        }
    }

if语句涵盖每种可能的变化;但这对我来说感觉非常笨拙,我想知道是否有一种更简单的方法,并且会产生一个准备好的陈述? (根据我的阅读,rawQuery()单独容易受到SQL注入攻击,SQLiteStatement.execute()不能用于查询。

1 个答案:

答案 0 :(得分:1)

rawQuery()query()都以完全相同的方式容易受到SQL注入攻击,但前提是您在不使用参数的情况下将字符串值直接插入SQL字符串中。

您应该动态构造SQL语句:

Cursor getHousesFromDatabase(String owner, String city, Integer size) {
    String[] params = new String[(owner != null ? 1 : 0) +
                                 (city  != null ? 1 : 0) +
                                 (size  != null ? 1 : 0)];
    int paramIndex = 0;
    String where = "";
    if (owner != null) {
        where = COLUMN_OWNER + " LIKE ?";
        params[paramIndex++] = owner + "%";
    }
    if (city != null) {
        if (!where.equals(""))
            where = where + " AND ";
        where = where + COLUMN_CITY + " LIKE ?";
        params[paramIndex++] = city + "%";
    }
    if (size != null) {
        if (!where.equals(""))
            where = where + " AND ";
        where = where + COLUMN_SIZE + " LIKE ?";
        params[paramIndex++] = size + "%";
    }
    return db.query(TABLE_HOUSES, columns, where, params, null, null, null);
}