[Android/Kotlin] SQLite

2023. 9. 25. 00:06·App&Web/Android

학교 모바일 응용 수업 복습

 

 

SQLite

클라이언트 어플리케이션에 주로 사용하는 경량 내장형 DBMS

  • 관계형 데이터베이스
  • http:///www.sqlite.org
  • 안드로이드, iOS, 그리고 웹 브라우저 등에서 사용 
    → 안드로이드 경우 프레임워크에 기본 내장

 

기기에 자료를 영구적으로 저장해야할 경우 적용

  • 휴대폰 내부에 파일로 DB가 만들어짐
  • 라이브러리 형태로 호출하여 사용 (클래스 import)

DB 사용 절차

 

SQLiteOpenHelper 상속 클래스 작성 → helper 객체 생성 → helper를 사용하여 SQLiteDatabase 객체 획득 → SQLiteDatabase 객체를 사용하여 Query 수행 → helper 객체 (및 관련 객체) Close 수행

 

1. SQLiteOpenHelper 상속 클래스 작성

class MyDBHelper: SQLiteOpenHelper ( ... ) {
	MyDBHelper()	// 생성자
    onCreate()		// 테이블 생성
    onUpgrade()		// DB 수정이 필요한 경우
}
  • DB를 관리하는 클래스
  • :SQLiteOpenHelper 안받아도 되지만 도움받으면 편함

 

 

2. helper 객체 생성

val helper = MyDMHelper ( ... )

 

 

3. helper를 사용하여 SQLiteDatabase 객체 획득

val writableDB = helper.writableDatabase	// 쓰기 전용
// insert, update, delete
val readableDB = helper.readableDatabase 	// 읽기 전용
// select
  • SQLiteDabase는 실제 DB를 의미

 

 

4. SQLiteDabase 객체를 사용하여 Query 수행

  • 메소드 사용 방식
writableDB.insert()		// 자료 저장 시
writableDB.update() 	// 자료 수정 시
writableDB.delete() 	// 자료 삭제 시
writableDB.query()	 	// 자료 검색 시

 

  • SQL 문 직접 작성 방식
writableDB.execSQL() 	// insert, update, delete 사용 시
writableDB.rawQuery() 	// select 사용 시

 

* 필요에 따라 선택

 

 

5. helper 객체 (및 관련 객체) Close 수행

helper.close()
// Cursor 를 사용하였을 경우 Cursor.close() <=- select 사용 시

 


SQLiteOpenHelper

 

데이터베이스를 편리하게 사용할 수 있도록 도와주는 클래스 → 상속하여 사용

  • 데이터베이스 저장 파일 생성. DB 없으면 알아서 만들어줌
  • 테이블 생성
  • 테이블 업그레이드, 기본 샘플 데이터 추가 등
  • SQLiteDatabase 객체 제공

 

필수 재정의 메소드

  • 생성자 : 사용할 DB 파일 명 및 DB 버전을 지정
  • onCreate()
    • 사용할 테이블을 SQL을 사용하여 생성
    • 샘플이 필요할 경우 테이블 생성 후 샘플 추가 문장 작성
  • onUpgrade()
    • 데이블 구조를 변경해야 할 필요가 있을 때 사용
    • 특별히 재정의하지 않아도 무방

 


 

SQLiteOpenHelper 상속 클래스 작성

 

FoodDBHelper 전체 코드

class FoodDBHelper (context: Context?) : SQLiteOpenHelper(context, DB_NAME, null, 1) {
	val TAG = "FoodDBHelper"
    
    companion object {
    	const val DB_NAME = "food_db"
        const val TABLE_NAME = "food_table"
        const val COL_FOOD = "food"
		const val COL_COUNTRY = "country"
    }
    
	override fun onCreate(db: SQLiteDabase?) {
    	val CREATE_TABLE = 
        	"CREATE TABLE ${TABLE_NAME} (${BaseColumns._ID} INTEGER PRIMARY KEY AUTOINREMENT, " + 
            "${COL_FOOD} TEXT, ${COL_COUNTRY} TEXT }"
        Log.d(TAG, CREATE_TABLE)
        db?.execsQL(CREATE_TABLE)
	} 
    
    override fun onUpgrade(db: SQLiteDatabase?, oldVer: Int, newVer: Int) {
    	val DROP_TABLE = "DROP TABLE IF EXISTS ${TABLE_NAME}"
        db?.execSQL(DROP_TABLE)
        onCreate(db)
    }
}

 

1. SQLiteOpenHelper 상속

- 매개 변수 : context, DB 명, cursorFactory, DB ver.

