在Android上将数据插入Room数据库之前,如何检查数据是否已存在于数据库中?

4
在我的应用程序中,我想使用Room数据库显示离线数据。我编写了以下代码,但是当单击按钮添加数据时,如果该数据已存在于Room数据库中,则会显示ForceClose错误!在将数据添加到数据库之前,如何检查数据库中是否存在此数据?
我的NewsOfflineDatum类:
@Entity(tableName = "newsList")
public class NewsOfflineDatum {
    @PrimaryKey
    private int id;

    @ColumnInfo(name = "newsTitle")
    private String title;

    @ColumnInfo(name = "newsImage")
    private String image;

    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 getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }
}

我的适配器类:

public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.MyViewHolder> {

    private List<Today> model;
    private Context context;

    public NewsAdapter(List<Today> model) {
        this.model = model;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_news, parent, false);
        context = parent.getContext();

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        final Today todayModel = model.get(position);

        Glide.with(context)
                .load(AppConstant.IMAGE_URL + todayModel.getImage())
                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
                .into(holder.rowNews_img);
        holder.rowNews_txt.setText(todayModel.getTitle());
        holder.rowNews_dl.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                NewsOfflineDatum offlineDatum = new NewsOfflineDatum();
                offlineDatum.setId(todayModel.getId());
                offlineDatum.setTitle(todayModel.getTitle());
                offlineDatum.setImage(todayModel.getImage());

                MainActivity.myAppDatabase.getMyDao().addNews(offlineDatum);

                Toast.makeText(context, "Saved :)", Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    public int getItemCount() {
        return model.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {

        @BindView(R.id.rowNews_img)
        ImageView rowNews_img;
        @BindView(R.id.rowNews_txt)
        TextView rowNews_txt;
        @BindView(R.id.rowNews_dl)
        ImageView rowNews_dl;

        public MyViewHolder(View view) {
            super(view);
            ButterKnife.bind(this, view);
        }
    }
}

LogCat 错误:

Process: com.example.mac8.mvplearnclicksite, PID: 7697
android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: newsList.id (code 1555)
#################################################################
Error Code : 1555 (SQLITE_CONSTRAINT_PRIMARYKEY)
Caused By : Abort due to constraint violation.
    (UNIQUE constraint failed: newsList.id (code 1555))
#################################################################
    at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
    at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:865)
    at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
    at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:50)
    at android.arch.persistence.room.EntityInsertionAdapter.insert(EntityInsertionAdapter.java:64)
    at com.example.mac8.mvplearnclicksite.Data.DataBase.MyDao_Impl.addNews(MyDao_Impl.java:49)
    at com.example.mac8.mvplearnclicksite.Home.NewsAdapter$1.onClick(NewsAdapter.java:59)
    at android.view.View.performClick(View.java:6261)
    at android.view.View$PerformClick.run(View.java:23752)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6776)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1518)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)

这一行代码报错了:MainActivity.myAppDatabase.getMyDao().addNews(offlineDatum);

我该怎么修复它?

6个回答

10

这里提供了一种有效的解决方案,用于检查你的数据表中是否存在数据。

  • Room Database在你的数据库表中是否存在数据,永远不会返回一个布尔值。

要检查数据是否存在,可以获取 int 值。

0 = data is not exist in your table

要做到这一点,您需要尝试下面的代码

@Query("SELECT * FROM TableName WHERE userName = :userName")
int isDataExist(String userName);

使用以下代码调用此查询。

if (AppDatabase.getInstance(this).employeeDao().isDataExist(tvUserName.getText().toString()) == 0) {
 // data not exist.
 } else {
 // data already exist.
 }

4

使用此注释更新您的查询:

@Insert(onConflict = OnConflictStrategy.REPLACE)

我正在使用room db,应该将此添加到pojo类、repository还是Dao中? - TheCoderGuy
@Spritzig,您可以将此代码添加到DAO类中。 - Santhosh Joseph
我已经添加了这个功能,但是在room database中如何检查一个字符串是否存在呢? - TheCoderGuy
@Spritzig 请将您的问题作为一个新问题发布,这样您就可以详细地解释,我们也可以更好地理解它 :) - Santhosh Joseph

2

如果您只想检查记录是否存在,请使用此查询。

    @Query("SELECT EXISTS(SELECT * FROM TableName WHERE userId = :userId)")
    boolean isRecordExistsUserId(String userId);

这将简单地返回 true 或 false。根据布尔值,您可以执行剩余的流程。


1

你有两种方式:

1- 当你想将数据存入数据库时,不需要输入ID,也可以使用这种方法输入重复的数据。

2-

 @Insert(onConflict = OnConflictStrategy.REPLACE)
 void addNews(offlineDatum);

我希望使用它。

0

您遇到了约束违规问题,您正在尝试添加具有相同ID的实体。根据您的逻辑,您想要使用新实体进行更新,还是如果它不为空,则保留原样。


0
  @Query("SELECT EXISTS(SELECT 1 FROM table_name)")
  fun hasTable(): Boolean

在你的Dao中添加上面的代码。然后在你的逻辑中使用以下代码。
          if(mDao.hasTable()) {
                //Already have data
            } else {
                // Add data
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接