본문 바로가기

Programming/Android

안드로이드 kotlin + sqLite 사용 예제

<?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

parameteruser 객체를 받고, 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 연산을 통해서 해당 레코드의 idname 필드에 해당하는 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를 사용하는 방법 완료 

 

참조 : m.blog.naver.com/PostView.nhn?blogId=sgepyh2916&logNo=221423213160&proxyReferer=https:%2F%2Fwww.google.com%2F

728x90