簡體   English   中英

主外鍵實現Java和Android機房

[英]Primary and foreign key implementation Java and Android Room

這是我第一次在 StackOverflow 中提出問題,如果我沒有正確或以某種方式提出問題,請原諒我。

我有來自父 class 評估的兩個子類(PerformanceAssessment 和 ObjectiveAssessment)。 我能夠成功地為我的學校項目的多態性部分要求進行向下轉換,並且能夠在向下轉換后將父母和孩子的實例保存到他們適當的數據庫中(我有一個評估表、性能評估表和目標評估表)。 但是,我現在遇到了 Android Room 數據庫問題。 我意識到我需要實現外鍵才能正確執行 CRUD 操作。 如何調整我的父類和子類代碼並添加適當的注釋以正確實現外鍵和主鍵? 我需要為每個 class 自動生成主鍵:父(評估)和兩個子(性能評估和目標評估)。 但是我還需要利用子主鍵作為父數據庫的外鍵,這樣當我刪除性能/目標評估的實例時,我也可以在向下轉換時刪除評估實例。 我發現很少有關於此的有用信息。 提前致謝。

我現在收到這些錯誤:

構建錯誤

父 Class:Assessment.java

@Entity(tableName = "assessment_table")
public class Assessment {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "assessment_id")
    private final int assessment_id;

    private String assessmentName;
    private String assessmentStart;
    private String assessmentEnd;
    private int courseID;

    public Assessment(int assessment_id, String assessmentName, String assessmentStart, String assessmentEnd, int courseID) {
        this.assessment_id = assessment_id;
        this.assessmentName = assessmentName;
        this.assessmentStart = assessmentStart;
        this.assessmentEnd = assessmentEnd;
        this.courseID = courseID;
    }

兒童 class:PerformanceAssessment.java

@Entity(tableName = "performance_assessment", foreignKeys = {
        @ForeignKey(
                entity = Assessment.class,
                parentColumns = "assessment_id",
                childColumns = "performance_id",
                onUpdate = CASCADE,
                onDelete = CASCADE
        )
})
public class PerformanceAssessment extends Assessment{

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "performance_id")
    private int performanceID;
    private String type;

    public PerformanceAssessment(int assessment_id, String assessmentName, String assessmentStart, String assessmentEnd, int courseID, int performanceID, String type) {
        super(assessment_id, assessmentName, assessmentStart, assessmentEnd, courseID);
        this.performanceID = performanceID;
        this.type = type;
    }

兒童 class:ObjectiveAssessment.java

@Entity(tableName = "objective_assessment", foreignKeys = {
        @ForeignKey(
                entity = Assessment.class,
                parentColumns = "assessment_id",
                childColumns = "objective_id",
                onUpdate = CASCADE,
                onDelete = CASCADE
        )
})
public class ObjectiveAssessment extends Assessment{

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "objective_id")
    private int objective_ID;
    private String type;

    public ObjectiveAssessment(int assessmentID, String assessmentName, String assessmentStart, String assessmentEnd, int courseID, int objective_ID, String type) {
        super(assessmentID, assessmentName, assessmentStart, assessmentEnd, courseID);
        this.objective_ID = objective_ID;
        this.type = type;
    }

這是我在應用程序中添加新評估的部分:

