android - SQLite : db. 插入在 if 语句中不起作用

标签 android android-sqlite

我正在尝试使用 SQLite 数据库来存储回收站 View 的信息。我希望数据库根据描述只包含唯一的记录。我试图在创建数据库时将描述字段设置为唯一,但似乎没有帮助。相反,我决定创建一个函数来检查描述是否已存在于数据库中,然后插入包含此信息的新记录。在运行调试工具查看我哪里出错后,此功能工作正常。我认为错误出在 db.insert 函数中,该函数在 if 语句中似乎没有执行。感谢您的帮助。

附言我完全是 SQLite 的菜鸟,对它周围的行话不是很熟悉。

这是帮助处理数据库的类的部分代码

public class DataBaseHandler extends SQLiteOpenHelper {

  private final Context context;

  public DataBaseHandler(@Nullable Context context) {
      super(context, Constants.DB_NAME, null, Constants.DB_VERSION);
      this.context = context;
  }

   @Override
public void onCreate(SQLiteDatabase db) {
    String CREATE_FOOD_TABLE = "CREATE TABLE " + Constants.TABLE_NAME + "("
        + Constants.KEY_ID + " INTEGER PRIMARY KEY,"
        + Constants.KEY_FOOD_ITEM + " INTEGER,"
        + Constants.KEY_PRICE + " TEXT,"
        + Constants.KEY_QTY_NUMBER + " INTEGER,"
        + Constants.KEY_DESCRIPTION + " TEXT,"
        + Constants.KEY_DATE_NAME + " LONG);";

        db.execSQL(CREATE_FOOD_TABLE); 
}

这是 hasObject 函数的代码:

    public boolean hasObject(String foodCode) {
        SQLiteDatabase db = getWritableDatabase();
        String selectString = "SELECT * FROM " + Constants.TABLE_NAME + " WHERE " + Constants.KEY_DESCRIPTION + " =?";

        // Add the String you are searching by here.
        // Put it in an array to avoid an unrecognized token error
        Cursor cursor = db.rawQuery(selectString, new String[] {foodCode});

        boolean hasObject = false;
        if(cursor.moveToFirst()){
            hasObject = true;
        }

        cursor.close();
        db.close();
        return hasObject;
    }

常量在单独的类中定义为静态最终。

这是我的代码中存在问题的地方。

public void addItem(Item item) {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(Constants.KEY_FOOD_ITEM, item.getItemName());
    values.put(Constants.KEY_PRICE, item.getPrice_double());
    values.put(Constants.KEY_QTY_NUMBER, item.getItemQuantity());
    values.put(Constants.KEY_DESCRIPTION, item.getDescription());
    values.put(Constants.KEY_DATE_NAME, 
    java.lang.System.currentTimeMillis());//timestamp of the system

//        db.insert(Constants.TABLE_NAME, null, values);
//        Log.d("DBHandler", "added Item: ");
        //Check if the record already exists in the database
        if(!hasObject(item.getDescription())){
            //Insert the row
            db.insert(Constants.TABLE_NAME, null, values);              // This is not running as planned
            Log.d("DBHandler", "added Item: ");
        }
        else {
            //Don't insert the row
            Log.d("DBHandler", "Item exists");

        }
    }

正如您所注意到的,我尝试按原样运行 db.insert 函数,而不检查记录是否已存在于数据库中,并且运行正常。 但是,如果我继续添加记录,无论它们是否在数据库中,都会有太多重复项,这会弄乱回收站 View 。

这里调用了 additem 函数:

        databaseHandler= new DataBaseHandler(this);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));


        itemList= new ArrayList<>();
        //tempitemlist = new ArrayList<>();

        //Get items from Firebase
        mfoodRef.addValueEventListener(new ValueEventListener() {
            //Will run everytime there is an update to the condition value in the database
            //So this will run when the .setValue function runs in the button onClickListener classes
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                //tempitemlist.clear();
                Iterable<DataSnapshot> databaseMenu = dataSnapshot.getChildren();
                for (DataSnapshot data:databaseMenu){
                    Menu tempMenu = data.getValue(Menu.class);
                    Item tempItem = new Item(tempMenu.getFoodName(),tempMenu.getFoodCode(),tempMenu.getFoodPrice());
                    //itemList.add(tempItem);
                    databaseHandler.addItem(tempItem);
                }
            }

            // In case we run into any errors
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

是的,我正在使用我的 Firebase 实时数据库中的信息来更新 onDataChange 方法中的数据库处理程序的内容。这就是为什么我需要在插入新记录时检查重复项。

编辑:

这是我在调试日志中发现的:

    Process: com.example.vendorwrecycler, PID: 12882
    java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/user/0/com.example.vendorwrecycler/databases/foodList
        at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:57)
        at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1567)
        at android.database.sqlite.SQLiteDatabase.insertOrThrow(SQLiteDatabase.java:1494)
        at com.example.vendorwrecycler.data.DataBaseHandler.addItem(DataBaseHandler.java:68)
        at com.example.vendorwrecycler.ListActivity.saveItem(ListActivity.java:184)
        at com.example.vendorwrecycler.ListActivity.access$500(ListActivity.java:34)
        at com.example.vendorwrecycler.ListActivity$4.onClick(ListActivity.java:159)
        at android.view.View.performClick(View.java:7125)
        at android.view.View.performClickInternal(View.java:7102)
        at android.view.View.access$3500(View.java:801)
        at android.view.View$PerformClick.run(View.java:27336)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

也许这可能与 IllegalStateException 有关?

最佳答案

您正在尝试对关闭的 DB 实例执行操作。尝试在 if 语句中移动 SQLiteDatabase db = getWritableDatabase();

if(!hasObject(item.getDescription())){
    //Insert the row
    SQLiteDatabase db = getWritableDatabase();
    db.insert(Constants.TABLE_NAME, null, values);             
    Log.d("DBHandler", "added Item: ");
}
else {
    //Don't insert the row
    Log.d("DBHandler", "Item exists");
}

您在 hasObject 函数中关闭了 DB 的连接。

关于android - SQLite : db. 插入在 if 语句中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59171783/

相关文章:

java - 使用雅虎财经检索股票报价

java - 如何使用在 Android studio 中自动创建的内部静态 Placeholder Fragment 类?

android - PowerManager.PARTIAL_WAKE_LOCK android

Android 广告系列测量不起作用

android - 如何删除 Android M 中所有应用的应用缓存?

java - 共享首选项未检索值

Android SQLite数据库递归查询

Android - 从服务查询数据库

android - 如何将旧版本的数据库文件导入新版本?

sqlite - 如何在 sqlite 中使用 ROW_NUMBER