Android
Data objects
안드로이드용 Parse에서 1:N 및 N:N 관계 생성 및 조회
19 분
안드로이드의 관계 소개 parse를 사용하면 데이터 객체를 저장하고 그들 간의 관계를 설정할 수 있습니다 이러한 동작을 모델링하기 위해, 다른 parseobject parseobject 의 값으로 사용될 수 있습니다 내부적으로 parse 프레임워크는 일관성을 유지하기 위해 참조된 객체를 한 곳에만 저장합니다 이는 복잡한 쿼리를 구축하고 실행할 때 추가적인 힘을 줄 수 있습니다 세 가지 주요 관계 유형이 있습니다 일대일 일대일 , 두 객체 간의 직접적인 관계를 설정합니다; 일대다 일대다 , 하나의 객체가 여러 다른 객체와 관련될 수 있습니다; 다대다 다대다 , 여러 객체 간에 복잡한 관계를 생성할 수 있습니다 parse에서 일대다 일대다 관계를 생성하는 두 가지 방법이 있습니다 첫 번째는 포인터 포인터 를 사용하는 것입니다 자식 클래스, 자식 클래스, 이는 생성 및 쿼리 시간에서 가장 빠릅니다 두 번째는 배열 배열 을 사용하는 것입니다 포인터 포인터 를 부모 클래스에서 사용하는데, 이는 크기에 따라 느린 쿼리 시간으로 이어질 수 있습니다 이러한 성능 문제로 인해 우리는 포인터 예제만 사용할 것입니다 parse에서 다대다 다대다 관계를 생성하는 세 가지 방법이 있습니다 첫 번째는 parse 관계 관계 , 이는 생성 및 쿼리 시간에서 가장 빠릅니다 우리는 이 가이드에서 이를 사용할 것입니다 두 번째는 배열 배열 을 사용하는 것입니다 포인터 포인터 를 사용하는데, 이는 크기에 따라 느린 쿼리 시간으로 이어질 수 있습니다 세 번째는 조인 테이블 조인 테이블 을 사용하는 것입니다 이는 고전 데이터베이스의 아이디어에서 비롯됩니다 다대다 관계가 있을 때, 우리는 양쪽의 모든 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 저장소에서 확인하세요 코틀린 예제 저장소 자바 예제 저장소 목표 우리의 목표는 실용적인 도서 앱을 만들어 parse 관계를 이해하는 것입니다 우리가 달성할 목표의 미리보기입니다 전제 조건 이 튜토리얼을 완료하기 위해 우리는 다음이 필요합니다 안드로이드 스튜디오 back4app에서 생성된 앱 참고 새 파스 앱 튜토리얼 을 따라 back4app에서 파스 앱을 만드는 방법을 배우세요 back4app에 연결된 안드로이드 앱 참고 파스 sdk 설치 튜토리얼 을 따라 back4app에 연결된 안드로이드 스튜디오 프로젝트를 만드세요 안드로이드 4 1 (젤리빈) 이상에서 실행되는 장치 (또는 가상 장치 ) 책 앱 이해하기 당신이 사용할 주요 객체 클래스는 book book 클래스이며, 각 책 항목을 등록에 저장합니다 또한, 다음은 다른 세 개의 객체 클래스입니다 출판사 출판사 책 출판사 이름, 일대다 일대다 관계는 book book 장르 장르 책 장르, 일대다 일대다 관계는 book book 이 예제에서는 책이 하나의 장르만 가질 수 있다고 가정합니다; 저자 저자 책 저자, 다대다 다대다 관계는 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 를(을) 앱에 초기화하는 방법을 모른다면 또는 위에 공유한 깃허브 링크에서 프로젝트를 다운로드하고 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 관계를 가진 책 객체 저장하기 이 기능은 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 관계 parse 관계 에 대해 배웠습니다 안드로이드 안드로이드