본문 바로가기
개발

(21) 독학으로 앱 만들어보기 (코틀린 sqlite select)

by 라이프_디자이너 2023. 1. 23.
반응형

코틀린 sqlite select insert delete update을 적용한 내용을 설명한다. 지난 글에서 RecyclerView를 다뤘는데, 그 이후에 삘 받아서 개발을 많이 진행했다. 그동안 개발한 내용을 하나씩 설명해 본다. 이번 글에서는 코틀린 sqlite select insert 등 데이터 저장을 위해 필요한 db를 다루는 법을 알아보자.

 

 

2022.12.03 - [개발] - (17) 독학으로 앱 만들어보기 (개발 과정)

 

(17) 독학으로 앱 만들어보기 (개발 과정)

독학으로 앱 만들어보기 본격 코딩 시작. 지난 포스팅에 남겨놓은 의문점을 해결하는 과정을 담아보겠다. 목표 달성한 횟수를 어떻게 표시하지? 여태까지 몇 번 목표 달성했는지 누가 기억해주

dev-nasus.tistory.com

 

1. DB 생성 (SQLiteOpenHelper)

 

DB 사용을 위해서는 DB 생성 -> 테이블 생성 -> 데이터 저장,조회,삭제,업데이트 순서로 진행할 수 있다. 무조건 DB를 먼저 생성해야 하는데, SQLite는 SQLiteOpenHelper라는 이미 만들어진 클래스를 활용하여 DB를 생성한다. DB 생성에 필요한 코드다. 일부만 가져온 내용으로 중괄호 짝이 맞지 않아 그대로 복붙 하면 에러가 발생할 것이다.

 

DB생성
class DBHelper(
    val context: Context?,
) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
    companion object{
        const val DATABASE_VERSION = 1
        const val DATABASE_NAME = "COMETRUE"

        // Table
        const val TABLE_NAME = "GOAL"
        const val UID = "UID"
        const val COL_GOAL_CONTENT = "goalContent"
        const val COL_GOAL_COUNT = "goalCount"
        const val COL_IS_NOW_GOAL = "isNowGoal"
    }

클래스를 하나 만든다. 보통 DBHelper라고 많이들 사용한다. 왜 이렇게 사용하는지는 잘 모르겠지만, 내 생각에는 안드로이드 개발 1세대가 예제를 만들 때 DBHelper라고 만들어서 다들 그렇게 쓰는게 아닐까 싶다. 이 코드 또한 많은 구글링을 통해 여러 소스코드를 보고 마음에 드는 부분을 짬뽕시켜서 만든 코드다.

반응형

class의 인자로는 context 를 받고, 클래스 생성 후 반환하는 데이터 타입을 SQLiteOpenHelper로 지정한다. SQLiteOpenHelper 인자에는 contxt, DB이름, null, DB버전 이렇게 4개를 넣으면 된다.

 

여기서는 companion object 라는 명령어를 사용하여 전처리 단계에서 상수를 생성하게끔 하였다. 또한 변하지 않고 고정되는 상수, 문자열은 const 명령어를 사용해서 변수로 만들어 재사용성을 높였다. DB 이름은 COMTURE로 지정했고 DB버전은 그냥 1로 했다. 다른 숫자로 해도 된다. DB생성에 필요한 상수들 외에도 미리 정의해 두었다. 앞선 글에서 이미 어떤 데이터를 저장할지 설계해서 알고 있기 때문에 그걸 그대로 적어주면 된다. 참고로 상수는 모두 대문자로 하는 게 코딩 세상에 예의다. 이렇게 작성하고 메인 액티비티에서 아래처럼 클래스를 선언하면 DB가 생성된다.

class MainActivity : AppCompatActivity() {

    lateinit var goalListAdapter: GoalListAdapter
    lateinit var dbHelper : DBHelper
    lateinit var mContext: Context

    @RequiresApi(Build.VERSION_CODES.O)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.goal_list)
        mContext = this
        dbHelper = DBHelper(this)

 

2. Table 생성

DB를 만들었으니 그다음에는 Table을 생성해야 한다. Table을 만들 때는 저장하고자 하는 데이터들이 무엇인지 명확하게 알고 있어야 한다. 한번 정하면 나중에 수정하기 어렵기 때문에 처음에 잘해야 되는데.... 이게... 경험이 없으면 어렵다. 우선 되는대로 만들자. 보통 onCreate 함수에 Table 생성 코드를 작성한다. 왜냐하면, DB를 생성한 다음에는 무조건 테이블이 필요하기 때문에 데이터를 다루기 전에 맨 처음 호출되는 onCreate 함수를 활용한다.

 

Table 생성
    override fun onCreate(db: SQLiteDatabase) {
        val sql: String = "CREATE TABLE IF NOT EXISTS " +
                "$TABLE_NAME ($UID integer primary key autoincrement, " +
                "$COL_GOAL_CONTENT text, $COL_GOAL_COUNT text, $COL_IS_NOW_GOAL integer);"
        db.execSQL(sql)
    }

