티스토리 뷰
Room
* 안드로이드에서 제공하는 데이터베이스 API
• 키-벨류 데이터베이스 : SharedPreferences
• 관계형 데이터베이스 : SQLite
- but 공식문서에서는 SQLite API를 직접 사용하는 것이 아닌, Room 라이브러리를 이용하여 SQLite를 다루라고 권장한다.
* 서버 쪽에서만이 아닌 앱 쪽에서도 데이터를 저장할 수 있어야 하는 이유
• 캐싱이 가능하기 때문
- 캐싱 : 캐시를 남기는 작업
- 캐시 : 나중에 빠르게 다시 사용할 수 있도록 남기는 임시 데이터
- 전에 사용했던 데이터를 다시 서버에 요청할 필요없이 빠르게 다시 사용할 수 있다.
- 서버에만 데이터를 저장한다면 간단한 데이터라도 서버와 통신해야하기 때문에 효율이 떨어지고, 무겁다.
- 네트워크 연결이 잠시 끊겨도 앱에 저장된 캐시로 앱을 계속해서 사용할 수 있다.
• Room은 관계형 데이터베이스이다. 대부분의 서버 데이터베이스들은 관계형 데이터베이스를 사용하기 때문에, 서버 쪽 데이터를 Room을 이용하여 캐싱하기에 좋다.
1. Room
• SQLite를 완벽히 활용하면서 원활한 데이터베이스 엑세스가 가능하도록 SQLite에 추상화 계층을 제공.
-> SQLite를 더 편하게 사용할 수 있도록 Room이라는 계층이 하나 더 존재한다고 생각하면 된다.
ex) 개발자가 Room에게 데이터 저장을 명령 -> Room이 SQLite를 이용하여 데이터를 저장해준다.
* 데이터베이스 작업은 메인 쓰레드에서 할 수 없다.
- 데이터베이스 작업은 오래 걸리는 작업이 많은데, 메인 쓰레드에서 하게 되면, 작업을 하는 동안 사용자가 아무 것도 할 수 없기 때문.
- 멀티 쓰레드를 이용하거나 Async를 이용한다.
• Room을 사용하기 위해서는 앱의 build.gradle 파일에 다음을 추가해야 한다.
- optional은 선택사항이다.
...생략...
apply plugin: 'kotlin-kapt'
...생략...
dependencies {
...생략...
def room_version = "2.4.3"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
// To use Kotlin annotation processing tool (kapt)
kapt "androidx.room:room-compiler:$room_version"
// To use Kotlin Symbol Processing (KSP)
ksp "androidx.room:room-compiler:$room_version"
// optional - RxJava2 support for Room
implementation "androidx.room:room-rxjava2:$room_version"
// optional - RxJava3 support for Room
implementation "androidx.room:room-rxjava3:$room_version"
// optional - Guava support for Room, including Optional and ListenableFuture
implementation "androidx.room:room-guava:$room_version"
// optional - Test helpers
testImplementation "androidx.room:room-testing:$room_version"
// optional - Paging 3 Integration
implementation "androidx.room:room-paging:2.5.0-beta01"
}
• Entity, DAO(Data Access Object), Database를 정의한다.
- 데이터베이스 이론이라 우선 간단히 알자.
- Entity : 데이터베이스의 항목이라 생각하면 될 듯.
- DAO : 데이터베이스에 엑세스하게 해주는 객체. DAO를 이용하여 데이터베이스에 데이터 추가, 수정, 삭제 등을 할 수 있다.
- Database : 데이터베이스가 어떤 항목을 가질 지, 어떤 DAO를 이용할 지 정의
package com.example.fastcampus
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.TextView
import androidx.room.*
import androidx.room.OnConflictStrategy.REPLACE
class Room_24 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_room24)
val database = Room.databaseBuilder( // 데이터베이스 생성
applicationContext,
AppDatabase::class.java,
"user_database").allowMainThreadQueries().build()
findViewById<TextView>(R.id.save).setOnClickListener { // save 버튼을 누르면
val user = User("홍", "길동") // 데이터 생성
database.userDao().insert(user) // 데이터베이스에 데이터 추가
}
findViewById<TextView>(R.id.load).setOnClickListener { // load 버튼을 누르면
val users = database.userDao().getAll() // 데이터베이스에 모든 항목 불러오기
users.forEach {
Log.d("testt", "" + it.id + " " + it.firstName + " " + it.lastName)
}
}
findViewById<TextView>(R.id.delete).setOnClickListener { // delete 버튼을 누르면
database.userDao().delete(1) // id = 1 인 데이터 삭제
}
}
}
@Database(entities = [User::class], version = 1) // 데이터베이스 선언
abstract class AppDatabase: RoomDatabase() {
abstract fun userDao(): UserDao
}
@Dao // DAO 선언
interface UserDao {
@Insert(onConflict = REPLACE)
fun insert(user: User)
@Query("DELETE FROM user WHERE id = :id")
fun delete(id: Int)
@Query("SELECT * FROM user")
fun getAll(): List<User>
}
@Entity // Entity 선언
class User(
@PrimaryKey(autoGenerate = true)
val id: Int,
@ColumnInfo(name = "last_name")
val lastName: String,
@ColumnInfo(name = "first_name")
val firstName: String
) {
constructor(lastName: String, firstName: String): this(0, lastName, firstName)
}
• activity_room24.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Room_24">
<TextView
android:id="@+id/save"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#AAAAFF"
android:gravity="center"
android:text="save"
android:textSize="50dp" />
<TextView
android:id="@+id/load"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#FFAAAA"
android:gravity="center"
android:text="load"
android:textSize="50dp" />
<TextView
android:id="@+id/delete"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#AAFFAA"
android:gravity="center"
android:text="delete"
android:textSize="50dp" />
</androidx.appcompat.widget.LinearLayoutCompat>
• 결과
이 글은
패스트 캠퍼스 Android 앱 개발의 정석 with Kotlin 올인원 패키지 Online
강의를 듣고 공부한 내용을 바탕으로 작성되었습니다.
'📱 Android > 💡 개념' 카테고리의 다른 글
[Android/개념] 24. 권한(Permission) (0) | 2022.11.14 |
---|---|
[Android/개념] 23. Network (0) | 2022.11.11 |
[Android/개념] 21. SharedPreferences (0) | 2022.11.10 |
[Android/개념] 20. Database(데이터베이스) (0) | 2022.11.09 |
[Android/개념] 19. ViewPager & TabLayout (0) | 2022.11.09 |