【问题标题】:TypeConverter not working when updating List<Boolean> in Room Database更新房间数据库中的 List<Boolean> 时,TypeConverter 不起作用
【发布时间】:2019-07-23 02:38:33
【问题描述】:

由于某种原因,我的查询在 DAO_Impl 构建中显示语法错误。我尝试了重建,但在执行以下查询时仍然出错:

查询:

@Query("UPDATE TasksTable SET daysOfWeek = :days WHERE taskID = :tkID")
    fun updateDays(tkID: Int, days: MutableList<Boolean>)

实体任务:

data class EntityTask(
    var taskID: Int = 0,
    var personID : Int = 0,
    var name : String = "",
    var frequency: Int = 1,
    var interval: Int = 0,
    var haveSchedule: Boolean = false,
    var schedule: Int = 0,
    var scheduleString: String = "",
    var description: String = "",
    var showProgressLayout: Boolean = true,
    var daysOfWeek: MutableList<Boolean> =  mutableListOf(),
    var daysOfMonth: MutableList<Boolean> = mutableListOf(),
    var currentScores: ScoresCurrent = ScoresCurrent(),
    @Ignore
    var scores : MutableList<EntityScore> = mutableListOf()
)

DaoTasks_Impl:

 @Override
  public void updateDays(int tkID, List<Boolean> days) {
    StringBuilder _stringBuilder = StringUtil.newStringBuilder();
    _stringBuilder.append("UPDATE TasksTable SET daysOfWeek = ");
    final int _inputSize = days.size();
    StringUtil.appendPlaceholders(_stringBuilder, _inputSize);
    _stringBuilder.append(" WHERE taskID = ");
    _stringBuilder.append("?");
    final String _sql = _stringBuilder.toString();
    SupportSQLiteStatement _stmt = __db.compileStatement(_sql); //This is line 330

错误信息:

03-01 07:05:37.504 26855-27552/com.samuelriesterer.taskprogress E/SQLiteLog: (1) near "?": syntax error
03-01 07:05:37.514 26855-27552/com.samuelriesterer.taskprogress E/AndroidRuntime: FATAL EXCEPTION: Thread-23439
    Process: com.samuelriesterer.taskprogress, PID: 26855
    android.database.sqlite.SQLiteException: near "?": syntax error (code 1): , while compiling: UPDATE TasksTable SET daysOfWeek = ?,?,?,?,?,?,? WHERE taskID = ?
    #################################################################
    Error Code : 1 (SQLITE_ERROR)
    Caused By : SQL(query) error or missing database.
        (near "?": syntax error (code 1): , while compiling: UPDATE TasksTable SET daysOfWeek = ?,?,?,?,?,?,? WHERE taskID = ?)
    #################################################################
        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1058)
        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:623)
        at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
        at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:59)
        at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
        at android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java:1132)
        at android.arch.persistence.db.framework.FrameworkSQLiteDatabase.compileStatement(FrameworkSQLiteDatabase.java:64)
        at android.arch.persistence.room.RoomDatabase.compileStatement(RoomDatabase.java:244)
        at com.samuelriesterer.taskprogress.data.daos.DAOTasks_Impl.updateDays(DAOTasks_Impl.java:310)
        at com.samuelriesterer.taskprogress.data.Data$Companion$editTask$thread$1.run(Data.kt:569)
        at java.lang.Thread.run(Thread.java:818)

我为此有一个类型转换器,所以我不知道为什么它不会让我更新列表。我知道我的类型转换器有效,因为它在将列表添加到数据库时有效。 (它被添加到我的数据库中)。它只是在 UPDATE 查询中使用时不起作用。

我的转换器:

@TypeConverter fun stringToListBoolean(value: String): MutableList<Boolean>
    {
        val list = mutableListOf<Boolean>()
        value.forEach { c ->
            if(c == 'F') list.add(false)
            else list.add(true)
        }
        return list
    }
@TypeConverter fun listBooleanToString(list: MutableList<Boolean>): String
{
    var value = ""
    for(i in list)
    {
        if(i) value += "T"
        else value += "F"
    }
    return value
}

【问题讨论】:

  • 您无法提供变量列表以将其存储到数据库中。对于这种情况,您需要 TypeConverter。您的错误是由于daysOfWeek & daysOfMonth
  • 但我确实有一个 typeConverter
  • 能否提供你的转换器的代码,能更好地帮助找到问题。
  • 我编辑了答案,见编辑
  • 您是否将TypeConverter 提供给您的数据库类

标签: android sqlite dao android-room


【解决方案1】:

因此,根据 Jeel Vankhede 的建议,我将 MutableList 更改为 ArrayList,并且 UPDATE 查询有效。 Impl 构建的区别:

可变列表:

@Override
  public void test(int tkID, List<Boolean> test) {
    StringBuilder _stringBuilder = StringUtil.newStringBuilder();
    _stringBuilder.append("UPDATE TasksTable SET test = ");
    final int _inputSize = test.size();
    StringUtil.appendPlaceholders(_stringBuilder, _inputSize);
    _stringBuilder.append(" WHERE taskID = ");
    _stringBuilder.append("?");
    final String _sql = _stringBuilder.toString();
    SupportSQLiteStatement _stmt = __db.compileStatement(_sql);

数组列表:

@Override
  public void test(int tkID, ArrayList<Boolean> test) {
    final SupportSQLiteStatement _stmt = __preparedStmtOfTest.acquire();
    __db.beginTransaction();
    try {
      int _argIndex = 1;
      final String _tmp;
      _tmp = Converters.listBooleanToString(test);
      if (_tmp == null) {
        _stmt.bindNull(_argIndex);
      } else {
        _stmt.bindString(_argIndex, _tmp);
      }
      _argIndex = 2;
      _stmt.bindLong(_argIndex, tkID);
      _stmt.executeUpdateDelete();
      __db.setTransactionSuccessful();
    } finally {
      __db.endTransaction();
      __preparedStmtOfTest.release(_stmt);
    }
  }

如您所见,ArrayList 使用转换器,而 MutableList 不使用。不知道这是为什么??

【讨论】:

    【解决方案2】:

    对此修复不太满意,但我最终通过创建一个单独的类来保存列表 daysOfWeek 和 daysOfMonth 的值来达到我的目的:

    间隔:

    class Interval(_daysOfWeek: MutableList<Boolean> = mutableListOf(false, false, false, false, false, false, false),
                   _daysOfMonth: MutableList<Boolean> = mutableListOf(false, false, false, false, false, false, false, false, false,
                       false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
                       false, false, false, false, false, false)
    )
    {
        val daysOfWeek = _daysOfWeek
        val daysOfMonth = _daysOfMonth
    }
    

    然后为此添加了一个自定义转换器。现在我可以查询更新了:

    @Query("UPDATE TasksTable SET name = :name, frequency = :frequency, interval = :interval, haveSchedule = :haveSchedule, schedule = :schedule, scheduleString = :scheduleString, description = :description, showProgressLayout = :showProgressLayout, intervals = :intervals WHERE taskID = :taskID")
    fun updateTask(taskID: Int, name: String, frequency: Int, interval: Int, haveSchedule: Boolean, schedule: Int, scheduleString: String, description: String, showProgressLayout: Boolean, intervals: Interval)
    

    【讨论】:

      猜你喜欢
      • 2019-01-17
      • 1970-01-01
      • 1970-01-01
      • 2018-10-29
      • 1970-01-01
      • 2022-11-09
      • 2021-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多