on
[Android/Kotlin] Todo List 앱을 만들어보자! - 3 (Room 데이터베이스)
[Android/Kotlin] Todo List 앱을 만들어보자! - 3 (Room 데이터베이스)
본 포스트는 Todo List 앱을 만들어보자! - 2 에 이어지는 글입니다.
이번 시간에는 Todo List의 데이터베이스 및 viewModel을 개발해보도록 하겠습니다.
이번에 생성할 파일들의 구조입니다.
각 기능별로 패키지를 세분화하였습니다.
그럼 Todo DTO부터 만들어보겠습니다!
Todo.kt
@Entity(tableName = "todoTable") class Todo( @ColumnInfo(name = "id") @PrimaryKey(autoGenerate = true) var id: Long = 0, @ColumnInfo(name = "title") val title: String, @ColumnInfo(name = "content") val content: String, @ColumnInfo(name = "timestamp") val timestamp: String, @ColumnInfo(name = "isChecked") var isChecked: Boolean ): Serializable { }
- @Entitiy는 테이블 이름, @ColumnInfo는 컬럼에 들어갈 이름, @PrimaryKey는 기본키를 의미합니다.
- Todo는
- id: 기본키 autoGenerate = true 를 해주었기 때문에, id 값을 자동으로 증가하게 됩니다.
- title: 제목
- content: 내용
- timestamp: 생성/수정 날짜
- isChecked: 체크박스 클릭(할 일 완료) 여부
로 구성하였습니다.
- Intent에 객체를 담기 위해 Serializable을 상속받았습니다.
다음으로 Dao를 작성하겠습니다.
TodoDao.kt
@Dao interface TodoDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insert(dto: Todo) @Query("select * from todoTable") fun list(): LiveData> @Query("select * from todoTable where id = (:id)") fun selectOne(id: Long): Todo @Update suspend fun update(dto: Todo) @Delete fun delete(dto: Todo) }
- 액티비티 개발에 앞서 CRUD를 먼저 작성해두고 시작하겠습니다!
- insert, query, update, delete는 Room 어노테이션을 사용해 구성하였습니다. SQLite에 비해 훨씬 간편해진 것을 알 수 있을 것입니다.
- 모든 항목을 불러오는 list 함수의 경우 LiveData를 사용해, 추가, 수정, 삭제에 의해 변화하는 값에 대해 즉시 반영이 가능하도록 하였습니다.
이번에는 데이터베이스를 만들어보겠습니다.
TodoDatabase.kt
@Database(entities = arrayOf(Todo::class), version = 1) abstract class TodoDatabase: RoomDatabase() { abstract fun todoDao(): TodoDao }
- entity는 Todo 클래스로, RoomDatabase 라이브러리를 사용해 생성하였습니다.
다음으로 Repository를 만들어봅시다!
TodoRepository.kt
private const val DATABASE_NAME = "todo-database.db" class TodoRepository private constructor(context: Context){ private val database: TodoDatabase = Room.databaseBuilder( context.applicationContext, TodoDatabase::class.java, DATABASE_NAME ).build() private val todoDao = database.todoDao() fun list(): LiveData> = todoDao.list() fun getTodo(id: Long): Todo = todoDao.selectOne(id) fun insert(dto: Todo) = todoDao.insert(dto) suspend fun update(dto: Todo) = todoDao.update(dto) fun delete(dto: Todo) = todoDao.delete(dto) companion object { private var INSTANCE: TodoRepository?=null fun initialize(context: Context) { if (INSTANCE == null) { INSTANCE = TodoRepository(context) } } fun get(): TodoRepository { return INSTANCE ?: throw IllegalStateException("TodoRepository must be initialized") } } }
- 먼저 Room.databaseBuilder().build() 를 통해 데이터베이스를 빌드하도록 합니다.
- companion object 객체는 클래스가 생성될 때 메모리에 적재되면서 동시에 생성하는 객체로, 데이터베이스 생성 및 초기화를 담당하기 위해 작성하였습니다.
다음으로 viewModel을 작성하겠습니다.
viewModel.kt
class TodoViewModel: ViewModel() { val todoList: LiveData> private val todoRepository: TodoRepository = TodoRepository.get() init { todoList = todoRepository.list() } fun getOne(id: Long) = todoRepository.getTodo(id) fun insert(dto: Todo) = viewModelScope.launch(Dispatchers.IO) { todoRepository.insert(dto) } fun update(dto: Todo) = viewModelScope.launch(Dispatchers.IO) { todoRepository.update(dto) } fun delete(dto: Todo) = viewModelScope.launch(Dispatchers.IO) { todoRepository.delete(dto) } }
- viewModel은 액티비티의 라이프사이클과 별개로 돌아가기 때문에 데이터의 유지 및 공유가 가능합니다.
- 이에 따라 viewModel에서 CRUD를 사용해 액티비티의 이동이 있어도 동일하게 값을 불러올 수 있도록 하였습니다.
마지막으로 ApplicationClass입니다!
ApplicationClass.kt
class ApplicationClass: Application() { override fun onCreate() { super.onCreate() TodoRepository.initialize(this) } }
- 이 클래스의 경우 앱이 실행될 때 단 한번 실행되도록 하기 위해 작성하였습니다.
- 앱 실행과 동시에 Repository 초기화를 통해 데이터베이스가 없을 경우 새로 빌드하도록 하였습니다.
ApplicationClass가 동작하도록 하기위해 Manifests를 수정하겠습니다.
AndroidManifest.xml
작성할 코드가 많았지만 충분히 따라올 수 있을 것이라 생각합니다!
오늘은 Room 데이터베이스, ViewModel 을 통해 CRUD 함수를 개발하였습니다.
다음시간에는 본격적으로 Todo 생성을 해보도록 하겠습니다.!
from http://pekahblog.tistory.com/169 by ccl(S) rewrite - 2021-11-17 08:02:38