【问题标题】:Check if object is exists in room database android java检查房间数据库android java中是否存在对象
【发布时间】:2021-09-12 21:48:01
【问题描述】:

我是 android 房间数据库的新手,我想将数据插入房间,但在插入之前我想检查该项目是否已存在于数据库中。我正在使用这些代码(新闻和文章相同,只是命名问题):
My Dao

package com.example.newsapp.models;

import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;

import com.example.newsapp.operations.Article;

import java.util.List;

@Dao
public interface SavedNewsDAO {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insert(Article article);

    @Query("DELETE FROM saved_articles")
    void deleteAll();

    @Query("DELETE FROM saved_articles where id =:id ")
    void removeNews(int id);

    @Query("SELECT * FROM saved_articles")
    LiveData<List<Article>> getAll();

    @Query("select Count() from saved_articles where title =:title and content =:content and description =:description")
    int checkArticle(String title, String content, String description);
}

我想用 checkArticle 方法获取数据库中的项目数。
我的存储库

package com.example.newsapp.models;

import android.app.Application;

import androidx.lifecycle.LiveData;

import com.example.newsapp.operations.Article;

import java.util.List;

public class SavedArticlesRepository {
    private final LiveData<List<Article>> allArticles;
    private final SavedNewsDAO savedNewsDAO;
    SavedArticlesRepository(Application application) {
        SavedNewsRoomDatabase db = SavedNewsRoomDatabase.getDatabase(application);
        savedNewsDAO = db.savedNewsDAO();
        allArticles = savedNewsDAO.getAll();
    }

    LiveData<List<Article>> getAllArticles() {
        return allArticles;
    }

    void insert(Article article) {
        SavedNewsRoomDatabase.databaseWriterExecutor.execute(() -> savedNewsDAO.insert(article));
    }

    void checkItem(Article article) {
        SavedNewsRoomDatabase.databaseWriterExecutor.execute(() -> {
            savedNewsDAO.checkArticle(article.title, article.content, article.description);
        });
    }
}

这是我的视图模型

package com.example.newsapp.models;

import android.app.Application;

import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;

import com.example.newsapp.operations.Article;

import java.util.List;

public class SavedNewsViewModel extends AndroidViewModel {
    private final SavedArticlesRepository savedArticlesRepository;
    private final LiveData<List<Article>> allArticles;
    public SavedNewsViewModel(Application application) {
        super(application);
        savedArticlesRepository = new SavedArticlesRepository(application);
        allArticles = savedArticlesRepository.getAllArticles();
    }

    public LiveData<List<Article>> getAllArticles() {
        return allArticles;
    }
    public void insert(Article article) {
        savedArticlesRepository.insert(article);
    }

    public void checkArticle(Article article) {
        savedArticlesRepository.checkItem(article);
    }
}

问题是我无法想象如何在 ViewModel 和 Repository 类中使​​用 checkArticle 方法,如 getAll 方法。据我了解,我必须将这些方法链接起来。我想检查一下这个方法:

savedNewsViewModel = new ViewModelProvider(this).get(SavedNewsViewModel.class);
        saveArticleButton.setOnClickListener(v -> {
            Article article = new Article();
            article.title = intent.getStringExtra("title");
            article.description = intent.getStringExtra("description");
            article.content = intent.getStringExtra("content");
            article.urlToImage = intent.getStringExtra("image");
            savedNewsViewModel.insert(article);
            Toast.makeText(this, "Article saved successfully", Toast.LENGTH_SHORT).show();
});

我看过其他问题,但我没有得到它

【问题讨论】:

    标签: java android database android-sqlite android-room


    【解决方案1】:

    您需要观察从checkArticle 方法获得的值。 通过以下方式使用 MutableLiveData:

    public class SavedArticlesRepository {
    
    ....
    
        LiveData<Integer> checkItem(Article article) {
            MutableLiveData<Integer> data = MutableLiveData();
            SavedNewsRoomDatabase.databaseWriterExecutor.execute(() -> {
                int count = savedNewsDAO.checkArticle(article.title, article.content, article.description);
                data.postValue(count);
            });
            return data;
        }
    
    }
    

    现在在您的视图模型中,还使用 ​​LiveData 扩展 checkArticle

    public LiveData<Integer> checkArticle(Article article) {
        return savedArticlesRepository.checkItem(article);
    }
    

    在你的片段或活动中观察这个方法:

     saveArticleButton.setOnClickListener(v -> {
            Article article = new Article();
            article.title = intent.getStringExtra("title");
            article.description = intent.getStringExtra("description");
            article.content = intent.getStringExtra("content");
            article.urlToImage = intent.getStringExtra("image");
    
            savedNewsViewModel.checkArticle.observe(getViewLifeCycleOwner(), new Observer{ count ->
                if(count > 0){
                    Toast.makeText(this, "Article already exists", Toast.LENGTH_SHORT).show();
                } else {
                    savedNewsViewModel.insert(article);
                    Toast.makeText(this, "Article saved successfully", Toast.LENGTH_SHORT).show();
                }
            });
    
    });
    

    我没有测试过这段代码,因为我不再使用 Java。但应该可以正常工作。 如果我可以建议,我会说学习 Kotlin 和协程。当您使用 Kotlin 和协程时,这些东西会容易得多。

    如果您需要更多帮助,请发表评论。

    【讨论】:

    • 效果很好,非常感谢。我也打算学 Kotlin,但我想学一点 Java,然后转用 Kotlin。我认为这样会更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    • 2020-05-01
    • 2021-11-30
    • 2018-08-18
    • 2018-01-04
    相关资源
    最近更新 更多