Java 房间数据库查询
我不熟悉Java 房间数据库查询,java,android,android-room,Java,Android,Android Room,我不熟悉房间,我正在尝试查询我的数据库以从中获取行。我尝试通过用主键查询它,主键是id,但问题是我不知道如何从存储库返回目标对象 这是Dao @Query("SELECT * FROM targets WHERE id = :id LIMIT 1") Targets findTargetById(int id); 这是存储库类 public Targets findTarget (int id) { new findTargetByIDAsyncTask(mTargetsDao).e
房间
,我正在尝试查询我的数据库
以从中获取行
。我尝试通过用主键查询它,主键是id,但问题是我不知道如何从存储库返回目标对象
这是Dao
@Query("SELECT * FROM targets WHERE id = :id LIMIT 1")
Targets findTargetById(int id);
这是存储库类
public Targets findTarget (int id) {
new findTargetByIDAsyncTask(mTargetsDao).execute(id);
}
private static class findTargetByIDAsyncTask extends AsyncTask<Integer, Void, Targets> {
private TargetsDao mAsyncTaskDao;
findTargetByIDAsyncTask(TargetsDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Targets doInBackground(Integer... integers) {
return mAsyncTaskDao.findTargetById(integers[0]);
}
@Override
protected void onPostExecute(Targets targets) {
super.onPostExecute(targets);
}
}
公共目标findTarget(int-id){
新建findTargetByIDAsyncTask(mTargetsDao).execute(id);
}
私有静态类FindTargetByDaSyncTask扩展了AsyncTask{
私人TargetsDao mAsyncTaskDao;
findTargetByIDAsyncTask(TargetsDao dao){
mAsyncTaskDao=dao;
}
@凌驾
受保护目标doInBackground(整数…整数){
返回mAsyncTaskDao.findTargetById(整数[0]);
}
@凌驾
受保护的void onPostExecute(目标){
super.onPostExecute(目标);
}
}
返回结果有两种方法
第一种方法是调用AsyncTask.get()
方法,但如果任务的时间超过5秒,它仍将保留一个主线程,从而导致ANR:
public Targets findTarget (int id) {
return new findTargetByIDAsyncTask(mTargetsDao).execute(id).get();
}
第二种方法更复杂,但它不能保持主线程。您应该添加一个回调类:
public interface Callback {
void onSuccess(Targets targets);
}
存储库的每个方法都将如下所示:
public void findTarget (Callback callback, int id) {
new findTargetByIDAsyncTask(mTargetsDao, callback).execute(id);
}
private static class FindTargetByIDAsyncTask extends AsyncTask<Integer, Void, Targets> {
private final TargetsDao mAsyncTaskDao;
private final Callback callback;
FindTargetByIDAsyncTask(TargetsDao dao, Callback callback) {
mAsyncTaskDao = dao;
this.callback = callback;
}
@Override
protected Targets doInBackground(Integer... integers) {
return mAsyncTaskDao.findTargetById(integers[0]);
}
@Override
protected void onPostExecute(Targets targets) {
callback.onSuccess(targets);
}
}
AsynTask看起来是这样的:
public void findTarget (Callback callback, int id) {
new findTargetByIDAsyncTask(mTargetsDao, callback).execute(id);
}
private static class FindTargetByIDAsyncTask extends AsyncTask<Integer, Void, Targets> {
private final TargetsDao mAsyncTaskDao;
private final Callback callback;
FindTargetByIDAsyncTask(TargetsDao dao, Callback callback) {
mAsyncTaskDao = dao;
this.callback = callback;
}
@Override
protected Targets doInBackground(Integer... integers) {
return mAsyncTaskDao.findTargetById(integers[0]);
}
@Override
protected void onPostExecute(Targets targets) {
callback.onSuccess(targets);
}
}
私有静态类FindTargetByDaSyncTask扩展了AsyncTask{
私人最终目标Dao mAsyncTaskDao;
私有最终回调;
FindTargetByIDAsyncTask(TargetsDao dao,回调){
mAsyncTaskDao=dao;
this.callback=回调;
}
@凌驾
受保护目标doInBackground(整数…整数){
返回mAsyncTaskDao.findTargetById(整数[0]);
}
@凌驾
受保护的void onPostExecute(目标){
callback.onSuccess(目标);
}
}
关键是从后台线程获取数据/对象。您可以使用Android的AsyncTask
或ExecutorService
。一个简单的示例是,如果要获取用户名字符串,方法如下:
private String getName() {
String name = null;
try {
name = Executors.newSingleThreadExecutor().submit(() ->
userDao.fetchUserName()).get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return name;
}
您可以在存储库的onPostExecute方法中对目标执行任何操作。如果您想在assyncTask之外的任何地方使用它,那么您可以创建一个全局变量并影响OnPostExecute中的值。我有一个类似的用例。你的答案似乎简单而有效。但是我看到很多答案都是使用Callable和Future返回一个对象(参见)。感谢您对您的方法与可调用/未来方法的看法。