플러터 CRUD 기능 구현(Get_it, Drift, SQLift) – 일기장 앱 만들기 (7)

플러터(Flutter) 앱에서 쉽게 사용할 수 있는 의존성 주입 패키지 Get_it는 코드의 결합도를 낮추고 유지보수를 쉽게 할 수 있어 개발자들에게 편의성을 제공한다. 지난 글에 이어서 플러터 CRUD 기능 중 Delete, Update을 구현하는 방법에 대해 작성한다.

CRUD 기능

CRUD(Create, Read, Update, Delete)중에 지난 포스트에서 Create, Read에 대해 작성했다면 이번 글에서는 Delete, Update을 위한 기능을 구현한다.

삭제 기능 구현

DB에 저장된 데이터를 삭제할 수 있도록 우측에 삭제 버튼을 추가하였다. 삭제 버튼을 클릭하면 삭제 여부를 확인하는 대화상자가 열리고 확인을 하면 홈 화면으로 돌아간다.

해당 버튼이 눌렀을때 _showConfirmationDialog 함수를 호출하도록 구성하였다.

appBar: AppBar(
  actions: [
    IconButton(
      icon: Icon(Icons.delete),
      onPressed: () {
        _showConfirmationDialog(context, date);
        print('Delete button pressed');
      },
    ),
  ],
),

_showConfirmationDialog 함수는 await 키워드를 사용하여 해당 함수가 Future의 완료를 기다리고 그 결과를 반환하는 동안 다른 작업을 수행할 수 있도록 한다. GetIt.I().removeSchedule(date);으로 날짜별 데이터를 삭제한 후 Navigator.of(context).pop();을 사용하여 이전 화면으로 돌아간다.

Future<void> _showConfirmationDialog(
    BuildContext context, DateTime date) async {
  await showDialog<void>(
    context: context,
    builder: (BuildContext context) {
      return AlertDialog(
        // 대화상자 제목
        title: Text('삭제 확인'),

        // 대화상자 내용
        content: Text('일정을 삭제하시겠습니까?'),

        // 대화상자 액션 버튼들
        actions: [
          // '취소' 버튼
          TextButton(
            onPressed: () {
              // 취소 버튼 클릭 시, 알림창 닫기만 수행
              Navigator.of(context).pop();
            },
            child: Text('취소'),
          ),

          // '확인' 버튼
          TextButton(
            onPressed: () {
              // 확인 버튼 클릭 시, 일정 삭제 후 알림창 닫기와 뒤로 가기 수행
              GetIt.I<LocalDatabase>().removeSchedule(date);
              Navigator.of(context).pop();
              Navigator.of(context).pop();
            },
            child: Text('확인'),
          ),
        ],
      );
    },
  );
}

업데이트 기능 구현

save 버튼을 눌렀을 때 이미 데이터가 존재하는 경우는 업데이트를 수행해야 된다. 업데이트를 하는 경우는 아래 코드처럼 GetIt.I().updateSchedule을 사용하여 쉽게 구현할 수 있다.

await GetIt.I<LocalDatabase>().updateSchedule(
  DiaryDbCompanion(
    content: Value(contentController.text),
    date: Value(date),
    create: Value(DateTime.now()),
  ),
);

하지만 현업에 있으면서 나의 경험으로는 데이터베이스를 삭제하거나 업데이트하지 않았다. 그 이유는 데이터를 삭제하거나 업데이트하는 것은 데이터의 무결성을 해칠 수 있다. 특히 중요한 정보에서 데이터 일괄성과 정확성을 유지하기 위해 삭제하지 않고 데이터를 보존하는 것이 중요하다. 그 외의 이점은 데이터 변경 이력을 효과적으로 관리할 수 있으며 데이터 충돌이나 성능 손실을 막을 수 있다.

그렇기 때문에 Save 버튼 눌렀을 때 createSchedule기능만 사용하고 존재하는 최근값만 보여주게 되면 사용자에게는 데이터가 업데이트하는 것으로 보인다.

void _saveDiaryEntry(DateTime date) async {
  try {
    // 새로운 값 생성
    await GetIt.I<LocalDatabase>().createSchedule(
      DiaryDbCompanion(
        content: Value(contentController.text),  // TextFormField에서 입력한 텍스트 값을 사용
        date: Value(date),
        create: Value(DateTime.now()))
      ),
    );

    // 저장 성공 시 메시지 출력 (선택적)
    debugPrint('Diary entry saved successfully.');
  } catch (e) {
    // 저장 실패 시 에러 메시지 출력 (선택적)
    debugPrint('Failed to save diary entry: $e');
  }
}

입력폼의 코드를 다시 한번 확인하면 controller에서 getControllerText(diaryDataList.last.content) 생성일자로 정렬한 데이터의 마지막 인덱스를 전달한다.

// 생성날짜로 정렬
diaryDataList.sort((a, b) => a.create.compareTo(b.create));
...
return TextFormField(
  controller: getControllerText(diaryDataList.last.content),
  keyboardType: TextInputType.multiline,
  maxLines: 25,
  decoration: InputDecoration(
    hintText: '입력해주세요.',
    // Display hintText only if there are no entries
  ),
);
...

마무리

지금까지 Get_it, Drift을 이용하여 Flutter로 일기장 앱을 구현해보았습니다. 다음 포스트에서는 실시간 데이터베이스를 이용하기 위해 앱어플리케이션 개발 플랫폼인 파이어베이스에 대해서 작성하려고 합니다. 읽어주셔서 감사합니다.

전체 코드는 링크에서 확인할 수 있습니다.

Leave a Comment