部屋:1対多

みなさんこんにちは。 2018年以外のほぼ1年間、GoogleはArchitecture Componentsに積極的に取り組んでいます優れたドキュメントにより、問題や困難なしに新しいコンポーネントの使用を開始できます。 しかし、コードハニーの樽の軟膏には常にハエがあります。 以下の注意事項は真実であると主張していませんが、ライブラリコードのグーグル検索と表示に2〜3時間かかる可能性があります。



1対多



ここではすべてが簡単です。ドキュメントには、エンティティ間の1対多の関係を得るためにクラスを編成する方法が記載されています。 2つのエンティティを取得します。



@Entity public class DialogPojo { @NonNull @PrimaryKey String id; //other fields } @Entity( foreignKeys = @ForeignKey(entity = DialogPojo.class, parentColumns = "id", childColumns = "dialogId", onDelete = ForeignKey.CASCADE), primaryKeys = {"dialogId", "tag"}) public class TagPojo { @NonNull String dialogId; @NonNull String tag; //other fields }
      
      





そしてそれらを単一のエンティティにバインドします:



 public class DialogWithTags { @Embedded public DialogPojo dialog; @Relation(parentColumn = "id", entity = TagPojo.class, entityColumn = "dialogId") public List<TagPojo> tags; //other fields }
      
      





DialogWithTagsタイプの新しいエンティティを取得するには、Daoを使用する必要があります。DaoはDialogPojoテーブルからデータをロードし、リンクテーブル(entity = TagPojo.class)からタグを自動的にロードします。



 @Dao public interface DialogDao { @Query("SELECT * FROM DialogPojo WHERE id = :dialogId") LiveData<DialogWithTags> loadDialogBy(String dialogId); @Query("SELECT * FROM DialogPojo WHERE id = :dialogId") DialogWithTags getDialogBy(String dialogId); }
      
      





この知識を使用すると、すでにデススターアプリケーションを収集することが可能です。 しかし、作業の過程で疑問が生じる場合があり、その答えは準備段階で最もよく知られています。



誠実さ



奇妙なことに、DialogWithTagsのリクエストはデータの整合性を保証しません。 つまり、DialogPojoはすでにロードされているが、TagPojoリストはロードされていない可能性があります。 プログラムのコンパイルの段階で、起こりうる問題に関する警告が表示されます。 そして、誰がこれらの警告を読みますか? データの整合性を確保するには、トランザクションアノテーションをリクエストに追加する必要があります。



 @Dao public interface DialogDao { @Transaction @Query("SELECT * FROM DialogPojo WHERE id = :dialogId") LiveData<DialogWithTags> loadDialogBy(String dialogId); @Transaction @Query("SELECT * FROM DialogPojo WHERE id = :dialogId") DialogWithTags getDialogBy(String dialogId); }
      
      





保存中



残念ながら、DialogWithTagsモデルの保存は機能しません。 たとえば、次のように、データを個別に、できれば1つのトランザクションで保存する必要があります。



 @Dao public abstract class DialogDao { @Transaction public void insert(DialogWithTags dialogWithTags) { insert(dialogWithTags.dialog); for(TagPojo tag: dialogWithTags.tags) { insert(tag); } } @Insert(onConflict = OnConflictStrategy.IGNORE) public abstract long insert(DialogPojo dialog); @Insert(onConflict = OnConflictStrategy.IGNORE) public abstract long insert(TagPojo tag); .... }
      
      





ライブデータ



LiveDataを使用する場合、最大の失望が待っています。 データは、[埋め込み]ダイアログフィールドに対してのみ有効になります。 タグへの変更は追跡されません。 もちろん、タグフィールドをLiveDataとして宣言できますが、LiveDataは少なくとも1つのオブザーバーが登録されている場合にのみデータを返すことを忘れないでください。



おわりに



他のフレームワークと同様に、アーキテクチャコンポーネントは多くの問題を解決し、開発者を定型コードから救い、生活をより美しくしますが、独自の問題も追加します。 私の場合、フレームワークはプロジェクトを正常に実装し、そこで素晴らしい気分になりました。



All Articles