class FoodDBHelper (context: Context?) : SQLiteOpenHelper(context, DB_NAME, null, 1//← 얘 바꾸면 onUpgrade()) {

 

 

2. DB 및 테이블, 테이블 컬럼명 등을 companion object로 생성하여 보관

→ 해당 항목명의 사용 일관성을 위해

 - ex ) FoodDBHelper.TABLE_NAME

// companion은 static을 대체
	companion object {
    	const val DB_NAME = "food_db"
        const val TABLE_NAME = "food_table"
        const val COL_FOOD = "food"
		const val COL_COUNTRY = "country"
    }

 

3. 최초로 readableDatabase 또는 writableDatabase 사용시 호출

 - DB의 테이블 생성 및 필요시 샘플 데이터 추가

// db: SQLiteDabase? -> null일 수도 있는 객체임
	override fun onCreate(db: SQLiteDabase?) {

 

4. BaseColumns 인터페이스의 _ID 속성(i_d) 지정

→ 다른 안드로이드 요소에서 필요한 경우가 있음

		val CREATE_TABLE = 	// 테이블 새로 만듦
        					 // _ID == '_id' 
                                                // 안드로이드 항상 primary key는 _ID로 하자(약속) -> 외부에서 쉽게 파악. 필수x 권장o
        	"CREATE TABLE ${TABLE_NAME} (${BaseColumns._ID} INTEGER PRIMARY KEY AUTOINREMENT, " + 
            "${COL_FOOD} TEXT, ${COL_COUNTRY} TEXT }"
        Log.d(TAG, CREATE_TABLE)
        db?.execsQL(CREATE_TABLE)

 

5. 새로운 버전의 DB를 사용할 필요가 있을 때 사용

 - 버전 같음 → 실행x

 - 버전 다름 → 실행o

							 // oldVer이 1임
	override fun onUpgrade(db: SQLiteDatabase?, oldVer: Int, newVer: Int) {
    	val DROP_TABLE = "DROP TABLE IF EXISTS ${TABLE_NAME}"
        db?.execSQL(DROP_TABLE)
        onCreate(db)
    }

 


Helper 객체 생성

DB 사용 부분에서 객체 생성

 

Helper 객체 생성 시의 동작

  • 생성자에 의해 DB파일이 안드로이드 내부저장소에 생성
  • 실기기는 보안 문제로 폴더 외부 접근이 안되므로 에뮬레이터 상에서만 확인 가능
  • [Device File Explorer] 사용
    • 에뮬레이터 선택 후 [File Explorer] 선택

 


SQLiteDabase

Helper 클래스에 의해 관리되는 데이터베이스 클래스

  • DB 작업 Query를 수행

 

Helper 클래스를 사용하여 획득

  • 읽기 전용 (select)
val myDB : SQLiteDatabase = myDBHelper.readableDatabase
  • 읽기/쓰기 겸용 (select/update/delete)
val myDB : SQLiteDatabse = myDBHelper.writableDatabase

 

SQL을 직접 사용하거나 관련 메소드를 사용하여 Query 수행

 

모든 작업 수행 후 helper 객체를 통해 반드시 close()하여 종료

 


SQLiteDatabase Query

 

데이터 삽입

Query 전용 함수 사용 or SQL 사용

  • 전용 함수 사용은 Content Provider 사용과 동일

 

데이터 삽입 - insert() or execSQL()

  • ContentValues 객체 생성 후 입력할 데이터 값 설정 후 insert() 사용 
    → 반환값이 있으므로 삽입 결과 확인 가능
  • execSQL()를 사용하여 SQL 직접 작성 후 수행
  • 수행 완료 후 helper.close() 호출

 

  • 전용함수 사용 방식
// helper는 FoodDBHelper 객체
val db = helper.writableDatabase
val newRow = ContentValues()	// insert할 내용물 저장
newRow.put("food", "된장찌개")	// id는 autoinrement니까 빼고 함
newRow.put("country", "한국")
db.insert("food_table", null, newRow)
helper.close()
  • SQL 직접 사용방식
// 방법 1 - 문자열 표시 시 '' 사용 주의
db.execSQL("INSERT INTO food_table " + 
	"VALUES (NULL, '된장찌개', '한국')")
    
// 방법 2 - 매개변수 결합 방식, execSQL(sql, 매개변수 배열)
db.execSQL("insert into ${FoodDBHelper.TABLE_NAME} " +
	"value (null, ?, ?)", arrayOf("된장찌개", "한국"))

 

 

데이터 수정

데이터 수정 - update() or execSQL()

  • ContentValues 객체에 변경할 값 및 조건 설정 후 update() 사용
  • execSQL() 메소드를 사용하여 SQL 직접 작성 후 수행

 

  • 전용함수 사용방식
val db = helper.writableDatabase
val newRow = ContentValues()	
newRow.put("country", "한국")
val whereClause = "food_?"	// 수정할 row 검색 조건 - 여러 개일 경우 A=? and B=?
val whereArgs = arrayOf("된장찌개")
db.update("food_table", updateRow, whereClause, whereArgs)
helper.close()
  • SQL 직접 사용 방식
db.execSQL("UPDATE food_table " +
	" SET country='한국' WHERE food='된장찌개'")

 

 

데이터 삭제

데이터 삭제 - delete() or execSQL()

  • 삭제대상 검색 조건 지정 후 delete() 수행
  • execSQL 메소드를 사용하여 SQL 직접 작성 후 수행

 

  • 전용함수 사용방식
val db = helper.writableDatabase
val whereClause = "food_?"	
val whereArgs = arrayOf("된장찌개")
db.delete("food_table", whereClause, whereArgs)
helper.close()
  • SQL 직접 사용방식
  •  
db.execSQL("DELETE FROM food_table WHERE food='된장찌개'")

 

 

 

데이터 검색

데이터 검색 - query() or rawQuery()

  • 조건문 지정 후 query() 수행
  • rawQuery 메소드를 사용하여 SQL 직접 수행
  • Cursor(데이터 반환 집합에 대한 레퍼런스) 값을 반환
  • 사용 후 Helper 및 Cursor는 반드시 close() 적용

 

  • 전용함수 사용방식
val db = helper.readableDatabase	// 읽기 전용 사용 가능
val columns = arrayOf("_id", "food", "country")	// 검색할 컬럼명, null 일 경우 모든 컬럼
val selection = "food=?"	// 검색 조건
val selectionArgs = arrayOf("된장찌개")
val cursor = db.query(
	"food_table", columns, selection, selectionargs,
    null, null, null, null
)
  • SQL 직접 사용 방식
val cursor = db.rawQuery("SELECT _id, food, country FROM" +
	" food_table WHERE food='된장찌개'", null)

 

 

Cursor

Corsor

  • select 문에 의해 반환한 레코드의 집합을 가리킴
  • Cursor.moveToNext() : 다음 레코드가 있으면 true, 없으면 false
  • Cursor.getTYPE(column_index)를 사용하여 값을 읽어옴
// DB 겁색 결과를 DTO에 저장하여 List에 보관하고자 할 경우
// val foodList = arrayListOf<FoodDTO>()
with(cursor) {
	while (moveToNext()){
    	val id = getInt( getColumnIndex("_id"))
		val food = getString(getColumnIndex("food"))
        val country = getString(getColumnIndex("country"))
        Log.d(TAG, "$id - $food ($country)")
        // 결과를 DTO 객체에 저장후 List에 보관
        // val dto = FoodDTO(id, food, country)
        // foodList.add(dto)
    }
}

cursor.close()
helper.close()

'App&Web > Android' 카테고리의 다른 글

[Android/Kotlin] 주간 달력 만들기  (0) 2024.02.21
[Android/Kotlin] fragment에서 fragment로 이동  (0) 2024.02.21
[Android/Kotlin] 안드로이드 spinner(스피너) 배경색 적용  (0) 2024.02.21
[Android/Kotlin] 안드로이드 스튜디오 알림 안뜸 해결  (0) 2023.11.05
[Android/Kotlin] 뷰바인딩  (0) 2023.09.27
'App&Web/Android' 카테고리의 다른 글
  • [Android/Kotlin] fragment에서 fragment로 이동
  • [Android/Kotlin] 안드로이드 spinner(스피너) 배경색 적용
  • [Android/Kotlin] 안드로이드 스튜디오 알림 안뜸 해결
  • [Android/Kotlin] 뷰바인딩
2월2
2월2
  • 2월2
    서벅돌의 성장일기
    2월2
  • 전체
    오늘
    어제
    • 분류 전체보기 (120)
      • TIL (2)
      • Server (28)
        • spring (7)
        • node.js (16)
        • 기타 (5)
      • App&Web (17)
        • Web (1)
        • Android (16)
        • iOS (0)
      • 공부 (59)
        • 깃&깃허브 (3)
        • 파이썬 (17)
        • 유니티 (4)
        • 자료구조 | 알고리즘 (15)
        • 자바 (3)
        • 운영체제 (8)
        • AI와 데이터 (9)
      • 대외활동 (12)
        • NPC 동아리 (1)
        • UMC 동아리 (11)
      • 대학교 (1)
        • 교직 (1)
      • 기타 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글 관리
  • 링크

  • 공지사항

    • Notice
  • 인기 글

  • 태그

    java
    유니티
    Lua
    Android
    Unity
    Python
    코틀린
    루아
    mysql
    안드로이드
    자바
    파이썬
    kotlin
    C
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
2월2
[Android/Kotlin] SQLite
상단으로

티스토리툴바