24.01.22 SharedPreferences, Room

KSang·2024년 1월 24일
0

TIL

목록 보기
37/101

Data

SharedPreferences

  • XML 포맷의 텍스트 파일에 키-값 세트로 정보를 저장.

  • SharedPreferences 클래스

    • Preferences의 데이터(키-값 세트)를 관리하는 클래스
    • 응용 프로그램 내의 액티비티 간에 공유하며, 한쪽 액티비티에서 수정 시 다른 액티비티에서도 수정된 값을 읽을 수 있다.
    • 응용 프로그램의 고유한 정보이므로 외부에서는 읽을 수 없다.
    • 알림설정 ON/OFF 등 개인적인 정보에 사용

공유 환경설정의 핸들 가져오기

  • getSharedPreferences (name, mode)
    • 여러개의 Shared Preference파일들을 사용하는 경우
    • name : 프레퍼런스 데이터를 저장할 XML 파일의 이름이다.
    • mode : 파일의 공유 모드
      • MODE_PRIVATE: 생성된 XML 파일은 호출한 애플리케이션 내에서만 읽기 쓰기가 가능
      • MODE_WORLD_READABLE, MODE_WORLD_WRITEABLE은 보안상 이유로 API level 17에서 deprecated됨
        다른대서도 읽을 수 있음
val sharedPref = activity?.getSharedPreferences(
        getString(R.string.preference_file_key), Context.MODE_PRIVATE)
  • 사용 가능한 데이터 타입

    putBoolean
    putFloat
    putInt
    putLong
    putString
    putStingset

  • getPreferences - 한개만 저장할 일이 없어서 잘 안씀
    • 한개의 Shared Preference 파일을 사용하는 경우
    • Activity 클래스에 정의된 메소드 이므로, Activity 인스턴스를 통해 접근 가능
    • 생성한 액티비티 전용이므로 같은 패키지의 다른 액티비티는 읽을 수 없다.
val sharedPref = activity?.getPreferences(Context.MODE_PRIVATE)

Room

  • Room의 주요 3요소
    • @Database: 클래스를 데이터베이스로 지정하는 annotation, RoomDatabase를 상속 받은 클래스여야 함
      • Room.databaseBuilder를 이용하여 인스턴스를 생성함
    • @Entity: 클래스를 테이블 스키마로 지정하는 annotation
    • @Dao: 클래스를 DAO(Data Access Object)로 지정하는 annotation
      • 기본적인 insert, delete, update SQL은 자동으로 만들어주며, 복잡한 SQL은 직접 만들 수 있음

Migration

간단히 말하면 기존에 테이블 쓰다가 추가할게 생겨서 테이블을 변경시키면

이전까지 있던 데이터들이 에러가 날테니 Migration으로 버전을 나눠줌

  • 포함되는 Entity들과 데이터베이스 버전(version)을 @Database annotation에 지정함 버전이 중요 (만약 테이블을 추가해야된다면 테이블이 추가된채 앱을 업데이트할때 기존에 깔려있던 앱 들은 데이터베이스가 업데이트가 안되있어서 에러가남 migration을 이용해 테이블을 추가한다거나 변경함)

    • version이 기존에 저장되어 있는 데이터베이스보다 높으면, 데이터베이스를 open할 때 migration을 수행하게 됨

    • Migration 수행 방법은 RoomDatabase 객체의 addMigration() 메소드를 통해 알려줌

    • 여러개의 Migration 지정 가능

      Room.databaseBuilder(...).addMigrations(MIGRATION_1_2, MIGRATION_2_3)
      
      private val MIGRATION_1_2 = object : Migration(1, 2) {   // version 1 -> 2
          override fun migrate(database: SupportSQLiteDatabase) {
              database.execSQL("ALTER TABLE student_table ADD COLUMN last_update INTEGER")
              //ALTER TABLE 테이블 변경하는거, 컬럼을 추가한다
          }
      }
      
      private val MIGRATION_2_3 = object : Migration(2, 3) {   // version 2 -> 3
          override fun migrate(database: SupportSQLiteDatabase) {
              database.execSQL("ALTER TABLE class_table ADD COLUMN last_update INTEGER")
          }
      }

Room Database의 주요 어노테이션(Annotations)

  1. @Database
    - 데이터베이스 클래스를 정의할 때 사용합니다.
    - 데이터베이스에 포함될 엔티티와 버전을 명시합니다.
    1. @Entity
      • 데이터베이스 내의 테이블을 정의할 때 사용합니다.
      • 클래스 이름이 테이블 이름으로 사용되며, 필드는 컬럼으로 매핑됩니다.
    2. @PrimaryKey
      • 엔티티의 기본 키(primary key)를 정의할 때 사용합니다.
      • 유니크한 값이어야 하며, 데이터베이스 내에서 각 엔티티를 구분하는 데 사용됩니다.
    3. @ColumnInfo
      • 테이블의 컬럼 정보를 세부적으로 정의할 때 사용합니다.
      • 컬럼의 이름, 타입, 인덱스 등을 설정할 수 있습니다.
    4. @Dao
      • 데이터 접근 객체(Data Access Object)를 정의할 때 사용합니다.
      • 데이터베이스의 CRUD(Create, Read, Update, Delete) 연산을 위한 메소드를 포함합니다.
    5. @Insert
      • 데이터를 삽입하는 메소드에 사용합니다.
      • 해당 메소드는 엔티티를 인자로 받아 데이터베이스에 추가합니다.
    6. @Query
      • 복잡한 SQL 쿼리를 실행하는 메소드에 사용합니다.
      • 메소드에 주어진 SQL 쿼리를 실행하여 결과를 반환합니다.
    7. @Update
      • 데이터를 업데이트하는 메소드에 사용합니다.
      • 인자로 받은 엔티티의 데이터로 기존 레코드를 갱신합니다.
    8. @Delete
      • 데이터를 삭제하는 메소드에 사용합니다.
      • 인자로 받은 엔티티를 데이터베이스에서 제거합니다.
    9. @Transaction
      • 메소드가 하나의 트랜잭션으로 실행되어야 함을 나타냅니다.
      • 여러 연산을 하나의 작업으로 묶어 실행할 때 사용합니다.
    10. @ForeignKey
      • 엔티티 간의 외래 키 관계를 정의할 때 사용합니다.
      • 참조 무결성을 유지하는 데 도움을 줍니다.
    11. @Index
      • 특정 컬럼에 인덱스를 생성할 때 사용합니다.
      • 쿼리 성능을 향상시키는 데 유용합니다.

Room DB 유의 사항

DAO는 쿼리언어로

Room의 애노테이션 프로세서를 사용하기 위해서는 room-compiler 의존성을 추가해야 함

    id ("kotlin-kapt")
...
dependencies {
    // Room 관련 의존성
    implementation "androidx.room:room-runtime:2.6.1" // Room 라이브러리
    kapt "androidx.room:room-compiler:2.6.1" // Room의 애노테이션 프로세서

Room은 기본적으로 메인 스레드에서의 데이터베이스 작업을 차단함

따라서 데이터베이스 작업을 백그라운드 스레드에서 수행해야한다

viewModelScope.launch(Dispatchers.IO) {
    // 여기서 데이터베이스 작업 수행
}

코루틴을 사용하자

LiveData 객체의 setValue 메서드가 백그라운드 스레드에서 호출되었을 때도 문제가 생긴다

postValue 사용하자

테이블 확인은 View -> ToolWindows -> AppInspection

0개의 댓글