iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
1

Room

Room是一個基於SQLite的數據庫框架,使用注解來取代SQL語句,可以在本地存儲大量數據。
最常見的就是緩存數據,當設備無法訪問網絡時,用戶仍可以瀏覽內容,有網路後就可以將用戶操作的內容更改同步到伺服器。

@Entity(tableName = "表格名稱"):標記為資料表。
@PrimaryKey(autoGenerate = true):自動添加唯一值。

@Dao:標記為Dao,將增刪改查四種方法寫在裡面。
@Insert(onConflict = OnConflictStrategy.REPLACE):增加資料,衝突時取代。
@Update(onConflict = OnConflictStrategy.REPLACE):更新資料,衝突時取代。
@Delete:刪除資料。
@Query("SELECT * FROM demo_table"):查詢全部資料。
@Query("SELECT * FROM demo_table WHERE info LIKE :info"):查詢info資料。

@Database(entities = [Demo::class], version = 1):標記要使用的資料表以及版本。
Room.databaseBuilder(context, DemoDatabase::class.java, "DemoDB").build():創建資料庫。
Room.inMemoryDatabaseBuilder(context, DemoDatabase::class.java).build():建測試資料庫,會清除資料。

導入Room 因為會使用到註解所以新增kapt

plugins {
    id 'kotlin-kapt'
}

dependencies {
    def room_version = "2.2.6"
    implementation "androidx.room:room-runtime:$room_version"
    kapt "androidx.room:room-compiler:$room_version"
}

創建資料表

@Entity(tableName = "demo_table")
class Demo {
    @PrimaryKey(autoGenerate = true)
    var id: Int = 0
    var info : String = ""
}

創建Dao(增刪改查)

@Dao
interface DemoDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insert(demo: Demo)

    @Update(onConflict = OnConflictStrategy.REPLACE)
    fun update(demo: Demo)

    @Delete
    fun delete(demo: Demo)

    @Query("SELECT * FROM demo_table")
    fun getAllDemo(): LiveData<List<Demo>>

    @Query("SELECT * FROM demo_table WHERE info LIKE :info")
    fun findByInfo(info: String): Demo
}

創建Database(因為使用同個資料庫所以使用Singleton,並且把抽象方法的Dao也放進去)

@Database(entities = [Demo::class], version = 1)
abstract class DemoDatabase : RoomDatabase() {

    abstract val demoDao: DemoDao
    
    companion object {
        @Volatile
        private var INSTANCE: DemoDatabase? = null
        fun getInstance(context: Context) : DemoDatabase {
            synchronized(this) {
                var instance = INSTANCE
                if (instance == null) {
                    instance = Room.databaseBuilder(
                        context.applicationContext, 
                        DemoDatabase::class.java,
                        "DemoDB"
                    ).fallbackToDestructiveMigration().build()
                }
                return instance
            }
        }
    }
}

MainActivity.kt

class MainActivity : AppCompatActivity() {

    private lateinit var demoDao: DemoDao
    private lateinit var demo: Demo
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //創建Database並取得Dao
        demoDao = DemoDatabase.getInstance(application).demoDao() 
        demo = Demo() 
    }

    fun insert(view: View) {
        CoroutineScope(Dispatchers.IO).launch {
            demo.info = "Hello World!"
            demoDao.insert(demo)
        }
    }

    //更新資料需要先撈取要改變的資料
    fun update(view: View) {
        CoroutineScope(Dispatchers.IO).launch {
            val dd = demoDao.findByInfo("Hello World!")
            dd.info = "Hello Jetpack"
            demoDao.update(dd)
        }
    }

    //刪除資料需要先撈取要刪除的資料
    fun delete(view: View) {
        CoroutineScope(Dispatchers.IO).launch {
            val dd = demoDao.findByInfo(input.text.toString())
            demoDao.delete(dd)
        }
    }

    //將查詢結果顯示在畫面上,使用LiveData會自動更新View
    fun query(view: View) {
        demoDao.getAllDemo().observe(this@MainActivity, Observer {
            title = it.size.toString()
            data.text = if (it.isNotEmpty()) { it[it.size - 1].info } else { "沒資料" }
        })
    }
}


上一篇
{Day8} Coroutines
下一篇
{Day10} Retrofit
系列文
Kotlin Android Jetpack 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言