---
title: Flutter에서 Parse로 1대다 관계 구현 및 쿼리
slug: docs-kr/flutter/parse-sdk/data-objects/flutter-one-to-many-relationship
description: Parse를 사용한 Flutter 개발에서 1대다 데이터 객체 관계 구현 및 효율적 쿼리 방법 가이드.
image: https://www.back4app.com/images/logo-social.png
createdAt: 2024-03-15T15:14:39.658Z
---

# 플러터의 일대다 관계


소개
--


Parse를 사용하면 데이터 객체를 저장하고 그들 간의 관계를 설정할 수 있습니다. 이러한 동작을 모델링하기 위해, 다른 <font color="#2166ae">`ParseObject`</font>의 값으로 사용될 수 있습니다. 내부적으로 Parse 프레임워크는 참조된 객체를 한 곳에 저장하여 일관성을 유지합니다. 이는 복잡한 쿼리를 구축하고 실행할 때 추가적인 힘을 줄 수 있습니다. 세 가지 주요 관계 유형이 있습니다:

-  <font color="#2166ae">`일대일`</font>, 두 객체 간의 직접적인 관계를 설정하며 오직 그들만의 관계입니다;
-  <font color="#2166ae">`일대다`</font>, 하나의 객체가 여러 다른 객체와 관련될 수 있습니다;
-  <font color="#2166ae">`다대다`</font>, 여러 객체 간에 복잡한 관계를 생성할 수 있습니다.

이 가이드에서는 <font color="#2166ae">`일대다`</font> 관계가 어떻게 작동하는지 실용적인 앱 예제를 사용하여 자세히 설명합니다. Parse에서 <font color="#2166ae">`일대다`</font> 관계를 생성하는 두 가지 방법이 있습니다:

- 첫 번째 방법은 <font color="#2166ae">`포인터`</font>를 사용하는 것입니다. <font color="#2166ae">`자식 클래스`</font>, 이는 생성 및 쿼리 시간에서 가장 빠릅니다.
- 두 번째 방법은 <font color="#2166ae">`배열`</font>을 사용하는 것입니다. <font color="#2166ae">`포인터`</font>를 부모 클래스에서 사용하면 크기에 따라 쿼리 시간이 느려질 수 있습니다. 이러한 성능 문제로 인해 우리는 포인터 예제만 사용할 것입니다.

Flutter 도서 등록 앱을 구현하고 Parse <font color="#2166ae">`포인터`</font>를 사용하여 관련 객체를 생성하고 쿼리할 것입니다.

