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
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(
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(tableName = "student_table") // 테이블 이름을 student_table로 지정함
data class Student (
@PrimaryKey @ColumnInfo(name = "student_id") // id, name은 student_id라는 이름으로 데이터베이스 테이블 안에 컬럼명으로 들어감
val id: Int,
val name: String
)
내일배움캠프를 수강하며 작성한 코드 입니다 🤓