[안드로이드] 로컬 DB 연동

Junyoung Park·2021년 12월 31일
1

ToyProject

목록 보기
2/11

SQLite

퀴즈 어플에 사용할 기출 문제를 데이터베이스를 통해 활용하기 위해 "어떤 데이터베이스를 사용할지" 결정해야 했다. PostgreSQL 등 다른 선택지도 있었지만, 안드로이드 환경에서 가장 편리하고 구현이 간단한 SQLite를 사용하기로 했다.

총 5개*100=500개의 문제를 입력해야 하는데, 데이터베이스를 작성하는 데에만 시간이 다소 걸릴 것 같다. 단순히 문제를 복사/붙여넣기 하는게 아니라, 문제 채점 이후 보여줄 view에서 문제 및 보기 해설 정보를 담을 값을 찾아서 입력해야 했기 때문이다.

일단, 테스트 케이스로 한 회차의 문제(즉 100문제)만을 다루기로 해보자(내일의 내가 모든 문제를 다 입력했으리라고 믿는다...). 즉 db 파일을 어플을 최초로 실행할 때 내부 데이터베이스로 로드한 뒤 사용할 것이다. 외부 데이터베이스 등을 활용할 수도 있지만, 구현하려는 어플 기능 상 간단한 기출 문제만 SELECT하는 게 기능의 대부분인지라 로컬 데이터베이스를 활용하는 게 편할 것 같았다.

assets → db

업로드 시 로컬 데이터베이스를 활용하는 방법은 다음과 같다.

  • create 시 db 경로에 db가 있는지 init으로 확인한다.
  • 없다면 어플을 처음 구동한 경우이므로 assets 내의 db를 복사/입력한다.
  • 있다면 이미 존재하므로 기능하지 않는다.
    init {
        val dbExist = checkDatabase()
        if (dbExist) {
            Log.d("dbCheck", "Database exist")
        } else {
            Log.d("dbCheck", "Database doesn't exist")
            createDatabase()
        }
    }

createDatebase() 함수는 File 입출력과 마찬가지로 inputStream과 outputStream을 사용해 붙여넣기 한다. 결과적으로 SQLiteDatabase가 관리하는 데이터베이스 폴더 내에는 assets에 초기값으로 로드한 데이터베이스 복사본이 자리 잡게 된다!

db → main

db로 업로드된 데이터베이스 활용은 일반적인 SQLite 함수 사용과 동일하다. 본 어플에서는 test_num(몇 회 차 문제인가?), type(어떤 유형인가?)에 따라 퀴즈 문제를 SELECT하고 이를 각 question1, question2 클래스의 리스트에 담아내 return하는 게 주요 기능이다.

    fun get_question1(test_num:Int, type:Int): MutableList<question1>{
        openDatabase()
        val query:String = "SELECT * FROM question1 WHERE question1.test_num = ${test_num} AND question1.type = ${type};"
        val cursor = dataBase?.rawQuery(query,null)
        cursor?.moveToFirst()
        val list = mutableListOf<question1>()
        do {
            val test_num = cursor?.getInt(0)
            val number = cursor?.getInt(1)
            val type = cursor?.getInt(2)
            val question = cursor?.getString(3)
            val question_detail = cursor?.getString(4)
            val answer = cursor?.getInt(5)
            val choice1 = cursor?.getString(6)
            val choice1_detail = cursor?.getString(7)
            val choice2 = cursor?.getString(8)
            val choice2_detail = cursor?.getString(9)
            val choice3 = cursor?.getString(10)
            val choice3_detail = cursor?.getString(11)
            val choice4 = cursor?.getString(12)
            val choice4_detail = cursor?.getString(13)
            list.add(question1(test_num, number, type, question, question_detail, answer, choice1, choice1_detail, choice2, choice2_detail,
                choice3, choice3_detail, choice4, choice4_detail))
        } while (cursor?.moveToNext() == true)
        cursor?.close()
        close()
        return list
    }

question1은 간단한 유형의 문제로 각 튜플이 문제와 문제 정보, 보기와 보기 정보를 모두 가지고 있기 때문에 한꺼번에 리스트로 만들어 return한다. rawQuery를 통해 편하게 SELECT할 수 있는데, 이후 유형별/기출별 문제 등 필요에 따른 다른 조회가 생길 때에는 함수 조건을 변경해 다양하게 사용할 예정이다. 위 코드는 가장 기본적인 형태의 문제를 반환하는 경우이다.

  • 이렇게 assets의 db 파일을 로컬로 옮기고 이를 활용하기까지 했다. 이제 본격적인 xml 레이아웃을 설계한 뒤 버튼을 통해 문제를 표시하고 채점하는 기능을 만들어보자.

그럼... 나중에 만나요!

profile
JUST DO IT

0개의 댓글

관련 채용 정보