1.  SQLite 프로그래밍

안드로이드에서 사용하는 SQLite는 관계형 데이터베이스

 

1) 안드로이드 앱 개발을 위한 SQLite 동작 방식

 

 

  🐰  안드로이드 앱에서 SQLite를 사용할 때는 일반적으로 SQLiteOpenHelper 클래스, SQLiteDatabase 클래스, Cursor 인터페이스를 이용

 

 

 

 

 

  • SQLiteOpenHelper 클래스를 상속받아 새로운 클래스를 생성
  • 생성한 클래스에는 데이터베이스 파일과 테이블을 생성하는 내용을 코딩 
  • SQLiteOpenHelper 클래스의 getWritableDatabase()를 사용하면 SQLiteDatabase를 반환받고execSQL() 또는 rawQuery() 등으로 SQL문을 실행 
  • 특히 SELECT문은 Cursor 인터페이스를 반환받은 후에 반복해서 테이블의 행 데이터에 접근

각 클래스에서 자주 사용되는 메서드
클래스 또는 인터페이스 메서드 주요 용도
SQLiteOpenHelper 클래스 생성자 DB 생성
  onCreate() 테이블 생성
  onUpgrade() 테이블 삭제 후 다시 생성
  getReadableDatabase() 읽기 전용 DB 열기. SQLiteDatabase 반환
  getWritableDatabase() 읽고 쓰기용 DB 열기. SQLiteDatabase 반환
SQLiteDatabase 클래스 execSQL() SQL문 (insert / update / delete) 실행
  close() DB 닫기
  query(), rawQuery() select 실행 후 커서 반환
Cursor 인터페이스 moveToFirst() 커서의 첫 행으로 이동
  moveToLast() 커서의 마지막 행으로 이동
  moveToNext() 현재 커서의 다음 행으로 이동

 


2.  가수 그룹의 이름과 인원을 데이터베이스에 입력하고 조회하는 응용 프로그램 작성

xml 코드

 

바깥 리니어 레이아웃 안에 리니어레이아웃(수평) 4개를 만들고 다음과 같이 화면 구성.
리니어 레이아웃 1 ~ 3은 layout_weight를 1로, 리니어 레이아웃 4는 8로 설정.

  • 리니어 레이아웃 1 : 텍스트뷰 1개, 에디트 텍스트 1개 (editName)
  • 리니어 레이아웃 2 : 텍스트뷰 1개, 에디트 텍스트 1개 (editNumber)
  • 리니어 레이아웃 3 : 버튼 3개 (btnInit, btnInsert, btnSelect)
  • 리니어 레이아웃 4 : 에디트 텍스트 2개 (editNameResult, editNumberResult)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/layout01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="이름"
            android:textSize="20dp"/>

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/editName" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/layout02"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="인원"
            android:textSize="20dp"/>

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/editNumber" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/layout03"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="horizontal"
        android:gravity="center_horizontal">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="10dp"
            android:text="초기화"
            android:id="@+id/btnInit" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="10dp"
            android:text="입력"
            android:id="@+id/btnInsert" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="조회"
            android:id="@+id/btnSelect" />


    </LinearLayout>

    <LinearLayout
        android:id="@+id/layout04"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_weight="8"
        android:gravity="center_vertical"
        android:background="#FBF4D1">

        <EditText
            android:id="@+id/editNameResult"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"/>

        <EditText
            android:id="@+id/editNumberResult"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"/>

    </LinearLayout>

</LinearLayout>

 


MainActivity
class MainActivity : AppCompatActivity() {
    lateinit var myHelper: MyDBHelper
    lateinit var editName: EditText
    lateinit var editNumber: EditText
    lateinit var editNameResult: EditText
    lateinit var editNumberResult: EditText
    lateinit var btnInit: Button
    lateinit var btnInsert: Button
    lateinit var btnSelect: Button
    lateinit var sqlDB: SQLiteDatabase

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setTitle("가수 그룹 관리 DB")

        editName = findViewById(R.id.editName)
        editNumber = findViewById(R.id.editNumber)
        editNameResult = findViewById(R.id.editNameResult)
        editNumberResult = findViewById(R.id.editNumberResult)

        btnInit = findViewById(R.id.btnInit)
        btnInsert = findViewById(R.id.btnInsert)
        btnSelect = findViewById(R.id.btnSelect)

        myHelper = MyDBHelper(this)

        btnInit.setOnClickListener {
            sqlDB = myHelper.writableDatabase
            myHelper.onUpgrade(sqlDB, 1, 2)
            sqlDB.close()
        }

