ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Room - Android Local Database
    Android 2023. 2. 23. 13:02


    ๐Ÿ™‡ ์•ˆ๋…•ํ•˜์„ธ์š” ! Mash-Up 10๊ธฐ Android Developer ์ •ํ˜„์„ฑ ์ธ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๐Ÿ™‡

     

    ์ด๋ฒˆ ํฌ์ŠคํŒ… ์ฃผ์ œ๋กœ ๋ฌด์—‡์„ ํ• ๊นŒ ๊ณ ๋ฏผ์„ ํ•˜๋‹ค,,,, ์ตœ๊ทผ ์ทจ์—… ์ค€๋น„๋ฅผ ํ•˜๋ฉฐ ๊ทธ๋™์•ˆ ๊ฐœ๋ฐœํ–ˆ๋˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋“ค์„ ํ•˜๋‚˜์˜ ํฌํŠธํด๋ฆฌ์˜ค๋กœ ๋ณด์—ฌ์ฃผ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•œ ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœํ•˜๋ฉฐ ์‚ฌ์šฉํ–ˆ๋˜ ๊ธฐ์ˆ  ์Šคํƒ ์ค‘ ํ•˜๋‚˜์ธ Room์— ๋Œ€ํ•ด ๋‹ค์‹œ ์ •๋ฆฌํ•ด๋ณผ ๊ฒธ ํฌ์ŠคํŒ… ์ฃผ์ œ๋กœ ์„ ์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

     

    ๐Ÿ’พ Local Database

    ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ๋Š” ์•ฑ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ €์žฅ์†Œ๋กœ SQLite๋ผ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋‹ค๋ฅธ ์™ธ๋ถ€ Database๋“ค๊ณผ ๋‹ฌ๋ฆฌ ์†Œ๊ทœ๋ชจ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ์ ํ•ฉํ•œ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‚ฌ์šฉ ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์šฉ๋Ÿ‰์ด ํฌ์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋“ค์€ ๊ตณ์ด ์„œ๋ฒ„์— ์ ‘์†ํ•˜๊ณ  ์ €์žฅํ•˜๋Š” ์ˆ˜๊ณ ๋ฅผ ๋“ค์ด์ง€ ์•Š๊ณ  ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ํ†ตํ•ด ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์ ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š”๋ฐ ์ตœ์ ํ™”๋œ ๋งŒํผ ์†๋„๊ฐ€ ๋น ๋ฅด๊ณ  ๊ฐ€๋ณ๋‹ค๋Š” ์žฅ์ ์ด ์กด์žฌํ•˜์—ฌ ํ˜„์‹œ์ ์˜ ๋งŽ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ณตํ†ต์œผ๋กœ ๋‚ด๋ถ€ DB๋ฅผ ํ™œ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

     

    Local Database ์ข…๋ฅ˜

     

    SQLite Database Library, Room Database Library

    ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ Local Database๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ, SQLite Database Library ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•ด์™”์Šต๋‹ˆ๋‹ค.

     

    ํ•˜์ง€๋งŒ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ƒ๋‹นํ•œ ์‹œ๊ฐ„๊ณผ ๋…ธ๋ ฅ ๋“ฑ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์ด ๋ณต์žกํ•˜์—ฌ, ๊ตฌ๊ธ€์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ ์ž ์ƒˆ๋กญ๊ฒŒ Room Database Library๋ฅผ ๋ฐฐํฌํ•˜์˜€์Šต๋‹ˆ๋‹ค.

     

    ๐Ÿ‘ Room์— ์ƒˆ๋กญ๊ฒŒ ์ถ”๊ฐ€๋œ ๊ธฐ๋Šฅ
    
    1. ์ปดํŒŒ์ผ ์‹œ์ ์— SQL ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๊ธฐ๋Šฅ
    2. Schema๊ฐ€ ๋ณ€๊ฒฝ๋  ์‹œ ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธ ๊ธฐ๋Šฅ
    3. Java ๋ฐ์ดํ„ฐ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด ์ƒ์šฉ๊ตฌ ์ฝ”๋“œ ์—†์ด ORM ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด ๋งคํ•‘ ๊ธฐ๋Šฅ
    4. LiveData์™€ Rx Java๋ฅผ ์œ„ํ•œ Observation ์ƒ์„ฑ ๋ฐ ๋™์ž‘ ๊ธฐ๋Šฅ

    ์œ„์™€ ๊ฐ™์ด SQLite Database Library์—์„œ๋Š” ํ—ˆ์šฉ๋˜์ง€ ์•Š๋˜ ๊ธฐ๋Šฅ๋“ค์ด ์ƒˆ๋กญ๊ฒŒ ์ถ”๊ฐ€๋˜๋ฉด์„œ ์กฐ๊ธˆ ๋” ๊ฐœ๋ฐœ์ž๋“ค์ด Local DB๋ฅผ ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋œ ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ์— ๋”ฐ๋ผ SQLite Database์˜ ์‚ฌ์šฉ ๋นˆ๋„๋Š” ์ค„์–ด๋“ค๊ณ , Room Database์˜ ์‚ฌ์šฉ ๋นˆ๋„๋Š” ์ฆ๊ฐ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


    ๐Ÿ’ฝ Room Library

    ORM์ด๋ž€?

     

    ๋จผ์ €, Room์„ ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ธฐ ์ „์— ORM์— ๋Œ€ํ•œ ๊ฐœ๋…์„ ๊ฐ„๋‹จํžˆ ์‚ดํŽด๋ณผ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

    • Object-Relational Mapping
    • ORM์ด๋ž€, Object Relational Mapping, ๊ฐ์ฒด-๊ด€๊ณ„ ๋งคํ•‘์˜ ์ค„์ž„๋ง์ž…๋‹ˆ๋‹ค. ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(Object Oriented Programming, OOP)์€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(Relational DataBase, RDB)๋Š” ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฐ์ฒด ๋ชจ๋ธ๊ณผ ๊ด€๊ณ„ํ˜• ๋ชจ๋ธ ๊ฐ„์— ๋ถˆ์ผ์น˜๊ฐ€ ์กด์žฌํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ORM์„ ํ†ตํ•ด ๊ฐ์ฒด ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ SQL๋ฌธ์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜์—ฌ ๋ถˆ์ผ์น˜๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์žฅ์ 
      1. ๊ฐ์ฒด ์ง€ํ–ฅ์ ์ธ ์ฝ”๋“œ๋กœ ์ธํ•ด ๋” ์ง๊ด€์ ์ด๊ณ , ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋‹ค.
      2. ์žฌ์‚ฌ์šฉ์„ฑ ๋ฐ ์œ ์ง€๋ณด์ˆ˜์˜ ํŽธ๋ฆฌ์„ฑ์ด ์ฆ๊ฐ€ํ•œ๋‹ค.
    • ๋‹จ์ 
      1. ์™„๋ฒฝํ•œ ORM์œผ๋กœ๋งŒ ์„œ๋น„์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต๋‹ค.
      2. ํ”„๋กœ์‹œ์ €๊ฐ€ ๋งŽ์€ ์‹œ์Šคํ…œ์—์„œ๋Š” ORM์˜ ๊ฐ์ฒด ์ง€ํ–ฅ์ ์ธ ์žฅ์ ์„ ํ™œ์šฉํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

    Room์ด๋ž€?

     

    ์•ˆ๋“œ๋กœ์ด๋“œ ์•„ํ‚คํ…์ณ ์ปดํฌ๋„ŒํŠธ(Android Architecture Components, AAC)์— ์†ํ•˜๋Š” Room์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‰ฝ๊ณ  ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ORM ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.

    Room Library ๊ตฌ์„ฑ์š”์†Œ

     

    ์—”ํ‹ฐํ‹ฐ(Entity), ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ฐ์ฒด(DAO), ๋ฃธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(Room Database), ์ด ์„ธ ๊ฐœ์˜ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ํ†ตํ•ด Room ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.

     

     

    • Entity
      ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋‚ด์˜ ๋ฆด๋ ˆ์ด์…˜ ์ฆ‰, ํ…Œ์ด๋ธ”์„ ๋œปํ•˜๋ฉฐ DB์— ์ €์žฅํ•  ๋ฐ์ดํ„ฐ ํ˜•์‹์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
    • DAO(Data Access Object)
      ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜์—ฌ ์ˆ˜ํ–‰ํ•  ์ž‘์—…์„ ๋ฉ”์†Œ๋“œ ํ˜•ํƒœ๋กœ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
    • Room Database
      ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ „์ฒด์ ์ธ ์†Œ์œ ์ž ์—ญํ• ์„ ํ•˜๋ฉฐ DB๋ฅผ ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ๋ฒ„์ „์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

    ๐Ÿ’ป ์˜ˆ์ œ ์‚ดํŽด๋ณด๊ธฐ

    Room Database๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํฌํŠธํด๋ฆฌ์˜ค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

     

    - Entity (๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ํ…Œ์ด๋ธ” ๋‹ด๋‹น)
    
      PortfolioEntity, ProfileEntity
    
    - DAO (๊ฐ๊ฐ์˜ ํ…Œ์ด๋ธ”์— ์ ‘๊ทผํ•˜์—ฌ ์ž‘์—… ์ˆ˜ํ–‰์„ ๋‹ด๋‹น)
    
      PortfolioDao, ProfileDao
    
    - Room Database (๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ „์ฒด์ ์ธ ์†Œ์œ ์ž ์—ญํ• )
    
      PortfolioDatabase

     

    ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ตฌ์„ฑ์š”์†Œ ์ž…๋‹ˆ๋‹ค.

     

    Build.Gradle ์„ค์ •ํ•˜๊ธฐ

    dependencies {
      	//Room Database Library
        implementation "androidx.room:room-runtime:2.2.6"
        implementation "androidx.room:room-ktx:2.2.6"
        implementation "androidx.room:room-testing:2.2.6"
        kapt "androidx.room:room-compiler:2.2.6"
    }

     

     

    PortfolioEntity

    @Entity(tableName = "portfolio")
    data class PortfolioEntity(
        @PrimaryKey(autoGenerate = true)
        @ColumnInfo(name = "id")
        val id: Long,
        @ColumnInfo(name = "thumbnail")
        val thumbnail: Int,
        @ColumnInfo(name = "image_drawable")
        val image: String,
        @ColumnInfo(name = "project")
        val project: String,
        @ColumnInfo(name = "introduction")
        val introduction: String,
        @ColumnInfo(name = "programming_language")
        val programming: String,
        @ColumnInfo(name = "architecture")
        val architecture: String,
        @ColumnInfo(name = "library")
        val library: String,
        @ColumnInfo(name = "server")
        val server: String,
        @ColumnInfo(name = "term")
        val term: String,
        @ColumnInfo(name = "link")
        val link: String
    )

    @Entity ์–ด๋…ธํ…Œ์ด์…˜๊ณผ ํ•จ๊ป˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋‚ด์˜ ๋ฆด๋ ˆ์ด์…˜(ํ…Œ์ด๋ธ”)์„ ์ƒ์„ฑํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค์˜ ์ด๋ฆ„์€ PortfolioEntity์ด์ง€๋งŒ tableName์„ portfolio๋กœ ์„ค์ •ํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— ํด๋ž˜์Šค ์ด๋ฆ„๊ณผ๋Š” ๋ณ„๊ฐœ๋กœ ์œ„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋‚ด์˜ ๋ฆด๋ ˆ์ด์…˜ ์ด๋ฆ„์€ portfolio๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๋กœ ๋ฆด๋ ˆ์ด์…˜ ๋‚ด์˜ ๊ฐ๊ฐ์˜ ์†์„ฑ๋“ค์„ ์ •์˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

    PortfolioDao

    @Dao
    interface PortfolioDao {
    
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        suspend fun insertPortfolio(portfolioEntity: PortfolioEntity)
    
        @Query("SELECT * FROM portfolio")
        suspend fun getPortfolio(): List<PortfolioEntity>
    
        @Query("SELECT * FROM portfolio WHERE id = :id")
        suspend fun getPortfolioInfo(id: Long): PortfolioEntity
    
    }

    @Dao ์–ด๋…ธํ…Œ์ด์…˜๊ณผ ํ•จ๊ป˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜์—ฌ ์ˆ˜ํ–‰ํ•  ์ž‘์—…๋“ค์„ ๋ฉ”์„œ๋“œ ํ˜•ํƒœ๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์†Œ๋“œ๋“ค์€ interface ๋‚ด์— ํฌํ•จ๋˜๋ฏ€๋กœ ๋ชจ๋‘ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋“ค์ด๋ฉฐ ์กฐํšŒ, ์ถ”๊ฐ€, ์ˆ˜์ •, ์‚ญ์ œ ๊ธฐ๋Šฅ( ์ €๋Š” ์ถ”๊ฐ€, ์กฐํšŒ ๊ธฐ๋Šฅ๋งŒ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. )์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

    ๋˜ํ•œ, insert ๋ฉ”์†Œ๋“œ ๋ถ€๋ถ„์„ ๋ณด๋ฉด, onConflict ์„ค์ •์„ ํ†ตํ•ด ๋งŒ์•ฝ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋‚ด์— ์ค‘๋ณต๋œ ๋ฐ์ดํ„ฐ ๊ฐ’์ด ์กด์žฌํ•œ๋‹ค๋ฉด, ๊ทธ ๊ฐ’ ์œ„์— ๋ฎ์–ด ์”Œ์šฐ๋Š” ์„ค์ •์„ ํ•ด๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

     

    PortfolioDatabase

    @Database(
        entities = [
            ProfileEntity::class,
            PortfolioEntity::class
        ],
        version = VERSION,
        exportSchema = false
    )
    
    abstract class PortfolioDatabase : RoomDatabase() {
    
        abstract fun profileDao(): ProfileDao
        abstract fun portfolioDao(): PortfolioDao
    
        companion object {
            const val VERSION = 1
            private const val TABLE_NAME = "portfolio_db"
    
            @Volatile
            private var instance: PortfolioDatabase? = null
    
            fun getInstance(context: Context): PortfolioDatabase {
                return instance ?: synchronized(this) {
                    instance ?: buildDatabase(context).also { instance = it }
                }
            }
    
            private fun buildDatabase(context: Context): PortfolioDatabase {
                return Room.databaseBuilder(context, PortfolioDatabase::class.java, TABLE_NAME)
                    .build()
            }
        }
    
    }

    @Database ์–ด๋…ธํ…Œ์ด์…˜๊ณผ ํ•จ๊ป˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ „์ฒด์ ์ธ ์†Œ์œ ์ž ์—ญํ• ์„ ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์•ž์—์„œ ์ƒ์„ฑํ•œ Entity, DAO ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ฉ์ ์œผ๋กœ ๋ฌถ์–ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ๋ฒ„์ „ ๊ด€๋ฆฌ๋ฅผ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

    Dagger DI ( ์˜์กด์„ฑ ์ฃผ์ž…์— ๋Œ€ํ•œ ์„ค๋ช…์€ ์ƒ๋žตํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค :( )

    DatabaseModule

    @Module
    class DatabaseModule {
    
       @Singleton
       @Provides
       fun providesPortfolioDatabase(context: Context): PortfolioDatabase =
           PortfolioDatabase.getInstance(context)
    
       @Singleton
       @Provides
       fun providesPortfolioDao(db: PortfolioDatabase): PortfolioDao = db.portfolioDao()
    
    }

    @Singleton ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด, ์ƒ์„ฑ์ž๊ฐ€ ์—ฌ๋Ÿฌ ์ฐจ๋ก€ ํ˜ธ์ถœ๋˜๋”๋ผ๋„ ์‹ค์ œ๋กœ ์ƒ์„ฑ๋˜๋Š” ๊ฐ์ฒด๋Š” ํ•˜๋‚˜์ด๊ณ , ์ตœ์ดˆ ์ƒ์„ฑ ์ดํ›„์— ํ˜ธ์ถœ๋œ ์ƒ์„ฑ์ž๋Š” ์ตœ์ดˆ์˜ ์ƒ์„ฑ์ž๊ฐ€ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•˜๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

    PortfolioRepository

    interface PortfolioRepository {
    
       suspend fun insertPortfolio(portfolio: Portfolio)
    
       suspend fun getPortfolio(): List<Portfolio>
    
       suspend fun getPortfolioInfo(id: Long): Portfolio
    
    }

    PortfolioRepositoryImpl

    class PortfolioRepositoryImpl(
       private val portfolioDao: PortfolioDao
    ) : PortfolioRepository {
    
       override suspend fun insertPortfolio(portfolio: Portfolio) =
           portfolioDao.insertPortfolio(portfolio.mapPortfolioEntity())
    
       override suspend fun getPortfolio(): List<Portfolio> =
           portfolioDao.getPortfolio().mapPortfolioList()
    
       override suspend fun getPortfolioInfo(id: Long): Portfolio =
           portfolioDao.getPortfolioInfo(id).mapPortfolio()
    
    }

     

    PortfolioMapper

    fun Portfolio.mapPortfolioEntity(): PortfolioEntity =
       PortfolioEntity(
           id,
           thumbnail,
           image,
           project,
           introduction,
           programming,
           architecture,
           library,
           server,
           term,
           link
       )
    
    fun PortfolioEntity.mapPortfolio(): Portfolio =
       Portfolio(
       		id,
       		thumbnail,
       		image,
       		project,
       		introduction,
       		programming,
       		architecture,
       		library,
       		server,
       		term,
       		link
       )
    
    fun List<PortfolioEntity>.mapPortfolioList(): List<Portfolio> =
       map { it.mapPortfolio() }

    ๊ฐ€์ ธ์˜จ Data๋ฅผ Mappingํ•˜๋Š” ๋งค์†Œ๋“œ์ž…๋‹ˆ๋‹ค.

     

    SampleData
    val INIT_PORTFOLIO: List<Portfolio> = listOf(
    	Portfolio(
    		..
    	),
    	Portfolio(
    		..
    	),
    		..
    )
    

    HomeViewModel

    class HomeViewModel @Inject constructor(
    	private val portfolioRepository: PortfolioRepository
    ) : ViewModel() {
    
      private val portfolio = MediatorLiveData<List<Portfolio>>()
    
      private val _homePortfolioUiModel = MediatorLiveData<List<HomePortfolioUiModel>>()
      val homePortfolioUiModel: LiveData<List<HomePortfolioUiModel>>
            get() = _homePortfolioUiModel
    
      init {
        _homePortfolioUiModel.addSource(portfolio) {
          _homePortfolioUiModel.value = it.mapToHomePortfolioUiModel()
        }
      }
    
      private fun insertPortfolio() {
        viewModelScope.launch {
          INIT_PORTFOLIO.iterator().forEach {
            portfolioRepository.insertPortfolio(it)
          }
        }
    
        portfolio.value = INIT_PORTFOLIO
      }
    
      private fun getPortfolio() {
        viewModelScope.launch {
          portfolio.value = portfolioRepository.getPortfolio()
        }
      }
    }
    

     

    ์ด๋ฒˆ ํฌ์ŠคํŒ…์„ ํ†ตํ•ด SQLite Database์— ๋น„ํ•ด Room Database๊ฐ€ ์„ฑ๋Šฅ๋ฉด์—์„œ๋„ ๋›ฐ์–ด๋‚˜๊ณ  ํŽธ๋ฆฌํ•˜๊ณ  ์ง๊ด€์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ฒด๊ฐํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค :)

    ๊ทธ๋Ÿผ ๐Ÿ‘‹

     


    ๐Ÿ“– Reference

    Room_Blog

    Room_Google Developers

    ORM_Blog

    'Android' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

    Custom View  (0) 2023.02.24
    Dagger - Raw Dagger  (0) 2023.02.24
    Android UI Test  (0) 2023.02.14
    Replace LiveData, SingleLiveEvent with Coroutines!  (0) 2023.02.14
    View Binding: What is it?  (0) 2023.02.14
Designed by Tistory.