[Android] 데이터 저장 - SQLiteDataBase (Kotlin)

hxeyexn·2023년 7월 5일
0
post-thumbnail

SQLite

SQLite란?

  • MySQL나 PostgreSQL와 같은 데이터베이스 관리 시스템이지만, 서버가 아니라 응용 프로그램에 넣어 사용하는 비교적 가벼운 DB이다

데이터베이스 프로그래밍이란?

  • 데이터베이스에 테이블을 만들고 SQL을 이용해 데이터를 삽입, 조회, 갱신, 삭제하는 방법이다


SQLiteDataBase

SQLiteDataBase란?

  • 안드로이드에서 사용하는 내장 데이터 베이스로 표준 SQL문을 사용하는 RDBMS(관계형 데이터 베이스)이다
  • MySQL과 유사한 문법을 사용하고 있다
  • 일반적인 RDBMS가 가지고 있는 기능을 가지고 있다

SQLiteOpenHelper

  • 안드로이드에서 SQLiteDataBase를 사용하려면 SQLiteOpenHelper를 상속받은 클래스를 만들어야 한다

DAO

  • Data Access Object
  • 데이터에 접근하기 위하여 사용하는 객체이다
  • CRUD
    • Create
    • Read : Read One(Read Condition) + Read All
    • Update
    • Delete


SQLiteDataBase 사용해보기 : 학생정보 저장해보기

💻 학생의 이름, 나이, 국어점수를 사용자로부터 입력받아 데이터베이스에 저장해보자

Part 1 : DBHelper.kt

1. SQLiteOpenHelper를 상속받은 DBHelper Class를 생성한다

class DBHelper(context: Context) : SQLiteOpenHelper(context, "Student.db", null, 1) {

}
  • Student.db : 사용할 데이터 베이스 파일의 이름
  • null : NullFactory, Null에 대한 처리를 어떻게 할 것인가.. ➡️ Null로 셋팅하면 된다
  • 1 : 버전

2. 클래스 생성하면 class DBHelper에 빨간줄이 뜬다 ➡️ 여기에 마우스를 올려 Implement members를 클릭하면 다음과 같이 코드가 변경된다

class DBHelper(context: Context) : SQLiteOpenHelper(context, "Student.db", null, 1) {
	override fun onCreate(db: SQLiteDatabase?) {
        TODO("Not yet implemented")
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        TODO("Not yet implemented")
    }
}
  • onCreate : 테이블을 생성하기 위해 호출되는 메서드
  • onUpgrade : 사용하는 DB 파일의 버전이 변경되었을 때 호출되는 메서드

3. 테이블의 구조를 정의한다

class DBHelper(context: Context) : SQLiteOpenHelper(context, "Student.db", null, 1) {

    override fun onCreate(db: SQLiteDatabase?) {

        // create table 테이블 이름
        // (컬럼이름 자료형 제약조건 ... )
        // 자료형 : 정수 - integer, 문자열 - text, 실수 - real, 날짜 - date
        // 제약조건 : 저장할 수 있는 값에 대한 조건
        // primary key : null을 허용하지 않고 중복된 값을 허용하지 않는다.
        // 각 행들을 개별적으로 구분할 수 있는 값을 저장하기 위해 사용한다.
        // autoincrement : 컬럼에 저장할 값을 지정하지 않으면 1부터 1씩 증가되는 값이 자동으로 저장한다.
        // not null : null 값을 허용하지 않는다. 즉, 개발자가 무조건 값을 정해줘야 한다.
        val sql = """create table StudentTable
            (idx integer primary key autoincrement,
            name text not null,
            age integer not null,
            korean integer not null)
        """.trimIndent()

		// 쿼리문을 수행한다
        db?.execSQL(sql)
    }

	// 부모의 생성자의 마지막에 넣어준 버전 번호가 데이터 베이스 파일에 기록 버전 보다 높을 때 호출된다.
    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        // 과거에 만들어진 테이블을 현재의 구조가 될 수 있도록 테이블을 수정하는 작업을 하면 된다.
        TODO("Not yet implemented")
    }

}

Part 2 : DAO.kt

1. DAO Class를 생성한다

class DAO {

}

2. CRUD 메서드를 작성한다

class DAO {
	
