Android
Data objects
Android開発におけるParseデータオブジェクト関係の実践方法
19 分
androidにおける関係性 はじめに parseを使用すると、データオブジェクト間の関係を確立して保存できます。この動作をモデル化するために、任意の parseobject parseobject を他の parseobject parseobject の値として使用できます。内部的に、parseフレームワークは、一貫性を維持するために参照されるオブジェクトを一箇所に保存します。これにより、複雑なクエリを構築および実行する際に追加の力を得ることができます。主な関係のタイプは3つあります 一対一 一対一 , 2つのオブジェクト間に直接的な関係を確立します; 一対多 一対多 , 1つのオブジェクトが多くの他のオブジェクトに関連付けられる場合; 多対多 多対多 , 多くのオブジェクト間に多くの複雑な関係を作成できます。 parseでの「 一対多 一対多 」関係を作成する方法は2つあります 最初の方法は、 ポインタ ポインタ を使用することで、 子クラス、 子クラス、 の作成とクエリ時間が最も速いです。 2つ目の方法は、 配列 配列 を使用することで、 ポインタ ポインタ を親クラスで使用することができ、サイズによってはクエリ時間が遅くなる可能性があります。このパフォーマンスの問題のため、ポインタの例のみを使用します。 parseでの「 多対多 多対多 」関係を作成する方法は3つあります。 最初の方法は、parseの リレーション リレーション , 作成とクエリ時間が最も速いです。このガイドではこれを使用します。 2つ目の方法は、 配列 配列 を使用することで、 ポインタ ポインタ のサイズによってはクエリ時間が遅くなる可能性があります。 3つ目の方法は、 結合テーブル 結合テーブル を使用することで、古典的なデータベースのアイデアです。多対多の関係がある場合、両側のすべての objectid objectid または ポインタ ポインタ を組み合わせて、新しい別のテーブルを作成し、その中で関係を追跡します。 このチュートリアルでは、android studio 4 1 1で作成された基本的なアプリを使用します。 buildtoolsversion=30 0 2 buildtoolsversion=30 0 2 、 compile sdk version = 30 0 2 compile sdk version = 30 0 2 と targetsdkversion 30 targetsdkversion 30 いつでも、このチュートリアルで構築した完全なandroidプロジェクトに、私たちのgithubリポジトリでアクセスできます。 kotlinの例リポジトリ javaの例リポジトリ 目標 私たちの目標は、実用的な本アプリを作成することでparseリレーションを理解することです。 ここに私たちが達成しようとしていることのプレビューがあります 前提条件 このチュートリアルを完了するには、次のものが必要です android studio back4appで作成されたアプリ。 注 新しいparseアプリのチュートリアル を参照して、back4appでparseアプリを作成する方法を学んでください。 back4appに接続されたandroidアプリ。 注 parse sdkのインストールチュートリアル を参照して、back4appに接続されたandroid studioプロジェクトを作成してください。 android 4 1 (jelly bean) 以上を実行しているデバイス(または 仮想デバイス )。 本アプリの理解 使用する主なオブジェクトクラスは book book クラスで、各書籍エントリを登録に保存します。また、他の3つのオブジェクトクラスは次のとおりです 出版社 出版社 書籍の出版社名、 一対多 一対多 の関係を持つ book book ジャンル ジャンル 書籍のジャンル、 一対多 一対多 の関係を持つ book book この例では、書籍は1つのジャンルしか持てないと考えます; 著者 著者 書籍の著者、 多対多 多対多 の関係を持つ book book , 書籍は複数の著者を持つことができ、著者も複数の書籍を持つことができます; これらのデータモデルの視覚的表現 始めましょう! 次のステップの前に、 back4app back4app を私たちのアプリケーションに接続する必要があります。 appid appid と clientkey clientkey を back4app back4app から string xml string xml ファイルに保存し、その後 parse parse を私たちの app java app java または app kt app kt ファイルで初期化します。 もし 新しいparseアプリのチュートリアル を知らない場合は、 parse parse をアプリに初期化する方法を確認してください。 または、上記のgithubリンクから共有したプロジェクトをダウンロードし、 appid appid と clientkey clientkey の部分だけを編集することもできます。 1 本の関連オブジェクトを保存してリストする このステップでは、次のようにして ジャンル ジャンル , 出版社 出版社 と 著者 著者 クラスを 書籍 書籍 クラスに関連付けて保存し、リストする方法を見ていきます。 1 1 ジャンルを保存してリストする 次のスニペットを使用して、 ジャンル ジャンル を登録できます。 1 private void addgenre(string name) { 2 //we are taking this name parameter from the input 3 progressdialog show(); 4 parseobject parseobject = new parseobject("genre"); 5 parseobject put("name", name); 6 parseobject saveinbackground(e > { 7 progressdialog dismiss(); 8 if (e == null) { 9 getgenres(); 10 inputgenre settext(""); 11 toast maketext(this, "genre saved successfully", toast length short) show(); 12 } else { 13 toast maketext(this, e getlocalizedmessage(), toast length short) show(); 14 } 15 }); 16 }1 private fun addgenre(name string) { 2 //we are taking this name parameter from the input 3 progressdialog show() 4 val parseobject = parseobject("genre") 5 parseobject put("name", name) 6 parseobject saveinbackground { 7 progressdialog dismiss() 8 if (it == null) { 9 getgenres() 10 inputgenre settext("") 11 toast maketext(this, "genre saved successfully", toast length short) show() 12 } else { 13 toast maketext(this, it localizedmessage, toast length short) show() 14 } 15 } 16 } 私たちは次のスニペットを使用して ジャンル ジャンル を登録できます。 1 private void getgenres() { 2 progressdialog show(); 3 parsequery\<parseobject> query = new parsequery<>("genre"); 4 query findinbackground((objects, e) > { 5 progressdialog dismiss(); 6 list\<parseobjectmodel> list = new arraylist<>(); 7 for (parseobject parseobject objects) { 8 list add(new parseobjectmodel(parseobject)); 9 } 10 11 genreadapter adapter = new genreadapter(list, this); 12 recyclerview\ setlayoutmanager(new linearlayoutmanager(this)); 13 recyclerview\ setadapter(adapter); 14 }); 15 }1 private fun getgenres() { 2 progressdialog show() 3 val query = parsequery\<parseobject>("genre") 4 query findinbackground { objects, e > 5 progressdialog dismiss() 6 var list mutablelist\<parseobjectmodel> = arraylist() 7 for (parseobject in objects) { 8 list add(parseobjectmodel(parseobject)) 9 } 10 val adapter = genreadapter(this, list) 11 recyclerview\ layoutmanager = linearlayoutmanager(this) 12 recyclerview\ adapter = adapter 13 } 14 } 1 2 パブリッシャーを保存してリストする 次のスニペットを使用して、 パブリッシャー パブリッシャー を登録できます。 1 private void addpublisher(string name) { 2 //we are taking this name parameter from the input 3 progressdialog show(); 4 parseobject parseobject = new parseobject("publisher"); 5 parseobject put("name", name); 6 parseobject saveinbackground(e > { 7 progressdialog dismiss(); 8 if (e == null) { 9 getpublishers(); 10 inputpublisher settext(""); 11 toast maketext(this, "publisher saved successfully", toast length short) show(); 12 } else { 13 toast maketext(this, e getlocalizedmessage(), toast length short) show(); 14 } 15 }); 16 }1 private fun addpublisher(name string) { 2 //we are taking this name parameter from the input 3 progressdialog show() 4 val parseobject = parseobject("publisher") 5 parseobject put("name", name) 6 parseobject saveinbackground { 7 progressdialog dismiss() 8 if (it == null) { 9 getpublishers() 10 inputpublisher settext("") 11 toast maketext(this, "publisher saved successfully", toast length short) show() 12 } else { 13 toast maketext(this, it localizedmessage, toast length short) show() 14 } 15 } 16 } 次のスニペットを使用して、 パブリッシャー パブリッシャー を登録できます。 1 private void getpublishers() { 2 progressdialog show(); 3 parsequery\<parseobject> query = new parsequery<>("publisher"); 4 query findinbackground((objects, e) > { 5 progressdialog dismiss(); 6 list\<parseobjectmodel> list = new arraylist<>(); 7 for (parseobject parseobject objects) { 8 list add(new parseobjectmodel(parseobject)); 9 } 10 11 publisheradapter adapter = new publisheradapter(list, this); 12 recyclerview\ setlayoutmanager(new linearlayoutmanager(this)); 13 recyclerview\ setadapter(adapter); 14 }); 15 }1 private fun getpublishers() { 2 progressdialog show() 3 val query = parsequery\<parseobject>("publisher") 4 query findinbackground { objects, e > 5 progressdialog dismiss() 6 val list arraylist\<parseobjectmodel> = arraylist() 7 for (parseobject in objects) { 8 list add(parseobjectmodel(parseobject)) 9 } 10 11 val adapter = publisheradapter(this, list) 12 recyclerview\ layoutmanager = linearlayoutmanager(this) 13 recyclerview\ adapter = adapter 14 } 15 } 1 3 著者を保存してリストする 次のスニペットを使用して、 著者 著者 を登録できます。 1 private void addauthor(string name){ 2 //we are taking this name parameter from the input 3 progressdialog show(); 4 parseobject parseobject = new parseobject("author"); 5 parseobject put("name", name); 6 parseobject saveinbackground(e > { 7 progressdialog dismiss(); 8 if (e == null) { 9 getauthors(); 10 inputauthor settext(""); 11 toast maketext(this, "author saved successfully", toast length short) show(); 12 } else { 13 toast maketext(this, e getlocalizedmessage(), toast length short) show(); 14 } 15 }); 16 }1 private fun addauthor(name string) { 2 //we are taking this name parameter from the input 3 progressdialog show() 4 val parseobject = parseobject("author") 5 parseobject put("name", name) 6 parseobject saveinbackground { 7 progressdialog dismiss() 8 if (it == null) { 9 getauthors() 10 inputauthor settext("") 11 toast maketext(this, "author saved successfully", toast length short) show() 12 } else { 13 toast maketext(this, it localizedmessage, toast length short) show() 14 } 15 } 16 } 私たちは次のスニペットを使用して 著者 著者 を登録できます。 1 private void getauthors() { 2 progressdialog show(); 3 parsequery\<parseobject> query = new parsequery<>("author"); 4 query findinbackground((objects, e) > { 5 progressdialog dismiss(); 6 list\<parseobjectmodel> list = new arraylist<>(); 7 for (parseobject parseobject objects) { 8 list add(new parseobjectmodel(parseobject)); 9 } 10 11 authoradapter adapter = new authoradapter(list, this); 12 recyclerview\ setlayoutmanager(new linearlayoutmanager(this)); 13 recyclerview\ setadapter(adapter); 14 }); 15 }1 private fun getauthors() { 2 progressdialog show() 3 val query = parsequery\<parseobject>("author") 4 query findinbackground { objects list\<parseobject>, e parseexception? > 5 progressdialog dismiss() 6 val list arraylist\<parseobjectmodel> = arraylist() 7 for (parseobject in objects) { 8 list add(parseobjectmodel(parseobject)) 9 } 10 val adapter = authoradapter(this, list) 11 recyclerview\ layoutmanager = linearlayoutmanager(this) 12 recyclerview\ adapter = adapter 13 } 14 } この部分では、 parseobjectmodel parseobjectmodel というモデルクラスを使用します。このモデルクラスには、データを読み取るための parseobject parseobject 変数があり、次のステップで本を保存するために使用する ischecked ischecked 変数があります。 ischecked ischecked 変数を使用して、選択したオブジェクトを簡単に取得できます。 こちらが私たちの parseobjectmodel parseobjectmodel モデルです。 1 public class parseobjectmodel { 2 parseobject object; 3 boolean ischecked = false; 4 5 public parseobjectmodel(parseobject object) { 6 this object = object; 7 } 8 9 public parseobject getobject() { 10 return object; 11 } 12 13 public parseobjectmodel setobject(parseobject object) { 14 this object = object; 15 return this; 16 } 17 18 public boolean ischecked() { 19 return ischecked; 20 } 21 22 public parseobjectmodel setchecked(boolean checked) { 23 ischecked = checked; 24 return this; 25 } 26 }1 class parseobjectmodel(obj parseobject) { 2 var obj parseobject? = null 3 var ischecked boolean = false 4 5 init { 6 this obj = obj 7 } 8 } 2 本オブジェクトとその関係を保存する 2 1 1\ n関係を持つ本オブジェクトを保存する この関数は新しい 本 本 をback4appデータベースに1\ n関係で作成します。 1 progressdialog show(); 2 book put("genre", genre); 3 book put("publisher", publisher); 4 book put("title", title); 5 book put("year", year); 6 book saveinbackground(e > { 7 progressdialog hide(); 8 if (e == null) { 9 toast maketext(addbookactivity this, "book saved successfully", toast length short) show(); 10 startactivity(new intent(addbookactivity this, booklistactivity class)); 11 finish(); 12 } else { 13 toast maketext(addbookactivity this, e getlocalizedmessage(), toast length short) show(); 14 } 15 });1 progressdialog show() 2 book put("genre", genre) 3 book put("publisher", publisher!!) 4 book put("title", title) 5 book put("year", year) 6 book saveinbackground { 7 progressdialog hide() 8 if (it == null) { 9 toast maketext(this, "book saved successfully", toast length short) show() 10 startactivity(intent(this\@addbookactivity, booklistactivity class java)) 11 finish() 12 } else { 13 toast maketext(this, it localizedmessage, toast length short) show() 14 } 15 } 2 2 n\ n関係を持つbookオブジェクトを保存する この関数は新しい 本 本 をback4appデータベースにn\ n関係で作成します。 著者 著者 関係については、 authorrecyclerview authorrecyclerview のアダプターで選択された著者を見つけ、 parse relation parse relation として保存します。 1 progressdialog show(); 2 book put("genre", genre); 3 book put("publisher", publisher); 4 book put("title", title); 5 book put("year", year); 6 7 //here we are setting book relation with getselecteditem function of bookauthoradapter 8 if (recyclerviewauthors getadapter() != null) { 9 relation = ((bookauthoradapter) recyclerviewauthors getadapter()) getselecteditems(book); 10 if (relation == null) { 11 toast maketext(this, "please select author/s", toast length short) show(); 12 return; 13 } 14 } else { 15 toast maketext(this, "something went wrong!!", toast length short) show(); 16 return; 17 } 18 19 book saveinbackground(e > { 20 progressdialog hide(); 21 if (e == null) { 22 toast maketext(addbookactivity this, "book saved successfully", toast length short) show(); 23 startactivity(new intent(addbookactivity this, booklistactivity class)); 24 finish(); 25 } else { 26 toast maketext(addbookactivity this, e getlocalizedmessage(), toast length short) show(); 27 } 28 }); 29 30 //this is the function for save author/s relation of book object this function in bookauthoradapter 31 public parserelation\<parseobject> getselecteditems(parseobject parseobject) { 32 parserelation\<parseobject> relation = parseobject getrelation("author relation"); 33 for (parseobjectmodel object this list) { 34 if (object ischecked()) 35 relation add(object getobject()); 36 } 37 return relation; 38 } 1 progressdialog show() 2 book put("genre", genre) 3 book put("publisher", publisher!!) 4 book put("title", title) 5 book put("year", year) 6 7 //here we are setting book relation with getselecteditem function of bookauthoradapter 8 9 if (recyclerviewauthors adapter != null) { 10 relation = (recyclerviewauthors adapter as bookauthoradapter) getselecteditems(book) 11 if (relation == null) { 12 toast maketext(this, "please select author/s", toast length short) show() 13 return 14 } 15 } else { 16 toast maketext(this, "something went wrong!!", toast length short) show() 17 return 18 } 19 20 book saveinbackground { 21 progressdialog hide() 22 if (it == null) { 23 toast maketext(this, "book saved successfully", toast length short) show() 24 startactivity(intent(this\@addbookactivity, booklistactivity class java)) 25 finish() 26 } else { 27 toast maketext(this, it localizedmessage, toast length short) show() 28 } 29 } 30 31 //this is the function for save author/s relation of book object this function in bookauthoradapter 32 33 fun getselecteditems(parseobject parseobject) parserelation\<parseobject>? { 34 var relation\ parserelation\<parseobject>? = parseobject getrelation("author relation") 35 for (obj in this list) { 36 if (obj ischecked) 37 relation? add(obj obj) 38 } 39 return relation 40 } 3 書籍の詳細を関係と共にクエリする これらの機能を使用して、私たちは 本 本 をその 出版社 出版社 に従ってリストします。まず、publisherクラスにクエリを投げます。 1 progressdialog show(); 2 parsequery\<parseobject> query = new parsequery<>("publisher"); 3 query findinbackground((objects, e) > { 4 progressdialog hide(); 5 if (e == null) { 6 booklistadapter adapter = new booklistadapter(objects, this); 7 recyclerview\ setlayoutmanager(new linearlayoutmanager(this)); 8 recyclerview\ setadapter(adapter); 9 } else { 10 toast maketext(this, e getlocalizedmessage(), toast length short) show(); 11 } 12 });1 progressdialog show() 2 val query = parsequery\<parseobject>("publisher") 3 query findinbackground { objects list\<parseobject>?, e parseexception? > 4 progressdialog hide() 5 if (e == null) { 6 val adapter = booklistadapter(this, objects!!) 7 recyclerview\ layoutmanager = linearlayoutmanager(this) 8 recyclerview\ adapter = adapter 9 } else { 10 toast maketext(this, e localizedmessage, toast length short) show() 11 } 12 } そして、私たちは各 本 本 が関連している 出版社 出版社 のリストを取得するためにクエリを実行します。 1 parseobject object = list get(position); 2 holder title settext(object getstring("name")); 3 parsequery\<parseobject> query = new parsequery<>("book"); 4 query whereequalto("publisher", object); 5 query findinbackground((objects, e) > { 6 if (e == null) { 7 booksadapter adapter = new booksadapter(objects, context); 8 holder books setlayoutmanager(new linearlayoutmanager(context)); 9 holder books setadapter(adapter); 10 } else { 11 toast maketext(context, e getlocalizedmessage(), toast length short) show(); 12 } 13 });1 val `object` = list\[position] 2 holder title text = `object` getstring("name") 3 val query = parsequery\<parseobject>("book") 4 query whereequalto("publisher", `object`) 5 query findinbackground { objects list\<parseobject>?, e parseexception? > 6 if (e == null) { 7 val adapter = booksadapter(context, objects!!) 8 holder books layoutmanager = linearlayoutmanager(context) 9 holder books adapter = adapter 10 } else { 11 toast maketext(context, e localizedmessage, toast length short) show() 12 } 13 } 今、私たちが任意の 本 本 オブジェクトをクリックすると、私たちはこの 本 本 のオブジェクトidを、その 本 本 の詳細を表示するページへのインテントと共に送信します。そして、私たちはそのページでこのオブジェクトidを使用して 本 本 のすべての詳細をデータベースから取得します。 1 private void getbookwithdetails() { 2 progressdialog show(); 3 parsequery\<parseobject> query = new parsequery<>("book"); 4 query getinbackground(getintent() getstringextra("objectid"), (object, e) > { 5 if (e == null) { 6 booktitle settext("title " +object getstring("title")); 7 bookyear settext("year " +object getstring("year")); 8 try { 9 bookgenre settext("genre " +object getparseobject("genre") fetchifneeded() getstring("name")); 10 } catch (parseexception parseexception) { 11 parseexception printstacktrace(); 12 } 13 try { 14 bookpublisher settext("publisher " + object getparseobject("publisher") fetchifneeded() getstring("name")); 15 } catch (parseexception parseexception) { 16 parseexception printstacktrace(); 17 } 18 19 object getrelation("author relation") getquery() findinbackground((objects, e1) > { 20 progressdialog hide(); 21 if (e1 == null) { 22 bookdetailauthoradapter adapter = new bookdetailauthoradapter(objects, this); 23 authorrecyclerview\ setlayoutmanager(new linearlayoutmanager(this)); 24 authorrecyclerview\ setadapter(adapter); 25 } else { 26 toast maketext(this, e getlocalizedmessage(), toast length short) show(); 27 } 28 }); 29 } else { 30 progressdialog hide(); 31 toast maketext(this, e getlocalizedmessage(), toast length short) show(); 32 } 33 }); 34 }1 private fun getbookwithdetails() { 2 progressdialog show() 3 val query = parsequery\<parseobject>("book") 4 5 query getinbackground(intent getstringextra("objectid")) { `object`, e > 6 if (e == null) { 7 booktitle text = "title " + `object` getstring("title") 8 bookyear text = "year " + `object` getstring("year") 9 try { 10 bookgenre text = "genre " + `object` getparseobject("genre")? fetchifneeded\<parseobject>()? getstring("name") 11 } catch (parseexception parseexception) { 12 parseexception printstacktrace() 13 } 14 try { 15 bookpublisher text = 16 "publisher " + `object` getparseobject("publisher")? fetchifneeded\<parseobject>()? getstring("name") 17 } catch (parseexception parseexception) { 18 parseexception printstacktrace() 19 } 20 21 `object` getrelation\<parseobject>("author relation") query findinbackground { objects, e1 > 22 progressdialog hide() 23 if (e1 == null) { 24 val adapter = bookdetailauthoradapter(this, objects) 25 authorrecyclerview\ layoutmanager = linearlayoutmanager(this) 26 authorrecyclerview\ adapter = adapter 27 } else { 28 toast maketext(this, e1 localizedmessage, toast length short) show() 29 } 30 } 31 } else { 32 progressdialog hide() 33 toast maketext(this, e localizedmessage, toast length short) show() 34 } 35 } 36 } 完了しました! この時点で、私たちは parse relationships parse relationships を学びました android android