        btnInsert.setOnClickListener {
            sqlDB = myHelper.writableDatabase
            sqlDB.execSQL("INSERT INTO `groupTBL` VALUES ('${editName.text.toString()}', " +
                    "${editNumber.text.toString()});")
            sqlDB.close()
            Toast.makeText(applicationContext, "입력됨", Toast.LENGTH_SHORT).show()
        }

        btnSelect.setOnClickListener {
            sqlDB = myHelper.writableDatabase
            val cursor: Cursor
            cursor = sqlDB.rawQuery("SELECT * FROM groupTBL;", null)

            var names = "그룹이름 \r\n ---------- \r\n"
            var numbers = "인원 \r\n ---------- \r\n"

            while(cursor.moveToNext()) {
                names += cursor.getString(0) + "\r\n"
                numbers += cursor.getString(1) + "\r\n"
            }

            editNameResult.setText(names)
            editNumberResult.setText(numbers)

            cursor.close()
            sqlDB.close()
        }
    }

    inner class MyDBHelper(context: Context): SQLiteOpenHelper(context, "groupDB", null, 1) {
        override fun onCreate(db: SQLiteDatabase?) {
            db!!.execSQL("CREATE TABLE `groupTBL`(`gName` CHAR(20) PRIMARY KEY, `gNumber` INTEGER);")
        }

        override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
            db!!.execSQL("DROP TABLE IF EXISTS `groupTBL`;")
            onCreate(db)
        }
    }
}

 

onCreate() 메서드 밖에 SQLiteOpenHelper 클래스에서 상속받는 내부 클래스를 정의한 후 생성자를 수정

 

inner class MyDBHelper(context: Context): SQLiteOpenHelper(context, "groupDB", null, 1) {}

 

super의 두 번째 파라미터에는 새로 생성될 데이터베이스의 파일명을 지정
마지막 파라미터는 데이터베이스 버전으로 처음에는 1을 지정


MyDBHelper 클래스의 onCreate()와 onUpgrade() 메서드를 코딩
override fun onCreate(db: SQLiteDatabase?) {
    db!!.execSQL("CREATE TABLE `groupTBL`(`gName` CHAR(20) PRIMARY KEY, 
        `gNumber` INTEGER);")

}


  테이블을 생성하는 SQL문.
  onUpgrade()에서 호출되거나 데이터를 입력할 때 혹은 테이블이 없을 때 처음 한 번 호출.

override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
    db!!.execSQL("DROP TABLE IF EXISTS `groupTBL`;")
    onCreate(db)
}

 

  테이블을 삭제하고 새로 생성. 초기화 할 때 호출

 


초기화 버튼를 클릭했을 때 동작하는 리스너 코딩
myHelper = MyDBHelper(this)


  생성자가 실행되어 groupDB 파일이 생성

sqlDB = myHelper.writableDatabase
myHelper.onUpgrade(sqlDB, 1, 2)
sqlDB.close()


  groupDB를 쓰기용 데이터베이스로 열고, onUpgrade() 메서드를 호출. groupTBL 테이블이 있으면 삭제한 후 새로 생성. 이후 데이터베이스를 닫음.
  onUpgrade()의 두번째 파라미터에는 이전 버전을, 세 번째 파라미터는 새버전을 입력하는데 파라미터를 받은 다음 사용하지 않았으므로 아무 숫자나 넣어도 됨.


입력 버튼를 클릭했을 때 동작하는 리스너 코딩

 

sqlDB = myHelper.writableDatabase


  groupDB를 쓰기용으로 열기

 

sqlDB.execSQL("INSERT INTO `groupTBL` VALUES ('${editName.text.toString()}'," +
    " ${editNumber.text.toString()});")

 

  insert 문을 생생 후 execSQL() 메서드로 실행


조 버튼를 클릭했을 때 동작하는 리스너 코딩
while (cursor.moveToNext()) {
    names += cursor.getString(0) + "\r\n"
    numbers += cursor.getString(1) + "\r\n"
}


  행 데이터의 개수만큼 반복. moveToNext() 메서드는 커서 변수의 다음 행으로 넘어감.
  만약 다음행이 없다면 false를 반환하여 while문이 끝남.
  getString(열번호)는 현재 커서의 열 번호 데이터 값을 반환하여 문자열 변수에 계속 누적.
  0은 0번째 열 (그룹이름 열), 1은 1번째 열(인원).

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]

+ Recent posts