public void saveAssessment(View view) {

        assessmentTitle = editName.getText().toString();
        assessmentStart = editStart.getText().toString();
        assessmentEnd = editEnd.getText().toString();

        //Check if fields are empty:
        if (assessmentTitle.isEmpty() || assessmentStart.isEmpty() || assessmentEnd.isEmpty()) {

            Toast.makeText(AddAssessmentScreen.this, "Fill out required fields.", Toast.LENGTH_LONG).show();
            return;

        }
        else {

            //Check assessment type selected (used Downcasting for polymorphism):

            if (assessment_type == true) {
                Assessment performanceAssessment = new PerformanceAssessment(0, assessmentTitle, assessmentStart, assessmentEnd, currentCourseID, 0, selectedString);
                PerformanceAssessment castedPerformance = (PerformanceAssessment) performanceAssessment;
                //Insert assessment to database performance_assessment table (Performance child type):
                repository.insert(castedPerformance);
                Repository addToAssessment = new Repository(getApplication());
                //Insert assessment to database assessment_table (Assessment parent type):
                addToAssessment.insert(performanceAssessment);

            }
            else {
                Assessment objectiveAssessment = new ObjectiveAssessment(0,assessmentTitle, assessmentStart, assessmentEnd, currentCourseID, 0, selectedString);
                ObjectiveAssessment castedObjective = (ObjectiveAssessment) objectiveAssessment;
                //Insert assessment to database objective_assessment table (Objective child type):
                repository.insert(castedObjective);
                Repository addToAssessment = new Repository(getApplication());
                //Insert assessment to database assessment_table (Assessment parent type):
                addToAssessment.insert(objectiveAssessment);
            }

            Toast.makeText(AddAssessmentScreen.this, "New assessment added. Refresh previous screen.", Toast.LENGTH_LONG).show();

        }

如何調整我的父類和子類代碼並添加適當的注釋以正確實現外鍵和主鍵?

讓assessment_id 始終是主鍵,即不要在子類中對其進行編碼,然后在子類中擁有一個用於引用/映射/關聯的字段。

所以 PerformanceAssessment 可以是:-

@Entity(tableName = "performance_assessment", foreignKeys = {
        @ForeignKey(
                entity = Assessment.class,
                parentColumns = "assessment_id",
                childColumns = "assessment_reference",
                onUpdate = CASCADE,
                onDelete = CASCADE
        )
})
public class PerformanceAssessment extends Assessment {

    private int assessment_reference; //<<<<<<<<<
    private String type;

    public PerformanceAssessment(int assessment_id, String assessmentName, String assessmentStart, String assessmentEnd, int courseID, int assessment_reference, String type) {
        super(assessment_id, assessmentName, assessmentStart, assessmentEnd, courseID);
        this.assessment_reference = assessment_reference;
        this.type = type;
    }
    ....

並且所有編譯和基礎表都將使用以下方式構建:-

    _db.execSQL("CREATE TABLE IF NOT EXISTS `assessment_table` (`assessment_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `assessmentName` TEXT, `assessmentStart` TEXT, `assessmentEnd` TEXT, `courseID` INTEGER NOT NULL)");
    _db.execSQL("CREATE TABLE IF NOT EXISTS `performance_assessment` (`assessment_reference` INTEGER NOT NULL, `type` TEXT, `assessment_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `assessmentName` TEXT, `assessmentStart` TEXT, `assessmentEnd` TEXT, `courseID` INTEGER NOT NULL, FOREIGN KEY(`assessment_reference`) REFERENCES `assessment_table`(`assessment_id`) ON UPDATE CASCADE ON DELETE CASCADE )");
  • ObjectiveAssessment 顯然類似。

但是我還需要利用子主鍵作為父數據庫的外鍵,這樣當我刪除性能/目標評估的實例時,我也可以在向下轉換時刪除評估實例。

如果使用 1 (Assessment) - Many (PerformanceAssessments) 是可能的,一個評估有多個 PerformanceAssessments 怎么辦? 刪除 1 個 PerformanceAsessment 將刪除父評估,然后由於使用onDelete CASCADE將刪除級聯到所有其他 PerformanceAssessment 和 ObjectiveAssessment。 刪除不會傳播到父級(這就是使用術語 CASCADE 的原因,因為它暗示向下而不是無論如何)。

例如,您有一個包含 4 個 PerformanceAssessments 的評估,假設 3 個 ObjectiveAssessments 其中一個 PerformanceAssessments 被錯誤地添加了。 是否必須刪除所有內容並重新輸入以更正 1 錯誤的績效評估。

如果這是你想要的,你可以引入一個觸發器來自動化這種向上傳播,刪除任何東西並刪除所有東西。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM