sql >> Database teknologi >  >> RDS >> SQLite

Tilknytte tabeller ved hjælp af Room-database i Android Studio

Jeg tror på følgende arbejdseksempel er en af ​​måderne, hvorpå du kan opnå det, du ønsker.

Koden

Eksperimentenheden (tabel) 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;
    }
}
  • Intet særligt undtagen måske @Ignorer 'd constructor (for nemheds skyld)

Prøveenheden 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;
    }
}
  • Intet særligt undtagen måske @Ignorer 'd constructor (for nemheds skyld)

Dao.java (kombineret for nemheds skyld)

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;
        }
    }
}
  • Bemærk TrialWithExperiment klasse, definerer dette en kombination af en prøveversion og dens ejereksperiment.
  • Bemærk, hvordan kolonnenavne er forskellige, f.eks. ikke kun id, men eksperiment-id og trialId adskiller dem.
  • Bemærk den sidste @Query getExperimentsWithTrials() dette vil returnere en liste over forsøg med deres eksperimenter.

@Database ExperimentDatabase.java

@Database(entities = {Experiment.class, Trial.class}, version = 1,exportSchema = false)
public abstract class ExperimentDatabase extends RoomDatabase {
    public abstract Dao getDao();
} 

Endelig en aktivitet, der udnytter ovenstående :-

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()
            );

        }
    }
}

Dette :-

  • Tilføjer 2 eksperimenter (hver kørsel)
  • Henter eksperimenter i et datointerval (dette forudsætter et SQLite-genkendt datoformat) og udlæser dem til loggen.
  • Henter alle eksperimenter og sender dem til loggen.
  • Bruger listen over eksperimenter til at tilføje en prøveversion til hvert eksperiment.
  • Henter alle forsøg og sender dem til loggen.
  • Henter alle forsøg sammen med det overordnede eksperiment og sender dem til loggen.

Resultatet

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

Alternativ/Yderligere

En anden tilgang kunne være at bruge @Relation at oprette et objekt pr. eksperiment, der inkluderer en liste over de relaterede/tilknyttede forsøg i det pågældende objekt.

Hvis du udvider ovenstående, kan følgende tilføjes til 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;
    }
}

og derefter kunne følgende tilføjes til 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()
            );
        }
    }
}
  • Bemærk, hvordan forsøgene opnås ved at gå gennem listen over forsøg, der er integreret med ExperimentWithTrials objekt, i modsætning til listen over kombinerede eksperiment- og forsøgsdata fra den forrige.

    • Dette sandsynligvis til en renere OO-måde.
    • Men SQLite ser dette ud til at være besværligt/ineffektivt, da det ser ud til at køre flere forespørgsler. En for at få eksperimenterne og derefter en anden for at få de underliggende forsøg for hvert eksperiment.

Resulterende ekstra output

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
  • Bemærk, at for nemheds skyld er alt ovenstående blevet kørt på hovedtråden (dvs. .allowMainThreadQueries() er blevet brugt). Hvis du følger anbefalingerne, vil al databaseadgang ske via en anden tråd, i hvilket tilfælde @Transaction-annoteringen anbefales til forespørgsler.



  1. Hvordan opretter du en tilfældig streng, der er egnet til et sessions-id i PostgreSQL?

  2. SQL Developer 4.1.3 udgivet

  3. Sådan grupperes efter måned i PostgreSQL

  4. Sådan fungerer UNHEX() i MariaDB