Я считаю, что следующий Рабочий пример - это один из способов достижения желаемого.
Код
Экспериментальная сущность (таблица) Experiment.java
@Entity
public class Experiment {
@PrimaryKey(autoGenerate = true)
private long experimentId;
private String experimentName;
private String experimentDate;
public Experiment() {
}
@Ignore
public Experiment(String name, String date) {
this.experimentName = name;
this.experimentDate = date;
}
public long getExperimentId() {
return experimentId;
}
public void setExperimentId(long experimentId) {
this.experimentId = experimentId;
}
public String getExperimentName() {
return experimentName;
}
public void setExperimentName(String experimentName) {
this.experimentName = experimentName;
}
public String getExperimentDate() {
return experimentDate;
}
public void setExperimentDate(String experimentDate) {
this.experimentDate = experimentDate;
}
}
- Ничего особенного, кроме, возможно, @ Ignore d конструктора (для удобства)
Пробная сущность Trial.java
@Entity
public class Trial {
@PrimaryKey(autoGenerate = true)
private long trialId;
@ForeignKey(entity = Experiment.class, parentColumns = {BaseColumns._ID},childColumns = "parentExperiment", onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE)
private long parentExperiment;
private String trialVariable;
private String trialResult;
public Trial() {
}
@Ignore
public Trial(long parentExperimentId, String variable, String result) {
this.parentExperiment = parentExperimentId;
this.trialVariable = variable;
this.trialResult = result;
}
public long getTrialId() {
return trialId;
}
public void setTrialId(long trialId) {
this.trialId = trialId;
}
public long getParentExperiment() {
return parentExperiment;
}
public void setParentExperiment(long parentExperiment) {
this.parentExperiment = parentExperiment;
}
public String getTrialVariable() {
return trialVariable;
}
public void setTrialVariable(String trialVariable) {
this.trialVariable = trialVariable;
}
public String getTrialResult() {
return trialResult;
}
public void setTrialResult(String trialResult) {
this.trialResult = trialResult;
}
}
- Ничего особенного, кроме, возможно, @ Ignore d конструктора (для удобства)
Dao.java (объединено для удобства)
public interface Dao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
long[] insertExperiments(Experiment... experiments);
@Insert(onConflict = OnConflictStrategy.IGNORE)
long insertExperiment(Experiment experiment);
@Insert(onConflict = OnConflictStrategy.IGNORE)
long[] insertTrials(Trial... trials);
@Insert(onConflict = OnConflictStrategy.IGNORE)
long insertTrial(Trial trial);
@Update(onConflict = OnConflictStrategy.IGNORE)
int updateExperiments(Experiment... experiments);
@Update(onConflict = OnConflictStrategy.IGNORE)
int updateExperiment(Experiment experiment);
@Update(onConflict = OnConflictStrategy.IGNORE)
int updateTrials(Trial... trials);
@Update(onConflict = OnConflictStrategy.IGNORE)
int updateTrial(Trial trial);
@Delete
int deleteExperiments(Experiment... experiments);
@Delete
int deleteExperiment(Experiment experiment);
@Delete
int deleteTrials(Trial... trials);
@Delete
int deleteTrial(Trial trial);
@Query("SELECT * FROM Experiment")
List<Experiment> getAllexperiments();
@Query("SELECT * FROM Experiment WHERE experimentDate BETWEEN :startdate AND :enddate")
List<Experiment> getExperimentsInDateRange(String startdate, String enddate);
@Query("SELECT * FROM Trial")
List<Trial> getAllTrials();
@Query("SELECT * FROM Experiment JOIN Trial ON parentExperiment = experimentId")
List<TrialWithExperiment> getExperimentsWithTrials();
public class TrialWithExperiment {
private long experimentId;
private String experimentName;
private String experimentDate;
private long trialId;
private String trialVariable;
private String trialResult;
public long getExperimentId() {
return experimentId;
}
public void setExperimentId(long experimentId) {
this.experimentId = experimentId;
}
public String getExperimentName() {
return experimentName;
}
public void setExperimentName(String experimentName) {
this.experimentName = experimentName;
}
public String getExperimentDate() {
return experimentDate;
}
public void setExperimentDate(String experimentDate) {
this.experimentDate = experimentDate;
}
public void setTrialId(long trialId) {
this.trialId = trialId;
}
public long getTrialId() {
return trialId;
}
public String getTrialVariable() {
return trialVariable;
}
public void setTrialVariable(String trialVariable) {
this.trialVariable = trialVariable;
}
public String getTrialResult() {
return trialResult;
}
public void setTrialResult(String trialResult) {
this.trialResult = trialResult;
}
}
}
- Обратите внимание на класс TrialWithExperiment , он определяет комбинацию пробной версии и собственного эксперимента.
- Обратите внимание, как различаются имена столбцов, например, не просто идентификатор, но экспериментальный идентификатор и триальный идентификатор различают их.
- Обратите внимание на последние @Query getExperimentWithTrials () это вернет список испытаний с их экспериментами.
@Database ExperimentDatabase.java
@Database(entities = {Experiment.class, Trial.class}, version = 1,exportSchema = false)
public abstract class ExperimentDatabase extends RoomDatabase {
public abstract Dao getDao();
}
Наконец, действие, которое использует вышеупомянутое: -
public class MainActivity extends AppCompatActivity {
ExperimentDatabase mDB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDB = Room.databaseBuilder(this,ExperimentDatabase.class,"experimentdb").allowMainThreadQueries().build();
mDB.getDao().insertExperiments(new Experiment[]{
new Experiment("Experiment 1","2019-01-01"),
new Experiment("Experiment 2", "2019-02-01")
});
List<Experiment> experiments = mDB.getDao().getExperimentsInDateRange("2019-01-01","2019-12-31");
for (Experiment e: experiments) {
Log.d("EXPERIMENTS", "Experiment is " + e.getExperimentName() + " on " + e.getExperimentDate());
}
experiments = mDB.getDao().getAllexperiments();
for (Experiment e: experiments) {
Log.d("EXPERIMENTS", "Experiment is " + e.getExperimentName() + " on " + e.getExperimentDate());
}
for (Experiment e: experiments) {
mDB.getDao().insertTrial(
new Trial(
e.getExperimentId(),
"Variable for " + e.getExperimentName(),
"Result for Experiment on " + e.getExperimentDate()
)
);
}
List<Trial> trials = mDB.getDao().getAllTrials();
for (Trial t: trials ) {
Log.d("TRIAL ",
"Trial is for ExperimentID " + String.valueOf(t.getParentExperiment()) +
"\n\tVariable = " + t.getTrialVariable() +
"Result = " + t.getTrialResult()
);
}
List<Dao.TrialWithExperiment> trialsWithExperiments = mDB.getDao().getExperimentsWithTrials();
for (Dao.TrialWithExperiment te:trialsWithExperiments) {
Log.d(
"TRIALWITHEXPERIMENT",
"Experiment Name = " + te.getExperimentName() +
"\n\tExperiment Date = " + te.getExperimentDate() +
"\n\t\tTrial Variable = " + te.getTrialVariable() +
"\n\t\tTrial Result = " + te.getTrialResult()
);
}
}
}
Это: -
- Добавляет 2 эксперимента (каждый запуск)
- Извлекает эксперименты в диапазоне дат (предполагается, что формат даты распознается SQLite) и выводит их в журнал.
- Извлекает все эксперименты и выводит их в журнал.
- Использует Список экспериментов для добавления Испытания к каждому эксперименту.
- Извлекает все испытания и выводит их в журнал.
- Извлекает все испытания вместе с родительским экспериментом и выводит их в журнал.
Результат
05-28 10:19:42.770 5750-5750/? D/EXPERIMENTS: Experiment is Experiment 1 on 2019-01-01
05-28 10:19:42.770 5750-5750/? D/EXPERIMENTS: Experiment is Experiment 2 on 2019-02-01
05-28 10:19:42.776 5750-5750/? D/EXPERIMENTS: Experiment is Experiment 1 on 2019-01-01
05-28 10:19:42.776 5750-5750/? D/EXPERIMENTS: Experiment is Experiment 2 on 2019-02-01
05-28 10:19:42.786 5750-5750/? D/TRIAL: Trial is for ExperimentID 1
Variable = Variable for Experiment 1Result = Result for Experiment on 2019-01-01
05-28 10:19:42.786 5750-5750/? D/TRIAL: Trial is for ExperimentID 2
Variable = Variable for Experiment 2Result = Result for Experiment on 2019-02-01
05-28 10:19:42.787 5750-5750/? D/TRIALWITHEXPERIMENT: Experiment Name = Experiment 1
Experiment Date = 2019-01-01
Trial Variable = Variable for Experiment 1
Trial Result = Result for Experiment on 2019-01-01
05-28 10:19:42.787 5750-5750/? D/TRIALWITHEXPERIMENT: Experiment Name = Experiment 2
Experiment Date = 2019-02-01
Trial Variable = Variable for Experiment 2
Trial Result = Result for Experiment on 2019-02-01
Alternative / Дополнительные
Другим подходом может быть использование @ Relation для создания объекта в эксперименте, который включает в себя список связанных / связанных испытаний в этом объекте.
Расширяя вышесказанное, можно добавить следующее к Dao.java
@Query("SELECT * FROM Experiment")
List<ExperimentWithTrials> getExperimentsAndTrials();
class ExperimentWithTrials {
private long experimentId;
private String experimentName;
private String experimentDate;
@Relation(parentColumn = "experimentId", entityColumn = "parentExperiment")
List<Trial> trials;
public long getExperimentId() {
return experimentId;
}
public void setExperimentId(long experimentId) {
this.experimentId = experimentId;
}
public String getExperimentName() {
return experimentName;
}
public void setExperimentName(String experimentName) {
this.experimentName = experimentName;
}
public String getExperimentDate() {
return experimentDate;
}
public void setExperimentDate(String experimentDate) {
this.experimentDate = experimentDate;
}
public List<Trial> getTrials() {
return trials;
}
public void setTrials(List<Trial> trials) {
this.trials = trials;
}
}
, а затем к MainActivity.java можно добавить следующее
List<Dao.ExperimentWithTrials> experimentsWithTrials = mDB.getDao().getExperimentsAndTrials();
for (Dao.ExperimentWithTrials et: experimentsWithTrials ) {
Log.d(
"EXPERIMENTANDTRIALS",
"Experiment Name = " + et.getExperimentName() +
"\n\tExperiment Date = " + et.getExperimentDate()
);
for (Trial t: et.getTrials()) {
Log.d(
"TRIALFOREXPERIMENT",
"\t\tVariable = " + t.getTrialVariable() +
"\n\t\tResult = " + t.getTrialResult()
);
}
}
}
Обратите внимание, как Испытания получаются при циклическом просмотре списка Испытаний, встроенных в объект ExperimentWithTrials , в отличие от списка объединенных данных Эксперимента и Испытаний из предыдущего.
- Это, наверное, чище ОО пути.
- Однако в SQLite это кажется громоздким / неэффективным, поскольку кажется, что он запускает несколько запросов. Один для получения экспериментов, а другой - для базовых испытаний для каждого эксперимента.
Результирующий дополнительный вывод
05-28 13:05:35.052 6524-6524/? D/EXPERIMENTANDTRIALS: Experiment Name = Experiment 1
Experiment Date = 2019-01-01
05-28 13:05:35.052 6524-6524/? D/TRIALFOREXPERIMENT: Variable = Variable for Experiment 1
Result = Result for Experiment on 2019-01-01
05-28 13:05:35.052 6524-6524/? D/EXPERIMENTANDTRIALS: Experiment Name = Experiment 2
Experiment Date = 2019-02-01
05-28 13:05:35.052 6524-6524/? D/TRIALFOREXPERIMENT: Variable = Variable for Experiment 2
Result = Result for Experiment on 2019-02-01
- Обратите внимание, что для удобства все вышеперечисленное было выполнено в основном потоке (т. Е. .allowMainThreadQueries () ). Если вы будете следовать рекомендациям, доступ к базе данных будет осуществляться через другой поток, и в этом случае для запросов рекомендуется аннотация @Transaction.