Room_DB_제작 - boostcampwm-2024/and04-Nature-Album GitHub Wiki

✅ Room DB 설계 회의

  1. 라벨 ⇒ data class ⇒ 테이블에 저장
    1. id
    2. 라벨 배경색
    3. 이름
  2. 앨범⇒ data class ⇒ 테이블에 저장
    1. id
    2. 라벨 id
    3. 사진 디테일 이미지 id
  3. 사진 디테일 ⇒ data class → 테이블에 저장
    1. id
    2. 라벨 id
    3. bitmap 이미지
    4. 위치
    5. 설명
    6. 촬영일시
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY

💡 예리한 발견

  • 만약 다른 이미지로 대표이미지를 선택한다면 이전의 대표 이미지 필드의 값을 false로 바꾸기 위해 모든 도감 정보를 탐색해야하는 문제가 있었음
  • 대표이미지는 [앨범] 테이블 내에서 [사진 디테일] 테이블의 id값을 통해 관리한다면 탐색없이 효과적으로 가능

Q. key값을 무엇으로 둘 것인가?

  • 0 ~N으로 두자
  • 촬영일시

⇒ NoSQL 연결을 고려하고, 우선순위를 고려하여 복잡성을 줄이고 편의성을 높이자.

⇒ id를 key값으로 주자.

✅ Room DB 제작하기

참고: ✅ Room DB 네이밍 규칙

  • @Entity, @ColumnInfo를 모두 명시한다.
  • tableName과 column name은 snake 형식으로 작성한다.
@Entity(tableName = "label")
data class Label(
    @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Int,
    @ColumnInfo(name = "back_color") val backgroundColor: String,
    @ColumnInfo(name = "name") val name: String
)

💡table 구성도

💡Room DB 사용 예상 시나리오 & 쿼리문

  1. 사진 저장하기

    • 사용자가 입력한 라벨이 Label 테이블에 있는지 확인
      • SELECT id FROM LABEL WHERE name = :name
    • 사용자가 입력한 라벨이 Label 테이블에 없으면 해당 라벨을 Label 테이블에 생성
      • INSERT INTO LABEL(background_color, name) VALUES (:background_color, :name)
    • 사용자가 입력한 정보와 label_id 를 가지고 PhotoDetail 테이블에 저장
      • SELECT id FROM LABEL WHERE name = :name
      • INSERT INTO PHOTO_DETAIL VALUES (...)
    • label_id 와 방금 저장한 photo_detail_idAlbum 테이블에 저장
      • INSERT INTO ALBUM(..) VALUES (..)
  2. 모든 사진 가져오기

    • SELECT * FROM PHOTO_DETAIL
  3. 특정 앨범의 사진 전부 가져오기

    • 특정 앨범의 사진 가져오는 경우

      • 사용자가 화면 터지했을 때 해당 LazyColumn의 item의 id를 가져옴
      • 그 item은 Album이므로 해당 Album에 포함되어 있는 label_id를 기준으로 다 가져오면 됨
          @Query("SELECT photo_uri FROM photo_detail WHERE label_id = :labelId")
          fun getAllPhotoDetailUriByLabelId(labelId: Int): String
  4. 모든 앨범 가져오기

    label 이름과 detail 사진(대표) 필요

    • album 테이블에서 모든 정보 가져오기

      @Query("SELECT * FROM album")
          fun getALLAlbum(): List<Album>
    • label id로 label 테이블 조회하여 label name 가져오기

      @Query("SELECT name FROM label WHERE id = :id")
          fun getLabelNameById(id: Int): String
    • photo_detail id로 photo_detail 조회하여 uri 가져오기

      @Query("SELECT photo_uri FROM photo_detail WHERE id = :id")
          fun getPhotoDetailUriById(id: Int): String

Room Entity

@Entity(tableName = "label")
data class Label(
    @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Int = 0,
    @ColumnInfo(name = "background_color") val backgroundColor: String,
    @ColumnInfo(name = "name") val name: String
)

@Entity(
    tableName = "album",
    foreignKeys = [
        ForeignKey(
            entity = Label::class,
            parentColumns = ["id"],
            childColumns = ["label_id"],
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = PhotoDetail::class,
            parentColumns = ["id"],
            childColumns = ["photo_detail_id"],
            onDelete = ForeignKey.CASCADE
        )
    ]
)
data class Album(
    @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Int = 0,
    @ColumnInfo(name = "label_id") val labelId: Int,
    @ColumnInfo(name = "photo_detail_id") val photoDetailId: Int
)

@Entity(
    tableName = "photo_detail",
    foreignKeys = [
        ForeignKey(
            entity = Label::class,
            parentColumns = ["id"],
            childColumns = ["label_id"],
            onDelete = ForeignKey.CASCADE
        )
    ]
)
data class PhotoDetail(
    @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Int = 0,
    @ColumnInfo(name = "label_id") val labelId: Int,
    @ColumnInfo(name = "photo_uri") val photoUri: String,
    @ColumnInfo(name = "location") val location: String,
    @ColumnInfo(name = "description") val description: String,
    @ColumnInfo(name = "datetime") val datetime: String
)
  • 다른 테이블을 참조하는 Column은 ForeignKey로 지정하여 해당 키 값이 잘 못되어 있으면 DB에서 에러를 받도록 구성
⚠️ **GitHub.com Fallback** ⚠️