val pref = activity?.getSharedPreferences(
getString(R.string.string1), Context.MODE_PRIVATE
)
val edit = pref.edit() // 위의 pref를 수정할 때 사용한다.
edit.putString("", "") // 1번째는 key값, 2번째는 실제 저장할 값
edit.apply() // 수정 완료
binding.tvText.text = pref.getString("", "") // 1번째는 key값, 2번째는 null 시에 불러올 값
plugins {
....
id 'kotlin-kapt'
}
.....
dependencies {
......
def room_version = "2.5.1"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
kapt "androidx.room:room-compiler:$room_version"
// optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
// optional - Test helpers
testImplementation "androidx.room:room-testing:$room_version"
}
@Entity(tableName = "student_table") // 테이블 이름을 student_table로 지정함
data class Student (
@PrimaryKey
@ColumnInfo(name = "student_id")
val id: Int,
val name: String
)
CREATE TABLE table_name (table_id INTEGER PRIMARY KEY, name TEXT NOT NULL);
@Dao
interface MyDAO {
@Insert(onConflict = OnConflictStrategy.REPLACE) // INSERT, key 충돌이 나면 새 데이터로 교체
suspend fun insertStudent(student: Student)
@Query("SELECT * FROM student_table")
fun getAllStudents(): LiveData<List<Student>> // LiveData<> 사용 (코루틴 필요x)
@Query("SELECT * FROM student_table WHERE name = :sname")
suspend fun getStudentByName(sname: String): List<Student>
@Delete
suspend fun deleteStudent(student: Student); // primary key is used to find the student
// ...
}
@Database(entities = [Student::class, ClassInfo::class, Enrollment::class, Teacher::class], 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(database: SupportSQLiteDatabase) { 생략 }
}
private val MIGRATION_2_3 = object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) { 생략 }
}
fun getDatabase(context: Context) : MyDatabase {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(
context, MyDatabase::class.java, "school_database")
.addMigrations(MIGRATION_1_2, MIGRATION_2_3)
.build()
}
return INSTANCE as MyDatabase
}
}
}
Room.databaseBuilder(...).addMigrations(MIGRATION_1_2, MIGRATION_2_3)
private val MIGRATION_1_2 = object : Migration(1, 2) { // version 1 -> 2
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE student_table ADD COLUMN last_update INTEGER")
}
}
private val MIGRATION_2_3 = object : Migration(2, 3) { // version 2 -> 3
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE class_table ADD COLUMN last_update INTEGER")
}
}
myDao = MyDatabase.getDatabase(this).getMyDao()
runBlocking { // (주의) UI를 블록할 수 있는 DAO 메소드를 UI 스레드에서 바로 호출하면 안됨
myDao.insertStudent(Student(1, "james")) // suspend 지정되어 있음
}
val allStudents = myDao.getAllStudents() // LiveData는 Observer를 통해 비동기적으로 데이터를 가져옴
val allStudents = myDao.getAllStudents()
allStudents.observe(this) { // Observer::onChanged() 는 SAM 이기 때문에 lambda로 대체
val str = StringBuilder().apply {
for ((id, name) in it) {
append(id)
append("-")
append(name)
append("\n")
}
}.toString()
binding.textStudentList.text = str
}
오늘은 팀 편성이 새로 됐다. 발제를 새로 했다는 것이다. 핀볼을 돌렸는데 내가 팀장이 되었다.
언젠가는 내가 팀장이 걸릴 수도 있겠다고 생각은 했는데 이게 이번일 줄은 몰랐다.
어쨌거나 이왕 팀장이 된 거 조금 적극적으로 임해보기로 했다.
팀원분들도 다들 협조적으로 응해주셔서 팀 규칙도 원활하게 짤 수 있었다.
그래서 오랜만에 TIL도 작성하게 됐다. 내일부터는 알고리즘 문제도 오랜만에 풀어보기로 했다.
한동안 해이해졌던 마음을 다잡고 열심히 해봐야겠다.
이번 주차도 화이팅이다.