【问题标题】:Android SQLite insert method small clarificationAndroid SQLite插入方法小说明
【发布时间】:2022-01-19 19:19:29
【问题描述】:

我正在学习一些用于 android 开发的 sqlite 教程,我试图理解这行代码:


1  ContentValues values = new ContentValues();
2        values.put(AppContract.HeadphoneEntry.COLUMN_NAME, "Toto");
3        values.put(AppContract.HeadphoneEntry.COLUMN_BREED, "Terrier");
4        values.put(AppContract.HeadphoneEntry.COLUMN_WEIGHT, 7);
5
6
7
8        long newRowId = db.insert(AppContract.HeadphoneEntry.TABLE_NAME, null, values);

这行代码(第 8 行)是否将我的值插入到表中?或者我只是将行 ID 存储到名为“newRowId”的长类型变量中? 我问是因为插入了数据,但我不明白为什么......因为我认为我只是将行 ID 存储在该行上。

【问题讨论】:

    标签: java android sqlite android-sqlite


    【解决方案1】:

    这行代码(第 8 行)是否将我的值插入到表中?

    -> 是的,如果 db 使用 SQLiteOpenHelper.getWritableDatabase() 方法初始化,第 8 行会将您的值插入表中。

    或者我只是将行 ID 存储到名为“newRowId”的长类型变量中?

    -> 当您使用SQLiteDatabase.insert() 插入时,它返回新插入行的行ID,如果发生错误,则返回-1。

    【讨论】:

      【解决方案2】:

      SQLiteDatabase insert 方法插入一行并将插入行的 rowid 作为 long 或在冲突的情况下返回 -1 以指示该行没有插入。因此,如果插入了行,newRowId 的值将是大于 0 的正值;如果没有插入并且没有其他冲突(例如,外键约束冲突将导致抛出异常),则为 -1。

      • conflicts 可能是 PRIMARY KEY、UNIQUE、CHECK 或 NULL 约束违规。

      insert 方法是一种方便的方法,它生成底层 SQL 绑定任何参数并执行它。生成的 SQL 将类似于:-

      INSERT OR IGNORE INTO the_table_name (the_name_column, the_breed_column, the_weight_column) VALUES(?,?,?);
      

      地点:-

      • the_table_name 将是根据第一个参数的值,即 AppContract.HeadphoneEntry.TABLE_NAME 解析为的任何值。
      • the_name_column 将是 ContentValues 中第一个值的第一个值(即 AppContract.HeadphoneEntry.COLUMN_NAME 解析为的值)
      • the_breed_column 将根据第二个 ContentValues 的第一个值(即 AppContract.HeadphoneEntry.COLUMN_BREED 解析为的值)的第一个值进行赋值
      • the_weight_column 是第三个ContentValues 的第一个值(即AppContract.HeadphoneEntry.COLUMN_WEIGHT 解析为的值)

      ? 被相应 ContentValues 的第二个值替换(从第一个开始,即 'Toto',从第二个开始,即 'Terrier' ....) 绑定 SQL 语句时。绑定语句正确地将实际值括在单引号中,从而防止 SQL 注入。

      执行sqlite3_last_insert_rowid()接口后,返回结果0转为-1。

      如果您不使用便捷方法,那么要复制它所做的一切,您将不得不编写如下代码:-

          db.execSQL("INSERT OR IGNORE INTO " + AppContract.HeadphoneEntry.TABLE_NAME +
                  "(" +
                  AppContract.HeadphoneEntry.COLUMN_NAME +
                  "," + AppContract.HeadphoneEntry.COLUMN_BREED +
                  "," + AppContract.HeadphoneEntry.COLUMN_WEIGHT +
                  ") " +
                  "VALUES(?,?,?)", 
                  new String[]
                          {
                                  "Toto", 
                                  "Terrier", 
                                  "7"
                          }
          );
          Cursor csr = db.rawQuery("SELECT last_insert_rowid()",null);
          newRowID = -1;
          if (csr.moveToFirst()) {
              newRowID = csr.getLong(0);
              if (newRowID <= 0) {
                  newRowID = -1;
              }
          }
          csr.close();
      

      其中 db 是实例化的 SQLiteDatabase 对象。

      如果您的目标是尝试预测下一个要使用的 rowid,那么您可以使用:-

          Cursor csr = db.rawQuery("SELECT max(rowid)+1 FROM " + AppContract.HeadphoneEntry.TABLE_NAME + ";",null);
          long newRowID = 1; // 
          if (csr.moveToFirst()) {
              newRowID = csr.getLong(0);
          }
      

      但请注意 SQLite 不保证下一个插入的行将比现有的最高 rowid 大 1。如果您使用 AUTO INCREMENT ,则 sqlite_sequence 表存储该表使用的最高 rowid 和较高的值,并且将使用 max(rowid) 值。 即使如此,他们仍然不能保证预测值将是使用的值。最好不要尝试预测 rowid 的值,而是检索它,以便 Android Java 使用便捷方法。

      • 一个例外情况是,如果您深入研究使用负 rowid 值,而 -1 可能并不表示没有插入。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-09
        • 2017-12-06
        • 2011-02-09
        • 2013-03-05
        • 1970-01-01
        • 2020-10-31
        相关资源
        最近更新 更多