:::hint{type="info"}
관계는 <font color="#2166ae">`일대일`</font>이 일반적이지 않으며, 우리는 가이드에서 다루지 않을 것입니다. 예를 들어, 사용자 클래스와 다른 클래스 간의 관계는 민감한 사용자 데이터를 포함할 수 있습니다. [보안상의 이유로](https://blog.back4app.com/parse-server-best-practices/) (*1.4. 사용자가 다른 사람의 민감한 데이터에 접근하지 못하도록 하세요*).
:::

::embed[]{url="https://www.youtube.com/embed/b6fdFD0hlJo"}

## 전제 조건

:::hint{type="info"}
- [Flutter 버전 2.2.x 이상](https://flutter.dev/docs/get-started/install)
- [Android Studio ](https://developer.android.com/studio) 또는 [VS Code 설치](https://code.visualstudio.com/) ( [플러그인](https://docs.flutter.dev/get-started/editor) Dart 및 Flutter 포함)
- Back4App에서 [생성된](https://www.back4app.com/docs/get-started/new-parse-app) 앱:
  - **참고:&#x20;**&#x20;[새 Parse 앱 튜토리얼](https://www.back4app.com/docs/get-started/new-parse-app)을 따라 Back4App에서 Parse 앱을 만드는 방법을 배우세요.
- Back4app에 연결된 Flutter 앱.
  - **참고:&#x20;**&#x20;[Flutter 프로젝트에 Parse SDK 설치](https://www.back4app.com/docs/flutter/parse-sdk/parse-flutter-sdk)을 따라 Back4App에 연결된 Flutter 프로젝트를 만드세요.
- Android 또는 iOS를 실행하는 장치(또는 가상 장치).
:::

## 책 앱 이해하기


당신이 사용할 주요 객체 클래스는 <font color="#2166ae">`책`</font> 클래스이며, 각 책 항목을 등록에 저장합니다. 또한, 다음은 다른 세 개의 객체 클래스입니다:

- <font color="#2166ae">`출판사`</font>: 책 출판사 이름, <font color="#2166ae">`책`</font>과의 일대다 관계;
- <font color="#2166ae">`장르`</font>: 책 장르, <font color="#2166ae">`책`</font>,과의 일대다 관계. 이 예제에서는 책이 하나의 장르만 가질 수 있다고 가정합니다;
- <font color="#2166ae">`저자`</font>: 책 저자, <font color="#2166ae">`책`</font>,과의 다대다 관계, 책은 여러 저자를 가질 수 있고 저자도 여러 책을 가질 수 있습니다;

이 데이터 모델의 시각적 표현:

![](https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/A3OFhXHEJEAvPvi6DVVuq_image.png)

각 객체 클래스 (<font color="#2166ae">`출판사`</font>, <font color="#2166ae">`장르`</font>)는 문자열 유형의 <font color="#2166ae">`이름`</font> 속성만 가지고 있으며 <font color="#2166ae">`책`</font>은 <font color="#2166ae">`제목`</font>과 <font color="#2166ae">`연도`</font>, 추가적인 관계 속성과는 별개입니다. 이전 가이드에서는 <font color="#2166ae">`ParseObject`</font>를 저장하고 읽는 방법을 이미 보았으므로, 이번 가이드에서는 <font color="#2166ae">`장르`</font>와 <font color="#2166ae">`출판사`</font> 객체를 저장하고 읽는 방법은 다루지 않겠습니다.

책 앱에서 다음 화면을 찾을 수 있습니다:

- **장르 등록 및 목록**
- **출판사 등록 및 목록**
- **책 등록**
- **출판사 및 책 목록**
- **책 세부정보**

이 가이드의 주요 초점이 관계를 사용하여 Flutter와 Parse를 사용하는 것이기 때문에 Flutter 애플리케이션 코드를 설명하지 않겠습니다.

## 1 - 도서 앱 템플릿 만들기

먼저 도서 앱 프로젝트 템플릿을 실행해 보겠습니다. 이전 가이드에서 **Flutter plugin for Parse Server**를 열어보세요. [도서 Flutter 앱](https://github.com/templates-back4app/flutter_associations) 리포지토리도 복제하여 프로젝트를 실행할 수 있습니다. [main.dart](https://github.com/templates-back4app/flutter_associations/blob/master/lib/main.dart) 파일을 복사하고 이전 가이드의 현재 코드를 교체하세요.

**참고:**
함수 <font color="#2166ae">`debug`</font> 매개변수가 <font color="#2166ae">`Parse().initialize`</font>에서 <font color="#2166ae">`true`</font>로 설정되면, 콘솔에 Parse API 호출을 표시할 수 있습니다. 이 설정은 코드 디버깅에 도움이 될 수 있습니다. 릴리스 버전에서는 디버그를 비활성화하는 것이 좋습니다.

### 2단계 - 템플릿을 Back4app 프로젝트에 연결하기

앱 대시보드에서 [Back4App 대시보드->앱 설정->보안 및 키](https://www.back4app.com/docs/parse-dashboard/app-settings). Back4app에서 프로젝트의 ApplicationId와 ClientKey 값을 사용하여 <font color="#2166ae">`main.dart`</font>의 코드를 업데이트하세요.

- **keyApplicationId = 앱 ID**
- **keyClientKey = 클라이언트 키**

프로젝트를 실행하면 앱이 이미지와 같이 로드됩니다.

::Image[]{src="https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/yMFpRGpZJLsxJjtLPBDdk_image.png" size="30" width="323" height="627" position="center" showCaption="false"}

&#x20;<font color="#2166ae">`장르 추가`</font>를 클릭하여 책 등록에 사용될 <font color="#2166ae">`장르`</font> 목록을 등록하고 확인하세요.

::Image[]{src="https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/AXMne48nSmI_omEvIIFLT_image.png" size="30" width="323" height="627" position="center" showCaption="false"}

클릭하여 <font color="#2166ae">`퍼블리셔 추가`</font>를 등록하고 <font color="#2166ae">`퍼블리셔`</font> 목록을 확인하세요.

::Image[]{src="https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/s566XXvwuWEOBBdq6LHC5_image.png" size="30" width="323" height="627" position="center" showCaption="false"}

클릭하여 <font color="#2166ae">`책 추가`</font>를 클릭하여 새로운 <font color="#2166ae">`책`</font>을 등록하세요. <font color="#2166ae">`장르`</font> 및 <font color="#2166ae">`퍼블리셔`</font>와의 관계를 사용하세요.

::Image[]{src="https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/jVUGzMZD8IIhrw57GNnRc_image.png" size="30" width="328" height="637" position="center" showCaption="false"}

클릭하여 <font color="#2166ae">`퍼블리셔/책 목록`</font>을 클릭하여 <font color="#2166ae">`퍼블리셔`</font> 및 <font color="#2166ae">`책`</font> 목록을 확인하세요.

::Image[]{src="https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/EGNDJ3ZrgC9_P-vPrSZ_a_image.png" size="30" width="323" height="627" position="center" showCaption="false"}

## 3 - 책 객체와 그 관계 저장하기

이 기능은 Back4app 데이터베이스에 관계와 함께 새로운 책을 생성합니다. <font color="#2166ae">`doSaveBook`</font> 함수를 <font color="#2166ae">`main.dart`</font> 파일에서 검색하고, <font color="#2166ae">`Future<void> doSaveBook()`</font> 함수 안에 아래 코드를 삽입하세요:

```dart
1       final book = ParseObject('Book')
2         ..set('title', controllerTitle.text.trim())
3         ..set('year', int.parse(controllerYear.text.trim()))
4         //the objectId will be converted to a Pointer on the save() method
5         ..set('genre', ParseObject('Genre')..objectId = genre.objectId)
6         //you can also convert to a Pointer object before the saving using the .toPointer() method
7         ..set(
8             'publisher',
9             (ParseObject('Publisher')..objectId = publisher.objectId)
10                .toPointer());
11
12      await book.save();
```

이 기능을 구축하려면 다음 단계를 따르세요:

- 1\. Parse <font color="#2166ae">`Book`</font> 클래스를 다음 명령어로 새 인스턴스를 생성합니다. <font color="#2166ae">`ParseObject('Book')`</font>.
- 2\. <font color="#2166ae">`set`</font> 함수를 사용하여 이 객체의 필드를 설정합니다.
  - 2.1.<font color="#2166ae">`title`</font>은 텍스트 컨트롤러에서 값을 받는 텍스트 속성입니다.
  - 2.2.<font color="#2166ae">`genre`</font>는 <font color="#2166ae">`ParseObject`</font>를 정의하여 값을 받습니다. <font color="#2166ae">`objectId`</font>는 선택한 <font color="#2166ae">`Genre`</font>. (*Parse는 저장 시 포인터로 변환됩니다.*)
  - 2.3.<font color="#2166ae">`publisher`</font>는 <font color="#2166ae">`ParseObject`</font>를 정의하여 값을 받습니다. <font color="#2166ae">`objectId`</font>는 선택한 <font color="#2166ae">`Publisher`</font>. (*Parse에 대해 포인터로 저장하고 싶다고 지정할 수 있습니다.*<font color="#2166ae">`pointer`</font>*를 사용하여&#x20;*<font color="#2166ae">`toPointer()`</font>*&#x20;메서드*)
- 3\. <font color="#2166ae">`save`</font> 함수를 호출하여 <font color="#2166ae">`ParseObject`</font>, 이는 효과적으로 객체를 Back4app 대시보드의 데이터베이스에 등록합니다.

앱을 실행하고 새로운 기능을 테스트하세요.

- 버튼을 클릭하세요 <font color="#2166ae">`책 추가`</font>.
- 책 정보를 입력하세요.

앱은 저자(s)를 선택해야 하지만, 그에 대한 코드는 다음 가이드에서만 다룰 것입니다.

- 클릭하세요 <font color="#2166ae">`책 저장`</font> 버튼



::Image[]{src="https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/cssL-jdLG4ecfman8hIGp_image.png" size="30" width="323" height="627" position="center" showCaption="false"}

새 객체가 관계와 함께 데이터베이스에 저장되었는지 확인하려면 <font color="#2166ae">`Back4app 대시보드`</font>에 접근하고 <font color="#2166ae">`Book`</font> 클래스를 접근하세요.

![](https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/SEpUCYQHevWFwhR33NxCp_image.png)

대시보드를 사용하여 Book 클래스를 접근하면 객체 포인터 값을 클릭할 수 있으며 참조된 객체로 리디렉션됩니다. 이는 무해한 기능처럼 보일 수 있지만, 수동으로 검색하는 것보다 디버깅 및 오류 추적을 훨씬 더 빠르게 만듭니다.

## 4 - 책 목록 및 관련 객체 쿼리하기

이 함수는 퍼블리셔와의 관계를 사용하여 Back4app 데이터베이스에서 책을 쿼리합니다. 퍼블리셔를 통해 우리는 책 목록을 가져올 것입니다.

다음 함수 <font color="#2166ae">`getBookList`</font>를 파일 <font color="#2166ae">`main.dart`</font>, 그 다음 아래 코드를 <font color="#2166ae">`Future<List<ParseObject>> getBookList(String publisherId)`</font> 함수 안에 교체하세요:

```dart
1       QueryBuilder<ParseObject> queryBook =
2           QueryBuilder<ParseObject>(ParseObject('Book'))
3             ..whereEqualTo('publisher',
4                 (ParseObject('Publisher')..objectId = publisherId).toPointer())
5             ..orderByAscending('title');
6       final ParseResponse apiResponse = await queryBook.query();
7   
8       if (apiResponse.success && apiResponse.results != null) {
9         return apiResponse.results;
10      } else {
11        return [];
12      }
```

이 기능을 만들려면 다음 단계를 따르세요:

1. &#x20;<font color="#2166ae">`ParseQuery`</font> 객체를 생성하여 <font color="#2166ae">`Book`</font> 클래스에 대한 조건을 쿼리에 삽입하여 <font color="#2166ae">`Books`</font>를 검색합니다. <font color="#2166ae">`publisher`</font> 필드가 <font color="#2166ae">`pointer`</font>인 <font color="#2166ae">`Publisher ParseObject`</font>와 같도록 합니다.
2. 결과를 오름차순으로 정렬합니다. <font color="#2166ae">`name`</font> 순서로.
3. 쿼리의 검색 메서드를 사용하여 <font color="#2166ae">`query()`</font> 메서드를 호출합니다.
4. 작업이 성공하면 <font color="#2166ae">`Book`</font>의 객체가 반환됩니다.

앱을 실행하고 새로운 쿼리를 테스트하세요. 먼저 <font color="#2166ae">`List Publisher/Book`</font> 버튼을 클릭하세요.

::Image[]{src="https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/hUJS9Me_FZYq1DeuzH22Z_image.png" size="30" width="327" height="634" position="center" showCaption="false"}

## 완료되었습니다!

이 시점에서, 당신은 Parse에서 <font color="#2166ae">`Flutter`</font>에서 일대다 관계를 생성하고 쿼리하는 방법을 배웠습니다. 다음 가이드에서는 다대다 관계를 만드는 방법과 관련된 객체에서 데이터를 반환하는 쿼리를 수행하는 방법을 보여드리겠습니다.