    companion object {
    
    	fun insertData() {
        	// Create
        }
        
        fun selectData() {
            // Read One(Read Condition)
        }
        
        fun selectAllData() {
        	// Read All
        }
        
        fun updateData() {
			// Update
		}
        
        fun deleteData() {
        	// Delete
        }
        
    }
    
}

3. CRUD 메서드 호출 시 동작할 코드를 각 메서드 내부에 작성한다

  • Create : insertData()
  • 저장
fun insertData(context: Context, data: StudentClass) {
	val sql = """insert into StudentTable
    	| (name, age, korean)
        | values(?, ?, ?)
    """.trimMargin()

	val arg1 = arrayOf(
    	data.name, data.age, data.korean
    )
    val sqliteDatabase = DBHelper(context)
    sqliteDatabase.writableDatabase.execSQL(sql, arg1)
    sqliteDatabase.close()
}
  • Read One(Read Condition) : selectData()
  • 조건에 맞는 행 하나를 가져온다
fun selectData(context: Context, idx: Int) : StudentClass {
	// 쿼리문
	val sql = "select * from StudentTable where idx = ?"
    // ?에 들어갈 값 (문자열 배열)
    val arg1 = arrayOf("$idx")

	// DB 오픈
	val dbHelper = DBHelper(context)
    // 쿼리 실행
    val cursor = dbHelper.writableDatabase.rawQuery(sql, arg1)
    cursor.moveToNext()

	// 컬럼의 이름을 지정하여 컬럼의 순서값을 가져온다.
    val idx1 = cursor.getColumnIndex("name")
    val idx2 = cursor.getColumnIndex("age")
    val idx3 = cursor.getColumnIndex("korean")

	// 데이터를 가져온다.
    val name = cursor.getString(idx1)
    val age = cursor.getInt(idx2)
    val korean = cursor.getInt(idx3)

	val studentClass = StudentClass(name, age, korean)

	dbHelper.close()

	return studentClass
}
  • Read All : selectAllData()
  • 모든 행을 가져온다
fun selectAllData(context: Context) : MutableList<StudentClass> {
	// 모든 행을 가져오는 쿼리문을 작성한다
	val sql = "select * from StudentTable"
    
    // DB 오픈
    val dbHelper = DBHelper(context)
    // 쿼리 실행
    val cursor = dbHelper.writableDatabase.rawQuery(sql, null)
    // cursor 객체에는 쿼리문에 맞는 행에 접근할 수 있는 객체가 된다.
    // 처음에는 아무 행도 가르치고 있지 않는다.
    // moveToNext 메서드를 호출하면 다음 행에 접근할 수 있다.
    // 이때 접근할 행이 있으면 true를 반환하고 없으면 false를 반환한다.

	val studentList = mutableListOf<StudentClass>()

	while (cursor.moveToNext()) {
    	// 컬럼의 이름을 지정하여 컬럼의 순서값을 가져온다.
        val idx1 = cursor.getColumnIndex("name")
        val idx2 = cursor.getColumnIndex("age")
        val idx3 = cursor.getColumnIndex("korean")

		// 데이터를 가져온다.
        val name = cursor.getString(idx1)
        val age = cursor.getInt(idx2)
        val korean = cursor.getInt(idx3)
        
        val studentClass = StudentClass(name, age, korean)
        studentList.add(studentClass)
    }

	dbHelper.close()

	return studentList
}
  • Update : updateData()
  • 조건에 맞는 행의 컬럼의 값을 수정한다
fun updateData(context: Context, obj: StudentClass) {
	val sql = """update StudentTable
    	| set name = ?, age = ?, korean = ?
        | where idx = ?
    """.trimMargin()

	val args = arrayOf(obj.name, obj.age, obj.korean, obj.idx)
    val dbHelper = DBHelper(context)
    dbHelper.writableDatabase.execSQL(sql, args)
    dbHelper.close()
}
  • Delete : deleteData()
  • 조건 맞는 행을 삭제한다
fun deleteData(context: Context, idx: Int) {
	val sql = "delete from StudentTable where idx = ?"
    val args = arrayOf(idx)
    val dbHelper = DBHelper(context)
    dbHelper.writableDatabase.execSQL(sql, args)
    dbHelper.close()
}

profile
Android Developer

0개의 댓글