sql이라는 문자열 변수를 만들었고, 내용을 한글로 해석해 보면 $TABLE_NAME이라는 이름을 가진 테이블이 없으면 테이블을 만들어라. 테이블을 만들 때, 테이블의 데이터 항목들은 $UID, $COL_GOAL_CONTENT, $COL_GOAL_COUNT, $COL_IS_NOW_GOAL이다. 각 항목들은 위에 DB 생성할 때 이미 정의해 두었다. 그리고 각 데이터 항목들의 데이터 타입이 있는데 문자열(text)이나 정수(integer)다. UID의 경우에는 데이터마다 고유한 값을 지정해서 구분하기 위한 용도로 중요한 키(primary key)로 지정하고 테이블에 데이터가 추가되면 자동으로 번호를 증가(autoincrement)시켜라.

 

이렇게 sql 문자열을 만들고 인자에 들어있는 SQLiteDatabase 변수 db를 통해 db.execSQL(sql)로 실행시키면 된다.

        // Table
        const val TABLE_NAME = "GOAL"
        const val UID = "UID"
        const val COL_GOAL_CONTENT = "goalContent"
        const val COL_GOAL_COUNT = "goalCount"
        const val COL_IS_NOW_GOAL = "isNowGoal"

 

3. 데이터 조회, 저장, 삭제, 수정

 

DB와 테이블을 생성했으니 이제 데이터 조회, 저장, 삭제, 수정이 가능하다. SQL 쿼리를 직접 작성하는 방식이 있고 SQLite에서 제공하는 함수를 사용하는 방법이 있는데, 더 멀리 생각했을 때는 SQL 쿼리에 익숙해지는 게 좋을 거 같아서 SQL로 코딩했다.

 

  • select (조회) : select 조회할 데이터 항목 명 from 테이블명 where 조건;
    ※ select uid, data from table_name where uid>10;
  • insert (저장) : insert into 테이블명(데이터 항목 1, 데이터 항목 2...) values("데이터 1", "데이터 2...");
    ※ insert into table_name(uid, data) values(10, "sample_data");
  • delete (삭제) : delete from 테이블명 where 조건;
    ※ delete from table_name where uid=10;
  • update (수정) : update 테이블명 set 변경할 데이터 항목=변경할 데이터 where 조건;
    ※ update table_name set uid=11, data="update data" where uid=10;

 

SQL은 위와 같이 작성하면 되고, 쿼리를 실행시키는 방법은 writeableDatabase 변수를 만들고 쿼리 실행. 코드로 구현한 내용은 아래와 같다. select 조회한 데이터의 경우에는 여러 개 일 수 있으니 @SuppressLint("Range") 어노테이션을 사용한다. 해당 어노테이션이 무엇인지는 추가로 공부해봐야 한다.

    fun insertGoal(goalData: GoalData){
        val db = this.writableDatabase
        val data = "'"+goalData.goalContent + "',"+goalData.goalCount+","+goalData.isNowGoal
        var query = "INSERT INTO $TABLE_NAME($COL_GOAL_CONTENT , $COL_GOAL_COUNT , $COL_IS_NOW_GOAL) " + "values("+data+");"
        db.execSQL(query)
    }

    fun deleteGoal(goalData: GoalData){
        val db = this.writableDatabase
        val query = "DELETE FROM $TABLE_NAME where uid="+goalData.uid+";"
        db.execSQL(query)
    }

    fun updateGoal(goalData: GoalData){
        val db = this.writableDatabase
        val query = "UPDATE $TABLE_NAME SET $COL_GOAL_COUNT="+goalData.goalCount+" where uid="+goalData.uid+";"
        db.execSQL(query)
    }


    @SuppressLint("Range")
    fun selectGoals() : MutableList<GoalData>
    {
        val dataList = mutableListOf<GoalData>()
        val db = this.writableDatabase

        var query = "SELECT $UID, $COL_GOAL_CONTENT , $COL_GOAL_COUNT , $COL_IS_NOW_GOAL FROM $TABLE_NAME;"
        var data = db.rawQuery(query,null)

        while(data.moveToNext()){
            val uid = data.getInt(data.getColumnIndex(UID))
            val goalContent = data.getString(data.getColumnIndex(COL_GOAL_CONTENT))
            val goalCount = data.getInt(data.getColumnIndex(COL_GOAL_COUNT))
            val isNowGoal = data.getInt(data.getColumnIndex(COL_IS_NOW_GOAL))

            dataList.add(GoalData(uid,goalContent,goalCount,isNowGoal))
        }

        return dataList
    }

다음 글에는 추가할 데이터를 입력받는 입력 창을 만드는 법에 대해 작성해 본다.

반응형

댓글