如何将项目添加到子实体,外键引用 Android 房间中的父实体?
How can I add an item to a child entity with foreign key reference to the parent entity in Android Room?
我正在尝试编写一个类似于 Strava 的简单应用程序,它将使用 Room Persistence Library
记录活动
我的两个实体是:
@Entity
public class ActivityRecord {
@PrimaryKey(autoGenerate = true)
private long id;
private Date startTimestamp;
private Date endTimestamp;
public ActivityRecord() {
this.startTimestamp = new Date();
this.endTimestamp = this.startTimestamp;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Date getStartTimestamp() {
return startTimestamp;
}
public void setStartTimestamp(Date startTimestamp) {
this.startTimestamp = startTimestamp;
}
public Date getEndTimestamp() {
return endTimestamp;
}
public void setEndTimestamp(Date endTimestamp) {
this.endTimestamp = endTimestamp;
}
}
和:
@Entity(foreignKeys = @ForeignKey(
entity = ActivityRecord.class,
parentColumns = "id",
childColumns = "recordId",
onDelete = CASCADE),
indices = {@Index(value = {"recordId"})})
public class ActivityLocation {
@PrimaryKey(autoGenerate = true)
private long id;
private double latitude;
private double longitude;
private long recordId;
public ActivityLocation(double latitude, double longitude, long recordId) {
this.latitude = latitude;
this.longitude = longitude;
this.recordId = recordId;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public long getRecordId() { return recordId; }
public void setRecordId(long recordId) { this.recordId = recordId; }
}
我还创建了这两个 DAO:
@Dao
public interface ActivityRecordDao {
@Query("SELECT * FROM ActivityRecord ORDER BY id DESC")
LiveData<List<ActivityRecord>> getActivityRecords();
@Query("SELECT * FROM ActivityRecord WHERE id = :id")
ActivityRecord getActivityRecordById(long id);
@Query("SELECT * FROM ActivityRecord ORDER BY id DESC LIMIT 1")
ActivityRecord getLastActivityRecord();
@Insert
long setActivityRecord(ActivityRecord record);
@Update
void updateActivityRecord(ActivityRecord record);
@Delete
void deleteActivityRecord(ActivityRecord record);
}
和:
@Dao
public interface ActivityLocationDao {
@Query("SELECT * FROM ActivityLocation ORDER BY timestamp DESC")
LiveData<List<ActivityLocation>> getActivityLocations();
@Query("SELECT * FROM ActivityLocation WHERE id = :id")
ActivityLocation getActivityLocationById(long id);
@Query("SELECT * FROM ActivityLocation WHERE recordId = :recordId")
LiveData<List<ActivityLocation>> getActivityLocationsByRecordId(long recordId);
@Insert
void setActivityLocation(ActivityLocation location);
@Delete
void deleteActivityLocation(ActivityLocation location);
}
我可以从 MainActivity.java
中插入、更新和删除 ActivityRecords
,但我还没有找到如何在我的 BroadcastReceiver
当它从 com.google.android.gms.location.LocationResult
接收到更新的位置数据时
所以,我的问题是,如何添加一个 ActivityLocation
子项并引用一个 ActivityRecord
父项,以及如何在我的 [=18] 中获取我的应用程序数据库的实例=]?
解决了我的 BroadcastReceiver 中的 AsyncTask 问题。
我首先需要传入上下文和 activityLocations 列表作为参数。
这是通过创建私有参数 class 解决的:
private static class ActivityLocationParams {
Context context;
List<ActivityLocation> locations;
ActivityLocationParams(Context context, List<ActivityLocation> locations) {
this.context = context;
this.locations = locations;
}
}
接下来我创建了一个私有的 AsyncTask class:
private static class addActivityLocationAsyncTask extends AsyncTask<ActivityLocationParams, Void, Integer> {
@Override
protected Integer doInBackground(ActivityLocationParams... params) {
Context context = params[0].context;
List<ActivityLocation> locations = params[0].locations;
AppDatabase db = AppDatabase.getInstance(context);
ActivityRecord activityRecord = db.activityRecordDao().getLastActivityRecord();
int count = 0;
for (ActivityLocation location : locations) {
if (activityRecord == null) {
continue;
}
ActivityLocation activityLocation
= new ActivityLocation(location.getLatitude(),
location.getLongitude(), activityRecord.getId());
db.activityLocationDao().setActivityLocation(activityLocation);
count += 1;
}
return count;
}
@Override
protected void onPostExecute(Integer count) {
Log.d(TAG, "Number of ActivityLocations added: " + count.toString());
}
}
doInBackground
完成后,我打印出添加到数据库中的项目数以供调试之用。
最后我创建了 params 对象并在 BroadcastReceiver 中调用了 AsyncTask:
ActivityLocationParams params = new ActivityLocationParams(context, locations);
new addActivityLocationAsyncTask().execute(params);
我正在尝试编写一个类似于 Strava 的简单应用程序,它将使用 Room Persistence Library
记录活动我的两个实体是:
@Entity
public class ActivityRecord {
@PrimaryKey(autoGenerate = true)
private long id;
private Date startTimestamp;
private Date endTimestamp;
public ActivityRecord() {
this.startTimestamp = new Date();
this.endTimestamp = this.startTimestamp;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Date getStartTimestamp() {
return startTimestamp;
}
public void setStartTimestamp(Date startTimestamp) {
this.startTimestamp = startTimestamp;
}
public Date getEndTimestamp() {
return endTimestamp;
}
public void setEndTimestamp(Date endTimestamp) {
this.endTimestamp = endTimestamp;
}
}
和:
@Entity(foreignKeys = @ForeignKey(
entity = ActivityRecord.class,
parentColumns = "id",
childColumns = "recordId",
onDelete = CASCADE),
indices = {@Index(value = {"recordId"})})
public class ActivityLocation {
@PrimaryKey(autoGenerate = true)
private long id;
private double latitude;
private double longitude;
private long recordId;
public ActivityLocation(double latitude, double longitude, long recordId) {
this.latitude = latitude;
this.longitude = longitude;
this.recordId = recordId;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public long getRecordId() { return recordId; }
public void setRecordId(long recordId) { this.recordId = recordId; }
}
我还创建了这两个 DAO:
@Dao
public interface ActivityRecordDao {
@Query("SELECT * FROM ActivityRecord ORDER BY id DESC")
LiveData<List<ActivityRecord>> getActivityRecords();
@Query("SELECT * FROM ActivityRecord WHERE id = :id")
ActivityRecord getActivityRecordById(long id);
@Query("SELECT * FROM ActivityRecord ORDER BY id DESC LIMIT 1")
ActivityRecord getLastActivityRecord();
@Insert
long setActivityRecord(ActivityRecord record);
@Update
void updateActivityRecord(ActivityRecord record);
@Delete
void deleteActivityRecord(ActivityRecord record);
}
和:
@Dao
public interface ActivityLocationDao {
@Query("SELECT * FROM ActivityLocation ORDER BY timestamp DESC")
LiveData<List<ActivityLocation>> getActivityLocations();
@Query("SELECT * FROM ActivityLocation WHERE id = :id")
ActivityLocation getActivityLocationById(long id);
@Query("SELECT * FROM ActivityLocation WHERE recordId = :recordId")
LiveData<List<ActivityLocation>> getActivityLocationsByRecordId(long recordId);
@Insert
void setActivityLocation(ActivityLocation location);
@Delete
void deleteActivityLocation(ActivityLocation location);
}
我可以从 MainActivity.java
中插入、更新和删除 ActivityRecords
,但我还没有找到如何在我的 BroadcastReceiver
当它从 com.google.android.gms.location.LocationResult
所以,我的问题是,如何添加一个 ActivityLocation
子项并引用一个 ActivityRecord
父项,以及如何在我的 [=18] 中获取我的应用程序数据库的实例=]?
解决了我的 BroadcastReceiver 中的 AsyncTask 问题。
我首先需要传入上下文和 activityLocations 列表作为参数。 这是通过创建私有参数 class 解决的:
private static class ActivityLocationParams {
Context context;
List<ActivityLocation> locations;
ActivityLocationParams(Context context, List<ActivityLocation> locations) {
this.context = context;
this.locations = locations;
}
}
接下来我创建了一个私有的 AsyncTask class:
private static class addActivityLocationAsyncTask extends AsyncTask<ActivityLocationParams, Void, Integer> {
@Override
protected Integer doInBackground(ActivityLocationParams... params) {
Context context = params[0].context;
List<ActivityLocation> locations = params[0].locations;
AppDatabase db = AppDatabase.getInstance(context);
ActivityRecord activityRecord = db.activityRecordDao().getLastActivityRecord();
int count = 0;
for (ActivityLocation location : locations) {
if (activityRecord == null) {
continue;
}
ActivityLocation activityLocation
= new ActivityLocation(location.getLatitude(),
location.getLongitude(), activityRecord.getId());
db.activityLocationDao().setActivityLocation(activityLocation);
count += 1;
}
return count;
}
@Override
protected void onPostExecute(Integer count) {
Log.d(TAG, "Number of ActivityLocations added: " + count.toString());
}
}
doInBackground
完成后,我打印出添加到数据库中的项目数以供调试之用。
最后我创建了 params 对象并在 BroadcastReceiver 中调用了 AsyncTask:
ActivityLocationParams params = new ActivityLocationParams(context, locations);
new addActivityLocationAsyncTask().execute(params);