현재 진행 중인 프로젝트에서 앱 내부에 데이터를 저장하고 사용할 일이 생겼다.
1.자동 로그인
회원가입 시 내부 데이터에 정보를 저장하고, 시작 액티비티 부분에 내부 데이터에 id,pw를 서버에 보내고 DB쪽과 일치한다면 바로 메인 화면으로 이동하게끔.
자동 로그인에서 필요한 것은 id,pw 근데 이걸 한 사용자가 다양하게 List적으로 보관할 필요가 없긴해서 이건 그냥 txt파일로 저장하고 불러올 것 같다. 다만 pw저장 시 해시 등에 기법을 사용해야할 것 같다.
2.변하지 않는 데이터 제공
재난 상황이 발생했을 때 가이드라인 데이터를 제공해야하는데 DB나 서버가 가지고 있기 보다는 그냥 앱에 저장된 걸 사용하는 게 편하다는 의견이 있었고 크게 클라이언트쪽에 성능 저하가 발생하거나 그런 일이 없을 것 같아서 클라이언트쪽에서 저장하고 바로 불러오는 형식으로 하려한다.
이건 재난에 따라 홍수, 지진 등에 따라 DB로 표현할 수 있을 것 같긴하다.
내부 데이터를 사용해본 적이 없어서 처음에 SQLite와 Room이 서로 다른 각각 하나의 방식인 줄 알았다.
전혀 그렇지 않고 SQLite를 편하게 사용할 수 있게 하는 것이 Room이다.
bulid.gradle.kts (앱 수준)을 열고
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id ("kotlin-kapt")
}
// ROOM Database 사용
implementation("androidx.room:room-runtime:2.4.3")
annotationProcessor("androidx.room:room-compiler:2.4.3")
implementation("androidx.room:room-ktx:2.4.3")
kapt("androidx.room:room-compiler:2.4.3")
//-> 이건 sync now 한 번 하고 나중에 하는 게 인식이 잘 되는 것 같다!
Database
DB를 생성하고 관리하는 데이터베이스 객체 만들기 위한 추상 클래스
Entity
테이블
DAO (Data Access Object)
DB를 삽입,삭제,조회 등을 정의해놓은 인터페이스.
//테이블을 만들자
@Entity
data class User(
@PrimaryKey val uid: Int,
@ColumnInfo(name = "first_name") var firstName: String?,
@ColumnInfo(name = "last_name") var lastName: String?
)
//다오(DB와 상호작용(CRUD)
@Dao
interface UserDao {
@Query("SELECT * FROM user")
fun getAll(): List<User>
@Query("SELECT * FROM user WHERE uid IN (:userIds)")
fun loadAllByIds(userIds: IntArray): List<User>
@Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
"last_name LIKE :last LIMIT 1")
fun findByName(first: String, last: String): User
@Insert
fun insertAll(vararg users: User)
@Delete
fun delete(user: User)
}
//DB클래스
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
//데이터베이스 인스턴스 생성
val db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java, "database-name"
).build()
//DAO인스턴스 가져오기..이제 사용하면 된다!
val userDao = db.userDao()
':app:kaptGenerateStubsDebugKotlin' 작업에 대한 실행에 실패했습니다.
'compileDebugJavaWithJavac' 태스크(현재 대상은 1.8)와 'kaptGenerateStubsDebugKotlin' 태스크(현재 대상은 17) jvm 대상 호환성을 동일한 Java 버전으로 설정해야 합니다.
라고 한다..해당 에러는 타 블로그 분을 참고해서 해결!
https://velog.io/@mraz3068/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EC%8A%A4%ED%8A%9C%EB%94%94%EC%98%A4-%EB%B9%8C%EB%93%9C-%EA%B4%80%EB%A0%A8-%EC%98%A4%EB%A5%98JDK-version-17-1.8-11-%EB%AC%B4%ED%95%9C-%EB%B0%98%EB%B3%B5
위와 같이 바로 메인스레드에서 처리하려면 오류가 난다..메인스레드가 UI와의 작용도 처리해야하고 하니까 아마 다른 스레드 사용을 유도하는 것 같다!
// DB관련 작업은 타 쓰레드에서!!
implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.4.0")
implementation ("androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0")
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2")
//데이터베이스 인스턴스 생성
val db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java, "testDB-230826"
).build()
//DAO인스턴스 가져오기..이제 사용하면 된다!
val userDao = db.userDao()
val user1 = User(uid = 1, firstName = "John", lastName = "Doe")
// 액티비티의 lifecycleScope 내에서 코루틴 사용
lifecycleScope.launch(Dispatchers.IO) {
// IO 스레드에서 사용자 삽입
userDao.insertAll(user1)
// IO 스레드에서 사용자 검색
val users: List<User> = userDao.getAll()
// 메인 스레드에서 UI 업데이트
launch(Dispatchers.Main) {
Log.d("테스트", users.toString())
inf.text = users.toString()
}
}
https://developer.android.com/training/data-storage/room?hl=ko