我正在嘗試在 My UpdateActivity 中更新房間資料庫中的 Notes 但它不會在資料庫中更新它不會給出錯誤(作業正常)但不會更新資料庫中的資料。這是更新活動。我的日志值給出了我在 EditText 中輸入的正確結果,但沒有在資料庫中更新。
package com.example.keepnotes;
import static android.content.ContentValues.TAG;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import java.util.Objects;
public class UpdateActivity extends AppCompatActivity {
DatabaseHelper databaseHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update);
Toolbar toolbar_add = findViewById(R.id.toolbar_update_activity);
setSupportActionBar(toolbar_add);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
toolbar_add.setNavigationIcon(R.drawable.back_button);
toolbar_add.setNavigationOnClickListener(view -> onBackPressed());
EditText title = findViewById(R.id.update_activity_title);
EditText text = findViewById(R.id.update_activity_text);
Button updateBtn = findViewById(R.id.Update_button);
databaseHelper = DatabaseHelper.getDatabase(UpdateActivity.this);
String titleText = "";
String bodyText = "";
Bundle extras = getIntent().getExtras();
if (extras != null) {
titleText = extras.getString("title");
bodyText = extras.getString("text");
}
title.setText(titleText);
text.setText(bodyText);
updateBtn.setText(R.string.update);
Notes notes = new Notes(titleText,bodyText);
updateBtn.setOnClickListener(view -> {
notes.setTitle(title.getText().toString());
notes.setText(text.getText().toString());
databaseHelper.notesDao().updateNotes(notes);
Log.d(TAG, "onCreate: " notes.title notes.text);
finish();
});
}
}
我認為初始化Notes有任何問題
Notes notes = new Notes(titleText,bodyText);
我在我的活動中這樣初始化。
這里是筆記類。
package com.example.keepnotes;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;
@Entity(tableName = "notesTable")
public class Notes {
@PrimaryKey(autoGenerate = true)
public int id;
@ColumnInfo(name = "title")
public String title;
@ColumnInfo(name = "text")
public String text;
Notes(int id, String title, String text) {
this.id = id;
this.text = text;
this.title = title;
}
@Ignore
Notes(String title, String text) {
this.text = text;
this.title = title;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
這里是 NotesDao 類
package com.example.keepnotes;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
@Dao
public interface NotesDao {
@Query("SELECT * FROM notesTable")
List<Notes> getAllNotes();
@Query("SELECT * FROM notesTable")
LiveData<List<Notes>> findAllNotes();
@Insert
void addNotes(Notes note);
@Update
void updateNotes(Notes note);
@Delete
void deleteNotes(Notes note);
}
我該如何解決這個問題?
uj5u.com熱心網友回復:
如評論中所述,您將需要Notes
要更新的條目的主鍵(可能是一個完整的 id)。
看起來您正在使用putExtra
傳遞有關存在Notes
于不同Activity
. 如果從資料庫中檢索到現有Notes
物件(呼叫它noteToUpdate
),它應該包含您需要的主鍵。Intent
您可以在原始檔案中添加另一個鍵/值對,Activity
例如putExtra("id", noteToUpdate.id)
. 然后,在 中UpdateActivity
,您可以使用類似的東西noteId = extras.getString("id")
來檢索 id。
一旦你有了 this ,你就可以呼叫一個接受 id 的建構式noteId
來代替。Notes notes = new Notes(titleText, bodyText);
或者,您可以notes.setId(noteId)
在構造物件之后撰寫類似的內容。現在正確設定了主鍵,updateNotes
呼叫應該可以作業了。
編輯:如果我誤解了您的評論并且沒有 id 欄位(或類似欄位),請分享Notes
物體結構和主鍵。
uj5u.com熱心網友回復:
有兩種主要的方法可以通過 @Dao 注釋介面或抽象類來更新 Room。您可以使用通過@Update
注釋使用的便捷更新方法。另一種方法是使用UPADTE SQL 陳述句。
使用@Update
如果您使用帶@Update
注釋的函式,那么您將要更新的物件傳遞給函式。Room 然后代表您構建UPDATE SQL。但是,為了確保更新資料庫中的正確行而不是所有行(這可能是一場災難),Room 使用構成主鍵的欄位的值(用@PrimaryKey
or 欄位注釋的欄位使用 @Entity 注釋中的 primaryKeys 引數)。
您的問題的可能原因是titleText和bodyText都不是主鍵或一起構成主鍵,因此主鍵是默認值(如果主鍵是 java 原語,則通常顯式或隱式為 0 as long 或 int),因此沒有要更新此類 id 的行。在這種情況下,不會更新任何內容,就 SQLite 而言這不是錯誤。
所以如果你有
@Update
void update(Notes note);
然后生成的 SQL 將類似于
UPDATE notes SET titleText='the_value_extracted_from_the_titleText_field_of_the_passed_Notes_object', bodyText = 'the_value_extracted_from_the_bodyText_field_of_the_passed_Notes_object' WHERE the_primaryKeyField='the_value_from_the_primaryKeyFields_of_the_passed_Notes_object'
- 其中
the_value_from_the....
是對值的解釋,而不是實際值。
如果這是問題,那么要使用 @Update 便捷方法,您需要設定形成或形成主鍵的一個或多個欄位。例如notes.setId(the_respective_id);
,在進行更新之前。
便捷方法還將回傳一個整數,其中包含已更新的行數。
所以如果你有
@Update
int update(Notes note);
然后使用:-
if (databaseHelper.notesDao().updateNotes(notes) > 0) {
.... do something here if you want to indicate successful update
} else {
.... do something here if you want to indicate that nothing was updated
}
使用@Query
另一種方法是使用第二種方法,即通過 @Query 提供您自己的 UPDATE 陳述句,例如:-
@Query("UPDATE notes SET titleText=:newTitleText, bodyText=:newBodyText WHERE titleText=:originalTitleText AND bodyText=:originalBodyText;")
void update(String newTitleText, String newBodyText, String originalTitleText, String originalBodyText);
其中 original.... 將是從附加意圖中獲得的值。
重要筆記
- 如果 originalTitleText 和 originalBodyText 值的組合不是唯一的,則將更新多行。
- 如果您知道titleText 將是每一行的唯一值,那么您可以使用
WHERE titleText="originalTitleText
- 主鍵必須是唯一的,因此為什么建議在 UPDATE 的 WHERE 子句中使用主鍵。
- 當然,您可以使其他列或組合具有唯一索引,但這超出了應對范圍。
- 有一個例外(已知的 SQLite 功能/錯誤),不允許使用 Room,因為 NULL 被認為是唯一值,但使用 IS NULL 將指示任何 NULL,同樣 IS NOT NULL 將指示沒有 NULL
- 使用此方法不回傳更新的行數
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/504048.html
標籤:安卓 数据库 安卓布局 android-recyclerview 机器人房间
下一篇:如何SUM()列并寫入資料表