애플리케이션을 개발하다 보면 프로젝트의 요구 사항이 발전하는 것은 지극히 정상적인 일입니다. 기능을 추가하다 보면 다음과 같은 사실을 깨닫게 될 것입니다. 룸 엔티티 클래스 그리고 해당 테이블들도 새로운 요구사항에 맞게 변경되어야 합니다. 여기서 가장 큰 과제는 앱이 업데이트되고 데이터베이스 스키마가 변경될 때 사용자의 데이터가 손실되지 않도록 하는 것입니다.
이 문제를 해결하기 위해 Room은 가장 간단한 방식부터 더욱 정교한 방식까지 다양한 옵션을 제공합니다. 변경 사항이 단순한 열 추가인지 아니면 전체적인 구조 개편인지에 따라 다음 옵션 중에서 선택할 수 있습니다. 자동 또는 수동 마이그레이션전환이 원활하게 이루어지고 애플리케이션이 예기치 않게 종료되지 않도록 항상 보장합니다.
가장 빠른 방법: 자동 마이그레이션
Room은 2.4.0-alpha01 버전부터 자동 마이그레이션 기능을 제공하여 사용자의 편의성을 높여줍니다. 이 기능은 프레임워크가 이전 버전과 새 버전 간의 차이점을 분석하고 마이그레이션 계획을 자동으로 생성해 줍니다. 활성화하려면 어노테이션을 추가하기만 하면 됩니다. @자동이전 @Database 데코레이터의 autoMigrations 속성 내에 있습니다.
참고로, 중요한 세부 사항이 있습니다. 이것이 제대로 작동하려면, exportSchema는 true로 설정해야 합니다.스키마를 내보내지 않았거나 새 버전 번호로 데이터베이스를 컴파일하지 않은 경우 Room은 변경 사항을 인식하지 못하고 마이그레이션이 심각하게 실패합니다.
복잡한 사례 자동 처리
Room은 때때로 테이블을 삭제하거나 열 이름을 변경하는 것과 같이 모호한 변경 사항을 감지하는 데 어려움을 겪습니다. 이러한 경우 컴파일러는 오류를 발생시키고 특정 로직을 구현하도록 요청합니다. 자동 마이그레이션 사양이 정적 클래스는 Room이 길을 잃지 않도록 필요한 추가 정보를 제공하는 곳입니다.
이 사양 내에서는 다음과 같은 어노테이션을 사용할 수 있습니다. @RenameTable 시스템을 안내하기 위해서입니다. 또한 자동 마이그레이션이 완료된 후 추가 코드를 실행해야 하는 경우 다음 방법을 사용할 수 있습니다. onPostMigrate()이는 최종 데이터 조정을 하기에 이상적입니다.
완벽한 제어: 수동 마이그레이션
자동화로는 부족한 경우가 있는데, 예를 들어 테이블의 데이터를 두 개의 별개 엔티티로 분할해야 하는 경우가 그렇습니다. 이때 수동 마이그레이션이 필요한데, 이는 특정 클래스를 상속받는 클래스를 생성하는 방식으로 이루어집니다. 이주 그리고 migrate() 메서드를 재정의하는 부분입니다.
이 방법에서는 SQL 문을 직접 실행할 수 있는 SupportSQLiteDatabase 객체를 사용합니다. 예를 들어 열을 추가하려면 다음과 같이 사용합니다. ALTER TABLE데이터베이스 빌더에 이러한 경로를 등록할 때는 반드시 해당 메서드를 사용해야 합니다. addMigrations().
황금 팁: SQL 마이그레이션 쿼리 내에서 Kotlin 상수를 사용하지 마세요. 완전한 SQL 쿼리이렇게 하면 향후 상수 값을 변경하더라도 이전 마이그레이션에서 원래 값을 필요로 하는 경우 발생할 수 있는 치명적인 오류를 방지할 수 있습니다.
고급 전략 및 오류 관리
마이그레이션 경로를 정의할 수 없는 상황이고 데이터가 삭제되더라도 상관없다면(캐시 데이터일 가능성이 높기 때문), 다음 방법을 사용할 수 있습니다. fallbackToDestructiveMigration()이로 인해 Room은 모든 항목을 삭제하고 테이블을 처음부터 다시 생성하여 앱이 IllegalStateException 오류로 인해 충돌하는 것을 방지합니다.
보다 세밀한 제어를 위해서는 다음과 같은 대안이 있습니다. fallbackToDestructiveMigrationFrom()이는 사용자가 매우 특정한 버전에서 넘어온 경우에만 데이터를 삭제하는 방식입니다. fallbackToDestructiveMigrationOnDowngrade()이 기능은 사용자가 새 버전 위에 이전 버전의 앱을 설치했을 때 유용합니다.
사전 패키지 데이터베이스
때때로 앱에 데이터가 미리 설치되어 있기를 원할 때가 있습니다. Room을 사용하면 이를 할 수 있습니다. createFromAsset() o createFromFile()흥미로운 점은 이것이 파괴적 마이그레이션과 어떻게 상호 작용하는지입니다. 대상 버전과 일치하는 미리 패키징된 파일이 있는 경우 Room은 파괴적 정리 작업을 수행한 후 해당 파일을 사용하여 데이터베이스를 채웁니다.
NOT NULL을 이름 변경하고 처리하는 기술
SQLite에서 열 이름을 바꾸는 것은 특히 API 29 이전 버전에서는 골칫거리일 수 있습니다. 여기서 핵심적인 요령은 패턴을 사용하는 것입니다. 생성-복사-삭제올바른 이름으로 새 테이블을 생성하고, INSERT INTO … SELECT 문을 사용하여 데이터를 입력한 다음, 마지막으로 DROP TABLE 문으로 기존 테이블을 삭제합니다.
또 다른 중요한 시나리오는 열을 추가하는 것입니다. 기본값이 없는 NOT NULL 이미 레코드가 있는 테이블에서 데이터를 이동하는 것은 SQLite에서 직접 지원하지 않으므로, 임시 테이블을 생성하고 임시 기본값을 설정한 후 데이터를 이동하고 원본 테이블을 삭제한 다음 임시 테이블의 이름을 최종 테이블 이름으로 변경해야 합니다.
안정성 확보: 테스트 및 회로도
테스트 없이 프로덕션 환경으로 마이그레이션을 시작하지 마세요. Room은 테스트 도구를 제공합니다. 룸 테스트 그리고 MigrationTestHelper 클래스가 있습니다. 이 클래스를 사용하면 이전 버전에서 데이터베이스를 생성하고 실제 데이터를 삽입한 다음 실행할 수 있습니다. runMigrationsAndValidate() 최종 계획이 예상대로인지, 그리고 데이터가 여전히 존재하는지 확인하기 위해서입니다.
이 모든 것이 실현 가능하려면 스키마의 JSON 파일을 관리하는 것이 필수적입니다. 구성하려면 룸.스키마위치 Gradle 파일에서 Room은 버전 기록을 생성합니다. 이 파일들은 절대적인 진실입니다. createSql JSON 데이터는 오류를 방지하기 위해 수동 마이그레이션 시 그대로 복제해야 하는 데이터입니다.
순수 SQLite에서 Room으로의 전환
기존 방식대로 SQLite를 사용하다가 Room으로 전환하는 것은 매우 유익합니다. 전환 과정은 모델을 Room으로 변환하는 것을 포함합니다. @실재수동 쿼리를 대체할 DAO를 정의하고 RoomDatabase를 확장하는 클래스를 생성하세요. Room이 제어권을 가져올 때 기존 데이터를 삭제하지 않도록 데이터베이스 버전을 증가시키고 마이그레이션 경로를 정의하는 것이 중요합니다. 마이그레이션 경로가 비어 있더라도 마찬가지입니다.
JSON 내보내기 및 정확한 SQL 작성부터 계측 테스트를 통한 유효성 검사에 이르기까지 스키마 수명 주기를 완벽하게 이해하면 애플리케이션이 사용자 경험을 저해하거나 기기에서 중요한 정보를 잃을 염려 없이 발전할 수 있습니다. 더 많은 사람들이 주제에 대해 알 수 있도록 이 정보를 공유하세요.