[Android / Kotlin] Room 예제

Subeen·2024년 1월 23일
0

Android

목록 보기
48/73

결과 화면

Activity

class MainActivity : AppCompatActivity() {

    private val binding by lazy {
        ActivityMainBinding.inflate(layoutInflater)
    }
    lateinit var myDao: MyDAO

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        initView()
    }

    private fun initView() {
        // getDatabase에서 인스턴스를 가져옴
        myDao = MyDatabase.getDatabase(this).getMyDao()

        val allStudents = myDao.getAllStudent() // 테이블의 모든 Student 리스트를 가져옴

        // observe를 통해 자동으로 변경 됨
        allStudents.observe(this@MainActivity) {
            val str = StringBuilder().apply {
                for ((id, name) in it) {
                    append(id)
                    append("-")
                    append(name)
                    append("\n")
                }
            }.toString()
            binding.textStudentList.text = str
        }

        binding.addStudent.setOnClickListener {
            val id = binding.editStudentId.text.toString().toInt()
            val name = binding.editStudentName.text.toString()
            if (id > 0 && name.isNotEmpty()) { // 빈 값 체크
                CoroutineScope(Dispatchers.IO).launch {
                    myDao.insertStudent(Student(id, name)) // 객체 형태로 테이블에 insert
                }
            }

            // insert 후 EditText 초기화
            binding.editStudentId.text = null
            binding.editStudentName.text = null
        }

        binding.queryStudent.setOnClickListener {
            val name = binding.editStudentName.text.toString()
            CoroutineScope(Dispatchers.IO).launch {

                val results = myDao.getStudentByName(name) // 입력받은 이름으로 검색

                if (results.isNotEmpty()) {
                    val str = StringBuilder().apply {
                        results.forEach {student ->
                            append(student.id)
                            append("-")
                            append(student.name)
                        }
                    }
                    /*
                     * 데이터베이스에 대한 결과에 따라서 도는 루틴 자체가 별도의 코루틴 Thread에서 동작
                     * UI를 업데이트를 못 하기 때문에 Dispatchers.Main을 걸어서 UI를 업데이트
                     */
                    withContext(Dispatchers.Main) {
                        binding.textQueryStudent.text = str
                    }
                } else {
                    withContext(Dispatchers.Main) {
                        binding.textQueryStudent.text = ""
                    }
                }

            }
        }
        
    }
}

DAO

@Dao
interface MyDAO {
    @Insert(onConflict = OnConflictStrategy.REPLACE) // Insert, key 충돌이 나면 새 데이터로 교체
    suspend fun insertStudent(student: Student) // 값 추가

    @Query("SELECT * FROM student_table")
    fun getAllStudent(): LiveData<List<Student>> // LiveData 사용

    @Query("SELECT * FROM student_table WHERE name = :sname")
    suspend fun getStudentByName(sname: String): List<Student> // 이름으로 검색

    @Delete
    suspend fun deleteStudent(student: Student); // 값 삭제
}

Database

@Database(
    entities = [Student::class],
    exportSchema = false, version = 1
)
abstract class MyDatabase : RoomDatabase() {
    abstract fun getMyDao(): MyDAO

    companion object {
        private var INSTANCE: MyDatabase? = null
        private val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(db: SupportSQLiteDatabase) {
                //
            }
        }

        private val MIGRATION_2_3 = object : Migration(2, 3) {
            override fun migrate(db: SupportSQLiteDatabase) {
                db.execSQL("ALERT TABLE student_table ADD COLUMN last_update INTEGER")
            }
        }

        fun getDatabase(context: Context): MyDatabase {
            if (INSTANCE == null) {
                INSTANCE = Room.databaseBuilder(
                    context, MyDatabase::class.java, "school_database"
                )
                    .addMigrations(MIGRATION_1_2)
                    .build()
            }
            return INSTANCE as MyDatabase
        }
    }
}

Entity

@Entity(tableName = "student_table") // 테이블 이름을 student_table로 지정함
data class Student (
    @PrimaryKey @ColumnInfo(name = "student_id") // id, name은 student_id라는 이름으로 데이터베이스 테이블 안에 컬럼명으로 들어감
    val id: Int,
    val name: String
)

내일배움캠프를 수강하며 작성한 코드 입니다 🤓

profile
개발 공부 기록 🌱

0개의 댓글