簡體   English   中英

房間持久性庫中的繼承

[英]Inheritance in the Room Persistence Library

TL; DR:如何使用Room Persistence Library存儲和檢索ClassAClassB類型的對象,這些對象都從同一“列表”中的ClassP繼承?

換句話說, 我應該如何存儲List<? extends BaseAnimal> 在我的房間DB中List<? extends BaseAnimal>


出於這個問題的目的,我有動物。

public abstract class BaseAnimal {
    @PrimaryKey(autoGenerate = true)
    private long id;

    public BaseAnimal(long id){this.id = id;}

    public abstract void func(int param);

    public long getId() {
        return id;
    }
}

動物有一個id並實現一些函數func 可能會有很多種動物。 首先,我有一個Elephant ,另外有一個trunkLength屬性,還有一個Giraffe ,還有一個neckLength屬性。

public class Giraffe extends BaseAnimal {
    public long neckLength;

    public Giraffe(long id) {
        super(id);
    }

    @Override
    public void func(int param) {

    }
}

在我的申請中,我有幾個ElephantGiraffe例子。 我如何使用Android Room Persistence Library存儲和檢索按BaseAnimal.id排序的BaseAnimal.id


期望

起初,我希望它會像這樣簡單:

  • 使用@Entity(tableName = "base_animal_table")注釋BaseAnimal@Entity(tableName = "base_animal_table")

  • 使用@Database注釋RoomDatabase擴展名(entities = {BaseAnimal.class},version = 1)

  • 添加用於插入數據訪問對象的函數
    @Insert void insertAnimal(BaseAnimal animal);

  • 將方法添加到存儲庫

     public void insertAnimal(BaseAnimal animal){ new insertAnimalAsyncTask(recipeDAO).execute(animal); } private static class insertAnimalAsyncTask extends AsyncTask<BaseAnimal, Void, Void> { private RecipeDAO mAsyncTaskDao; insertAnimalAsyncTask(RecipeDAO dao) { mAsyncTaskDao = dao; } @Override protected Void doInBackground(final BaseAnimal... params) { mAsyncTaskDao.insertAnimal(params[0]); return null; } } 

我希望這會導致空間生成一個名為base_animal_table的表,它看起來有點像這樣(帶有一些示例數據):

| id | ElephantTrunkLength | GiraffeNeckLength |
| 0  | NULL                | 12                |
| 12 | 1337                | NULL              |

我還希望我可以從這個表中檢索這樣的數據:

// this is in the DAO
@Query("SELECT * from `base_animal_table` ORDER BY id ASC")
LiveData<List<BaseAnimal>> getAllAnimals();

然后獲取一個列表,其中包含Elephant類型的實體及其trunkLength屬性集,以及類型為Giraffe實體及其neckLength集。 這似乎並不簡單。 我該如何實現呢?


我看到的一種方法如下,但我不確定它是否是最好的方法。 而且我也開始懷疑Room比使用普通的SQLite更容易。 我嘗試用空間為這種方法制作一個工作示例,但仍有一些未解決的問題。

一種方法

創建一個表base_animals ,它只包含id和其他基本動物屬性,以及它們的子類型的指示符:

// base_animals
| id | animalType |
| 0  | "GIRAFFE"  |
| 12 | "ELEPHANT" |

使用此表來保存所有動物及其id的列表。 使用id及其特定屬性(分別為trunkLengthneckLength )創建表elephants和表giraffes 然后我們可以通過在基表和子表中創建一個條目來將動物存儲在DB中。
要通過id檢索特定的動物,我們現在可以在base_animals表中找到animalType ,然后決定在哪個子表 - 我們需要搜索的elephantsgiraffes

我對這種方法的問題在於它需要我編寫相當多的代碼,每當我創建一個新的動物實體時我都必須更新它 - 例如Dolphin

所以,我的問題是: 我應該如何存儲List<? extends BaseAnimal> 在我的房間DB中List<? extends BaseAnimal>
如果我可以讓BaseAnimal成為一個抽象類,我會更喜歡它。

我不確定在這里使用繼承是個好主意。 我建議改用合成。

保留一個名為Animal(不是BaseAnimal)的類。

動物應該有你所建議的類型。

另一個表(AnimalProperties)將保存每只動物的屬性。 它將具有Animals表的外鍵以及屬性名稱和屬性值。

現在...

如果這就是你需要的全部,意味着一個具有類型和屬性的類,那么你就完全了。 但是如果你還需要這個類的行為方式與為鳥類實現fly()方法和run()狗一樣,那么你應該考慮使用Composition為Animal添加行為。

如果你不熟悉作文,請看一下這里的簡單解釋。

暫無
暫無

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

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