带引号的ORMLite查询,Android

带引号的ORMLite查询,Android,android,ormlite,Android,Ormlite,我正在使用ORMLite,并使用表RecentSearch: @DatabaseTable(tableName = LocalStorageConfig.SQL_RECENTS_TABLE_NAME) public class RecentSearch { @DatabaseField public String search_text; public static String SQL_SEARCH_FIELD = "search_text"; @Datab

我正在使用ORMLite,并使用表RecentSearch:

@DatabaseTable(tableName = LocalStorageConfig.SQL_RECENTS_TABLE_NAME)
public class RecentSearch {

    @DatabaseField
    public String search_text;
    public static String SQL_SEARCH_FIELD = "search_text";

    @DatabaseField
    public String location_text;
    public static String SQL_LOCATION_FIELD = "location_text";

    @DatabaseField
    public Date creation_date = new Date();
    public static String SQL_CREATION_DATE_FIELD = "creation_date";
它几乎一直在工作,但是当我发现一个字符串包含一个'的情况下,它似乎是一个问题。你知道怎么解决这个问题吗?我找不到我要找的东西

下面是我的功能,删除最近的

public boolean deleteRecent(RecentSearch search) {
    try {
        Dao<RecentSearch, Integer> recentsDao = recentsSqlManager.getRecentsDao();
        DeleteBuilder<RecentSearch, Integer> deleteBuilder = recentsDao.deleteBuilder();

        deleteBuilder.where().eq(RecentSearch.SQL_SEARCH_FIELD, search.getSearch_text()).and().eq(RecentSearch.SQL_LOCATION_FIELD, search.location_text);
        recentsDao.delete(deleteBuilder.prepare());
        return true;
    } catch (Exception e) {
        Log.e(TAG, "Database exception", e);
        return false;
    }
}
public boolean deleteRecent(最近搜索){
试一试{
Dao recentsDao=recentsSqlManager.getRecentsDao();
DeleteBuilder DeleteBuilder=recentsDao.DeleteBuilder();
deleteBuilder.where().eq(RecentSearch.SQL\u搜索字段,SEARCH.getSearch\u text())和().eq(RecentSearch.SQL\u位置字段,SEARCH.LOCATION\u text);
rementsdao.delete(deleteBuilder.prepare());
返回true;
}捕获(例外e){
Log.e(标签“数据库异常”,e);
返回false;
}
}
以下是我得到的一个例外:

java.sql.SQLException: Problems executing Android statement: DELETE FROM `recent_searches` WHERE (`search_text` = '' AND `location_text` = 'Villefranche-d'Allier, Allier' ) 
    at com.j256.ormlite.misc.SqlExceptionUtil.create(SqlExceptionUtil.java:22)
    at com.j256.ormlite.android.AndroidCompiledStatement.runUpdate(AndroidCompiledStatement.java:66)
    at com.j256.ormlite.stmt.StatementExecutor.delete(StatementExecutor.java:425)
    at com.j256.ormlite.dao.BaseDaoImpl.delete(BaseDaoImpl.java:347)
...
Caused by: android.database.sqlite.SQLiteException: near "Allier": syntax error: , while compiling: DELETE FROM `recent_searches` WHERE (`search_text` = '' AND `location_text` = 'Villefranche-d'Allier, Allier' ) 
    at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
    at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:92)
    at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:65)
    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:83)
    at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:41)
    at android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java:1149)
java.sql.SQLException:执行Android语句时出现问题:从“最近的搜索”中删除('search\u text`=''和'location\u text`='Villefranche-d'Allier,Allier')
位于com.j256.ormlite.misc.SqlExceptionUtil.create(SqlExceptionUtil.java:22)
在com.j256.ormlite.android.AndroidCompiledStatement.runUpdate(AndroidCompiledStatement.java:66)
位于com.j256.ormlite.stmt.StatementExecutor.delete(StatementExecutor.java:425)
位于com.j256.ormlite.dao.BaseDaoImpl.delete(BaseDaoImpl.java:347)
...
原因:android.database.sqlite.SQLiteException:靠近“Allier”:语法错误:,编译时:从“最近的搜索”中删除('search\u text`=''和'location\u text`='Villefranche-d'Allier,Allier')
在android.database.sqlite.SQLiteCompiledSql.native\u compile(本机方法)中
位于android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:92)
位于android.database.sqlite.SQLiteCompiledSql.(SQLiteCompiledSql.java:65)
位于android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:83)
位于android.database.sqlite.SQLiteStatement.(SQLiteStatement.java:41)
位于android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java:1149)
在中,当您尝试使用引号构建查询时,应使用
SelectArg
功能,该功能将使用SQL生成查询?参数,然后将字符串直接传递给准备好的语句。这可以避免任何特殊字符转义的问题,并保护您免受SQL注入安全问题的影响。看

使用
SelectArg
,您可以执行以下操作:

DeleteBuilder<RecentSearch, Integer> deleteBuilder = recentsDao.deleteBuilder();

// create our argument which uses a SQL ?
SelectArg locationArg = new SelectArg(search.location_text);
deleteBuilder.where().eq(RecentSearch.SQL_SEARCH_FIELD, search.getSearch_text())
    .and().eq(RecentSearch.SQL_LOCATION_FIELD, locationArg);
recentsDao.delete(deleteBuilder.prepare());
...
DeleteBuilder DeleteBuilder=recentsDao.DeleteBuilder();
//创建使用SQL的参数?
SelectArg locationArg=新建SelectArg(搜索位置\文本);
deleteBuilder.where().eq(RecentSearch.SQL\u SEARCH\u字段,SEARCH.getSearch\u text())
.and().eq(RecentSearch.SQL\u LOCATION\u字段,locationArg);
rementsdao.delete(deleteBuilder.prepare());
...

您可以在绑定到查询时使用该对象,因为这将转义任何引号,这样它们就不会生成无效的sql。

首先,感谢您的解释,每当我对ORMLite有疑问时,您都已经在这里回答了。我想知道:recentsDao.delete(deleteBuilder.prepare());和deleteBuilder.delete()?没有什么不同@AlvaroSantisteban。.delete()只是一个调用,使其更简单。javadocs中这样说: