SQLite는 오픈소스로 만들어진 관계형 데이터 베이스입니다. (https://www.sqlite.org/)
SQLite를 이용한 데이터는 파일에 저장되며 다음과 같은 경로에 저장됩니다.
data/data/[package_name]/databases
Android에서 데이터베이스를 사용할 때 필요한 API는 android.database.sqlite 패키지로 제공됩니다.
SQLiteOpenHelper 클래스를 사용하여 데이터베이스 생성하기
SQLiteOpenHelper 클래스에는 데이터베이스 관리를 위한 유용한 API 세트가 포함되어 있습니다.
이 클래스를 사용하여 데이터베이스의 참조를 가져오면 시스템은 앱이 시작되고 있는 동안이 아닌 필요한 때에만 데이터베이스 생성 및 업데이트와 같이 장시간 실행될 수 있는 작업을 실행합니다.
개발자는 getWritableDatabase() 또는 getReadableDatabase()를 호출하기만 하면 됩니다.
SQLiteOpenHelper는 추상 클래스이므로 서브 클래스를 만들어 사용해야 합니다.
class DBHelper(
context: Context?,
name: String?, // 데이터 베이스 이름
factory: SQLiteDatabase.CursorFactory? = null, // null을 기본 값으로 함
version: Int // 데이터 베이스 버전
) : SQLiteOpenHelper(context, name, factory, version){
override fun onCreate(db: SQLiteDatabase?) {
// 테이블 생성
val memoSQL = "create table tb_memo (" +
"_id integer primary key autoincrement," +
"title," +
"content)"
db?.execSQL(memoSQL)
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
// 기존 테이블 제거후 다시 생성하기
db?.execSQL("drop table tb_memo")
onCreate(db)
}
}
SQLiteOpenHelper를 사용하려면 onCreate(), onUpgrade()를 재정의해서 사용해야 합니다.
- onCreate() : 앱이 설치되어 SQLiteOpenHelper가 최초로 사용되는 순간 호출됩니다.
- onUpgrade() 데이터 베이스 버전이 변경될 때마다 호출됩니다.
SQLiteDatabase 클래스
SQLite의 핵심 클래스는 SQLiteDatabase입니다.
데이터 베이스에 데이터를 저장하고, 가져오고, 수정, 삭제하는 sql를 SQLiteDatabase의 함수를 이용하여 수행합니다.
- execSQL(String sql, Object[] bindArgs) : select가 아닌 insert, update, delete 등 나머지 sql 실행
- rawQuery(String sql, String[] selectionArgs) : select sql 실행
execSQL() 함수로 insert문을 실행하기
다음은 SQLiteOpenHelper와 execSQL() 함수로 insert문을 실행한 예시입니다.
val helper = DBHelper(this,"memodb", null, DATABASE_VERSION)
val db:SQLiteDatabase = helper.writableDatabase
// insert Sql 실행
db.execSQL(
"insert into tb_memo (title, content) values (?,?)",
arrayOf(title, content)
)
db.close()
- SQLiteOpenHelper를 사용해 데이터 베이스를 생성하고
- SQLiteOpenHelper의 getWritableDatabase() 함수를 통해 SQLiteDatabase를 객체를 생성합니다.
- execSQL()을 통해 insert문을 실행하고 데이터를 저장합니다.
insert문에서 "~ values (?,?)"라고 작성하면 각각의 ?에 대응하는 데이터를 배열을 통해 넣어줘야 합니다.
rawQuery() 함수로 select문을 실행하기
val helper = DBHelper(this,"memodb", null, MainActivity.DATABASE_VERSION)
val db = helper.writableDatabase
// select Sql 실행
val cursor = db.rawQuery("select title, content from tb_memo order by _id desc limit 1", null)
// 다음행 가져오기
while (cursor.moveToNext()) {
// 다음 열 가져오기
titleView.text = cursor.getString(0)
contentView.text = cursor.getString(1)
}
db.close()
sql에 ? 표현이 없어 두 번째 매개변수 값이 null입니다. rawQuery의 응답 값은 Cursor 객체입니다.
Cursor 객체는 선택된 행의 집합 객체입니다.
여기서 각 열에 해당하는 데이터를 획득하려면 Cursor 객체를 이용해 행을 선택하고 선택된 행의 열 데이터를 획득하는 구조입니다.
위의 예시는 moveToNext() 함수를 통해 다음 행을 가져오고 getString() 함수를 통해 열 데이터를 가져옵니다.
매개변수의 0,1은 몇 번째 열 데이터를 가져오는지를 지정합니다.
Cursor의 다음 메서드를 통해 원하는 행을 가져올 수 있습니다.
- moveToNext(): 순서상으로 다음 행 선택
- moveToFirst(): 가장 첫 번째 행 선택
- moveToLast(): 가장 마지막 행 선택
- moveToPrevious(): 순서상으로 이전 행 선택
insert( ), query( ), update( ), delete( ) 함수 이용
execSQL(), rawQuery() 함수 이외에 다음의 함수를 이용해도 SQL 문을 수행할 수 있습니다.
execSQL(), rawQuery() 함수는 개발자가 직접 SQL 문을 매개변수로 전달해야 했지만
위 4가지 함수는 sql문을 만들기 위한 정보만 매개변수로 전달하면 자동으로 SQL 문을 만들어 실행해줍니다.
이 중 insert()와 update()는 ContentValues 클래스를 매개변수로 넘깁니다. key는 실제 테이블의 열 이름입니다.
ContentValues는 insert, update의 데이터를 key-value 형식으로 표현합니다.
- insert(String table, String nullColumnHack, ContentValues values)
- update(String table, ContentValues values, String whereClause, String[] whereArgs)
- delete(String table, String whereClause, String[] whereArgs)
- query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy,
- String having, String orderBy, String limit)
3번의 execSQL() 함수를 insert( ) 함수로 변경하면 다음과 같이 나옵니다.
val helper = DBHelper(this,"memodb", null, DATABASE_VERSION)
val db:SQLiteDatabase = helper.writableDatabase
// insert Sql 실행
var contentValues = ContentValues()
contentValues.put("title",title)
contentValues.put("content",content)
db.insert("tb_memo", null, contentValues)
db.close()
'Android > 개념 및 예제' 카테고리의 다른 글
안드로이드 퍼미션 개념 정리 (0) | 2021.05.18 |
---|---|
Realm를 사용해서 안드로이드 앱에 데이터 저장하기 (0) | 2021.05.14 |
안드로이드 앱 개발의 특징 및 디렉터리 구조 (0) | 2021.05.14 |
[Kotlin] Recyclerview click Event (람다 함수 사용) (0) | 2021.02.16 |
android 공식 문서를 영어로 봐야하는 이유 (0) | 2021.01.20 |