房间数据库更新时的重复数据输入

nwwlzxa7  于 2021-06-27  发布在  Java
关注(0)|答案(3)|浏览(261)

我有一份笔记申请表。用户可以创建新注解或更改现有注解。
在这个应用程序中,我尝试在用户更改现有笔记时自动保存笔记。因此,我使用 textWatcher 我打电话给 saveNotes() 中的方法 onTextChanged() 文本的方法。因此,每当用户从文本中添加或删除任何字符时,我打算在这里保存注解。

var ide: Int? = null  //Global Variable
//in OnCreate()
if(intent.getBooleanExtra("isViewOrUpdate", false)){
            viewOrOpenedNote = intent.getSerializableExtra("note") as Note?
            ide = viewOrOpenedNote?.id

在以上两个代码示例中。。整个想法就是制造变量 ide 充当一个检查器,即如果用户正在创建一个新的便笺,它将返回null;否则,如果用户已打开一个现有便笺以查看或编辑便笺,它将存储便笺的id。
下面是textwatcher

title_edit_text.addTextChangedListener((object : TextWatcher {
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
                saveNote()   // here I 
            }
            override fun afterTextChanged(p0: Editable?) {}
        }))

savenote()

private fun saveNote() {
                val note = Note()
                note.setTitle(Title)

                if (ide != null) {
                    note.setId(ide!!)  // Here I am assigning the note id to `ide` in case the 
                                         `saveNote()` is called when user has opened an existing note. If 
                                          this is a new note then ide will be null automatically.
                }
                class SaveNotes : AsyncTask<Void, Void, Void>() {
                    override fun doInBackground(vararg void: Void?): Void? {
                        NotesDatabase.getDatabase(applicationContext).noteDao().insertNote(note)
                        return null
                    }

                    override fun onPostExecute(result: Void?) {
                        super.onPostExecute(result)
                        ide = note.id               //This is because: If user has added a first 
                                                     character in new note, then after that an id will be 
                                                     assigned to this new database, whenever 
                                                    `saveNote()` method is called again after text change 
                                                     I need to save the changed note to the same existing 
                                                     id. I hope I am clear.

                     //***UPDATE***After much contemplation I have found out 
                       that here lies the problem! changing the value of ide by 
                       simply `ide = note.id` will always give null value for new 
                       note, as this id is not received from the created note, 
                       but from the blank note instance I created above. 
                    }
                }
                SaveNotes().execute()
}

问题:即使采取了上述预防措施,每次我更改一个便笺时,都会创建同一便笺的多个示例。例子:
假设我键入:你好
我得到的结果是5个不同id的音符,文字如下:
h//id=5
他//id=4
赫尔//id=3
地狱//id=2
你好//id=1
注解.java

@Dao
public interface NoteDao {

    @Query("SELECT * FROM note ORDER BY id DESC")
    List<Note> getAllNotes();

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insertNote(Note note);

    @Delete
    void delete(Note note);
}

注解.java

@Entity(tableName = "note")
public class Note implements Serializable {

    @PrimaryKey(autoGenerate = true)
    private int id;

    @ColumnInfo(name = "title")

注解数据库.java

public static synchronized NotesDatabase getDatabase(Context context)
    {
        if(notesDatabase == null){
           notesDatabase =  Room.databaseBuilder(context
            , NotesDatabase.class,
                    "note_db"
                    )
                   .addMigrations(MIGRATION_1_2)
                   .build();
        }
        return notesDatabase;
    }

    public abstract NoteDao noteDao();
ulydmbyx

ulydmbyx1#

每次在ontextchange中调用savenote时,您都要创建一个新示例(vieweropenednote),以便将从数据库获得的或当前显示给用户的旧示例note对象传递给用户。

//Pass the same note instance which you are showing on the screen.
@Update
fun updateNote(note: Note)

//Give note the same id as It saved in the previous note. e-g create a note instance but set Id = viewOrOpenedNote.id so that is where Conflict will arise and the database will replace it.
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertNote(note: Note) : Long

使用协同程序
第一步:

def coroutines_android_version = '1.3.9'
// Coroutines libraries
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_core"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_android_version"

第二步:
在课堂上清除。

private val ioScope = CoroutineScope(Dispatchers.IO)

第三步:

ioScope.launch {
    saveNote()
}

suspend fun saveNote(){
    NotesDatabase.getDatabase(applicationContext).noteDao().insertNote(note)
}
mzaanser

mzaanser2#

总结一下
考虑到您所做的更改,请指出 ide = note.id 在postexecutemethod()中。执行以下操作:
1.使用以下命令更改notedao.java中的insert块

@Insert(onConflict = OnConflictStrategy.REPLACE)
    long insertNote(Note note);  //long istead of void if you need the id as return

2.更改的数据类型 ide 从int到long

var ide: Long? = null

3.在 onCreate() ```
if(intent.getBooleanExtra("isViewOrUpdate", false)){
viewOrOpenedNote = intent.getSerializableExtra("note") as Note?
ide = viewOrOpenedNote?.id?.toLong() //Convert to long

4.你现在只需要更换 `saveNote()` 方法与下面的此块。

private fun saveNote() {
val database = NotesDatabase.getDatabase(applicationContext) //add this here
val note = Note()
note.setTitle(Title)

            if (ide != null) {
               note.setId(ide!!.toInt())  //convert to int as ide is long
            }
            class SaveNotes : AsyncTask<Void, Void, Void>() {
                override fun doInBackground(vararg void: Void?): Void? {
                        ide = database.noteDao().insertNote(note)  // two things inone line: first insert the note and then get the id of the note saved
                    return null
                }

                override fun onPostExecute(result: Void?) {
                    super.onPostExecute(result)
                    // Let this be empty
                }
            }
            SaveNotes().execute()

}

zpgglvta

zpgglvta3#

在你的刀里面做一个这样的函数

@Update(onConflict = OnConflictStrategy.REPLACE)
fun update(note: Note): Int

并在savenote函数中输入以下代码

fun saveNote(item: Note) {
    database.runInTransaction {
        val id = item.id

        if(id == null)
            getNoteDao().insert(item)
        else
            getNoteDao().update(item)
    }
}

相关问题