どのようにアンドロイドのJavaでのエラー「マッチング方法のパラメータを持っている必要があります、クエリ内の各バインド変数」を修正するには?

DaGee:

私は1つのだけのテーブルを持っているAndroidアプリに簡単なRoomDBを実装しようとした、およびタスクはdatabaseBuilderのコールバックを通じてプリロード、その内のオブジェクト。私はアプリを構築しようとした際、私は、クエリ内の各バインド変数がマッチング方法のパラメータエラーを持っている必要がありますが、私がヒットする場合は、2番目の時間を実行し、それはアプリをコンパイルし、私はデータベースに何も挿入することはできません、とあれば取得します私はそれが戻ってヌルを与える(0)そのIDによってプリロードされたタスクを照会してみてください。

これは私がDBに格納する私のTaskクラス、次のとおりです。

@Entity(tableName = "tasks")
public class Task {

    @PrimaryKey(autoGenerate = true)
    private int taskId;
    @ColumnInfo(name = "Description")
    private String description;

    public Task(String description) {
        this.description = description;
    }

    public void setTaskId(int taskId) {
        this.taskId = taskId;
    }


    public int getTaskId() {
        return taskId;
    }

    public String getDescription() {
        return description;
    }

    @NonNull
    @Override
    public String toString() {
        return "Task object, id: "+taskId;
    }
}

そして、これは私のTaskDAOです。

@Dao
public interface TaskDAO {

    @Query("SELECT * FROM tasks")
    List<Task> getAll();

    @Query("SELECT * FROM tasks WHERE taskId = (:taskId)")
    Task getTaskById(int taskId);

    @Insert
    void insertAll(Task...tasks);

}

そして、これは、データベースのクラスは次のとおりです。

@Database(entities = {Task.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    private static AppDatabase INSTANCE;

    public abstract TaskDAO taskDAO();

    public static AppDatabase getAppDatabase(Context context) {
        if (INSTANCE == null) {
            INSTANCE = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, "tasks.db")
                    .addCallback(new Callback() {
                        @Override
                        public void onCreate(@NonNull SupportSQLiteDatabase db) {
                            super.onCreate(db);
                            new PopulateInitialData(INSTANCE).execute();
                        }
                    }).build();
        }
        return INSTANCE;
    }

    private static class PopulateInitialData extends AsyncTask<Void, Void, Void> {

        private final TaskDAO taskDAO;

        public PopulateInitialData(AppDatabase database){
            taskDAO = database.taskDAO();
        }

        @Override
        protected Void doInBackground(Void... voids) {
            Task task1 = new Task("Task data");

            taskDAO.insertAll(new Task[] {task1});
            return null;
        }
    }
}

そして、これは私がDBを呼び出してタスクを照会しようとする方法です。

AppDatabase roomDB = AppDatabase.getAppDatabase(getApplicationContext());
new Thread(new Runnable() {
    @Override
    public void run() {
        Task task = roomDB.taskDAO().getTaskById(0)); //task is null
    }
}).start();
マイク:

insertAllの方法は、タスクオブジェクトの配列(期待Task[])しない単一のタスクオブジェクト。

あなたは、単一のTaskオブジェクトを挿入したい場合、あなたは、DAOなどに新たなinsertメソッドを追加することができます

@Insert
void insertOneTask(Task task);

交互に電流が単一要素アレイを使用insertAllの方法。

たとえば、

taskDAO.insertAll(new Task[]{task1});

私はデータベースに何も挿入できない、と私はそのID(0)でプリロードタスクを照会しようとした場合、それが戻ってヌルを与えます。

、通常の状況下では、最初のIDは1になり、0のIDを持つタスクが存在しないだろうからです。

次のコードを使用した場合

            List<Task> alltasks = roomDB.taskDAO().getAll();
            for (Task t: alltasks) {
                Log.d("TASKINFO","Task =" + t.getDescription() + " ID = " + t.getTaskId());
            }

後/前または代わりに Task task = roomDB.taskDAO().getTaskById(0)); //task is null

これは、タスクIDが1であることを示すだろう。

たとえば、 2019-09-29 20:00:20.463 D/TASKINFO: Task =Task data ID = 1

ROOMを使用してタスクのためのテーブルを作成します説明するために: -

CREATE TABLE IF NOT EXISTS `tasks` (`taskId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `Description` TEXT)

taskIdの列は、行IDカラムのエイリアスになり、値を与え、または指定された値がNULLである場合はありません。その後、ROWID、したがって、それの別名の値を自動生成します。値は、最後に記録された値や、データベース内の現在の最高値の高いより1つの大きくなります。そのような値がない場合、値はなります1

あなたが使用している場合

Task task = roomDB.taskDAO().getTaskById(1));

挿入されたタスクが返されます。

一般的に、あなたは、IDの値についての仮定は、むしろそれは、通常のリストから、プログラム的に得られるべき作るべきではありませんが、部屋であなたは通常、オブジェクト(egtheのgetAll()と上記のようにループのために、以下)を扱うでしょう

テスティング

コードは以下のように使用して試験しました: -

  • Task.javaコピーASISと変わりません
  • TaskDAO.javaは、 ASISと変わらずをコピー。
  • AppDatabase.javaは、 ASISと変わらずをコピー。

  • そして、これは私がDBを呼び出してタスクを照会しようとする方法です。

    • このコードを落としMainActivity.java

    • メイドroomDBクラス変数、(AppDatabase roomDB)だけのonCreateメソッドでそれをインスタンス化します。

    • また、エラー訂正(余分な括弧)と

    • 追加されたのgetAll上記のループコード。

ごとのように: -

public class MainActivity extends AppCompatActivity {

    AppDatabase roomDB;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        roomDB = AppDatabase.getAppDatabase(getApplicationContext());
        new Thread(new Runnable() {
            @Override
            public void run() {
                Task task = roomDB.taskDAO().getTaskById(0); //task is null
                List<Task> alltasks = roomDB.taskDAO().getAll();
                for (Task t: alltasks) {
                    Log.d("TASKINFO","Task =" + t.getDescription() + " ID = " + t.getTaskId());
                }
            }
        }).start();
    }
}

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=315089&siteId=1