<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" tools:context=".MainActivity">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content" android:orientation="vertical">
<EditText android:id="@+id/nameText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp" android:hint="Name"/>
<EditText android:id="@+id/ageText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp"
android:inputType="number" android:hint="Age"/>
<Button android:id="@+id/insertButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp"
android:text="Insert"
android:textAllCaps="false"/>
</LinearLayout>
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" android:weightSum="3">
<Button android:id="@+id/readButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Read"
android:textAllCaps="false"/>
<Button android:id="@+id/updateButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Update"
android:textAllCaps="false"/>
<Button android:id="@+id/deleteButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Delete" android:textAllCaps="false"/>
</LinearLayout>
<ScrollView android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:id="@+id/resultText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp" android:textSize="20dp"/>
</ScrollView>
</LinearLayout>
Sqlite를 사용하면 응용프로그램 내에 Database를 만들어서 TABLE을 통해 값들을 관리할 수 있습니다.
사용자의 이름, 나이를 입력받아 INSERT, READ, UPDATE, DELETE 하는 법을 알아봅시다.
activity_main.xml
이름, 나이를 입력할 수 있는 EditText와 각각의 기능을 수행하는 Button이 존재하고,
화면의 나머지 아래 영역은 ScrollView로 지정하여 READ를 수행한 결과값을 띄워줍니다.
activity_main.xml 에 다음과 같이 입력
User.kt
먼저 실질적으로 테이블 내에서 관리할 값인 이름, 나이, 그리고 고유 ID 값을 담고 있는 클래스를 만들어줍니다.
Kotlin에서는 기본 생성자에서 var property에 대해서 getter, setter를 지원하고
빈 생성자로 객체를 만들었을 때 지정해놓은 Default value가 들어가게 해줍니다.
class User (var name:String="",var age:Int=0){ var id:Int = 0 }
DataBaseHandler.kt
해당 클래스에서 기능별 메소드를 이용해 DB 작업을 수행합니다.
먼저 val property로 미리 사용될 네임 값들을 정해줍니다.
val DATABASE_NAME = "MyDB" val TABLE_NAME = "Users" val COL_NAME = "name" val COL_AGE = "age" val COL_ID = "id"
그리고 SQLiteOpenHelper Class를 상속받습니다.(context, DB_NAME, cursorFactory, version을 넘겨줍니다)
이후에 onCreate(),onUpgrade()메소드를 오버라이딩 해줘야 합니다.
onCreate() : 처음 만들어질 때 호출됨.
onUpgrade() : DB version이 바뀔 때 호출됨.
class DataBaseHandler(var context: Context) :SQLiteOpenHelper(context, DATABASE_NAME,null,1){ override fun onCreate(db: SQLiteDatabase?) { val createTable = "CREATE TABLE $TABLE_NAME ($COL_ID INTEGER PRIMARY KEY AUTOINCREMENT,$COL_NAME VARCHAR(50),$COL_AGE INTEGER)" db?.execSQL(createTable) } override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { } }
이제 각각 기능별로 function을 만들어 줍니다.
INSERT
parameter로 user 객체를 받고, DB를 수정하기 위해 writableDatabase를 가져오고 ContentValues를 통해 값을 key, value 쌍으로 put 해주고 insert() 함수를 실행시킨 결과를 받아 처리를 해줍니다.
fun insertData(user:User){ val db = this.writableDatabase val cv = ContentValues() cv.put(COL_NAME,user.name) cv.put(COL_AGE,user.age) val result = db.insert(TABLE_NAME,null,cv) if(result == (-1).toLong()) Toast.makeText(context,"Failed",Toast.LENGTH_LONG).show() else Toast.makeText(context,"Success",Toast.LENGTH_LONG).show() }
READ
추가된 레코드들을 list 형태로 return 해주는 함수입니다. 이번엔 readableDatabase를 참조해서 query 문을 정의한 뒤에 rawQuery() 함수의 결과값을 Cursor 형으로 받습니다.
이 Cursor를 통해 값을 조회할 수 있습니다. moveToFirst() 함수를 통해 Cursor의 위치를 처음으로 이동시키고 true 값일 시 do~While 문을 통해 list에 해당 레코드에 있는 data를 가져와서 추가시키는 작업을 합니다. 그리고 작업 후에는 Cursor 객체와 DB 객체를 close() 함수를 통해 닫아줘야 합니다.
fun readData():MutableList<User>{ val list :MutableList<User> = ArrayList() val db = this.readableDatabase val query = "Select * from $TABLE_NAME" val result:Cursor = db.rawQuery(query,null) if(result.moveToFirst()){ do { val user = User() user.id = result.getInt(result.getColumnIndex(COL_ID)) user.name = result.getString(result.getColumnIndex(COL_NAME)) user.age = result.getInt(result.getColumnIndex(COL_AGE)) list.add(user) }while (result.moveToNext()) }else Toast.makeText(context,"There is no data.",Toast.LENGTH_LONG).show() result.close() db.close() return list }
UPDATE
Update를 누르면 모든 레코드의 age 값을 +1 시키는 로직을 만들었습니다.
마찬가지로 result로 결과값을 가져와서 do~while 문을 통해 작업을 수행합니다.
update() 함수는 (TableName, ContentValues, colum, Array<String>)을 받습니다.
and 연산을 통해서 해당 레코드의 id와 name 필드에 해당하는 age 필드의 값을 +1 해줍니다. 마찬가지로 작업을 수행한 뒤에 close() 시켜줍니다.
fun updateData(){ val db = this.writableDatabase val query = "Select * from $TABLE_NAME" val result:Cursor = db.rawQuery(query,null) if(result.moveToFirst()){ do { val cv = ContentValues() cv.put(COL_AGE,result.getInt(result.getColumnIndex(COL_AGE))+1) db.update(TABLE_NAME,cv, "$COL_ID=? AND $COL_NAME=?", arrayOf(result.getString(result.getColumnIndex(COL_ID)), result.getString(result.getColumnIndex(COL_NAME)))) }while (result.moveToNext()) } result.close() db.close() }
DELETE
삭제 시에는 writableDatabase를 참조해서 delete() 함수를 호출해주면 됩니다.
delete() 함수는 인자로 (TableName, Colum, Array<String>)을 받습니다.
주석 구문처럼 조건을 걸어 특정 레코드를 삭제할 수도 있고,
2,3번째 인자에 null을 넣어주면 테이블 내의 레코드가 전체 삭제가 됩니다.
fun deleteData(){ val db = this.writableDatabase //db.delete(TABLE_NAME, "$COL_ID=?", arrayOf("1")) db.delete(TABLE_NAME, null,null) db.close() }
DataBaseHandler.kt 전체 소스입니다.
import android.content.ContentValues import android.content.Context import android.database.Cursor import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteOpenHelper import android.widget.Toast val DATABASE_NAME = "MyDB" val TABLE_NAME = "Users" val COL_NAME = "name" val COL_AGE = "age" val COL_ID = "id" class DataBaseHandler(var context: Context) :SQLiteOpenHelper(context, DATABASE_NAME,null,1){ override fun onCreate(db: SQLiteDatabase?) { val createTable = "CREATE TABLE $TABLE_NAME ($COL_ID INTEGER PRIMARY KEY AUTOINCREMENT,$COL_NAME VARCHAR(50),$COL_AGE INTEGER)" db?.execSQL(createTable) } override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { } fun insertData(user:User){ val db = this.writableDatabase val cv = ContentValues() cv.put(COL_NAME,user.name) cv.put(COL_AGE,user.age) val result = db.insert(TABLE_NAME,null,cv) if(result == (-1).toLong()) Toast.makeText(context,"Failed",Toast.LENGTH_LONG).show() else Toast.makeText(context,"Success",Toast.LENGTH_LONG).show() } fun readData():MutableList<User>{ val list :MutableList<User> = ArrayList() val db = this.readableDatabase val query = "Select * from $TABLE_NAME" val result:Cursor = db.rawQuery(query,null) if(result.moveToFirst()){ do { val user = User() user.id = result.getInt(result.getColumnIndex(COL_ID)) user.name = result.getString(result.getColumnIndex(COL_NAME)) user.age = result.getInt(result.getColumnIndex(COL_AGE)) list.add(user) }while (result.moveToNext()) }else Toast.makeText(context,"There is no data.",Toast.LENGTH_LONG).show() result.close() db.close() return list } fun updateData(){ val db = this.writableDatabase val query = "Select * from $TABLE_NAME" val result:Cursor = db.rawQuery(query,null) if(result.moveToFirst()){ do { val cv = ContentValues() cv.put(COL_AGE,result.getInt(result.getColumnIndex(COL_AGE))+1) db.update(TABLE_NAME,cv, "$COL_ID=? AND $COL_NAME=?", arrayOf(result.getString(result.getColumnIndex(COL_ID)), result.getString(result.getColumnIndex(COL_NAME)))) }while (result.moveToNext()) } result.close() db.close() } fun deleteData(){ val db = this.writableDatabase db.delete(TABLE_NAME, null,null) db.close() } }
MainActivity.kt
이제 DataBaseHandler 객체를 만들어 줍니다. Button에 따라 해당 기능에 맞는 메소드를 호출해주면 됩니다.
import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.widget.Toast import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { private val db = DataBaseHandler(this) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) insertButton.setOnClickListener { insert() } readButton.setOnClickListener { read() } updateButton.setOnClickListener{ db.updateData() read() } deleteButton.setOnClickListener{ db.deleteData() resultText.text="" } } private fun insert(){ if(nameText.text.toString().isNotEmpty() && ageText.text.toString().isNotEmpty()){ val user = User(nameText.text.toString(),ageText.text.toString().toInt()) db.insertData(user) }else{ Toast.makeText(this,"Please Fill All Data's",Toast.LENGTH_LONG).show() } } private fun read(){ val data : MutableList<User> = db.readData() if(data.isNotEmpty()) resultText.append("Read\n") for(i in 0 until data.size){ resultText.append("ID : ${data[i].id} NAME : ${data[i].name} AGE : ${data[i].age}\n") } } }
앱을 실행한 뒤에 {홍길동, 20}을 Insert 해준 뒤에 Read 해주고 {철수, 12}를 Insert 해준 뒤에 Read 해주고 Update를 한 결과입니다.
SQLite를 사용하는 방법 완료