SQLite?
- 클라이언트 어플리케이션에 주로 사용하는 경량 내장형 DBMS
- 관계형 데이터베이스이므로 테이블 형태로 데이터 저장
- 애플리케이션에 내장하므로 라이브러리 형태로 적용
- 모바일 기기 앱 등에 DB를 사용하여 자료를 저장하여야 할 경우 사용
안드로이드 DB 사용 순서
- DB 설계
- 요구사항(기능), UI(화면)을 고려하여 테이블 설계
- Helper 클래스 작성 - 테이블을 쉽게 접근 가능
- SQLiteOpenHelper 상속
- 설계를 바탕으로 DB 테이블 생성
- 샘플 데이터 추가
- DB 사용
- DB 접근이 필요할 때 Helper 클래스 객체 생성
- Writable or Readable
1. DB 테이블 설계
- DB 파일명과 테이블 명, 컬럼을 결정한다.
- 기본 키는 _id로 고정하며 integer type, autoincrement를 사용한다.
- 테이블 이름과 컬럼 이름은 자주 사용하므로 상수로 지정해둔다.
📍 테이블 생성 SQL문
CREATE TABLE 테이블 명 ( _id integer primary key autoincrement, 컬럼1 타입, 컬럼2 타입, 컬럼3 타입)
2. Helper 클래스 작성
- SQLiteOpenHelper - 안드로이드 DB를 편리하게 사용할 수 있도록 도와주는 SQLiteDatabase 패키지 소속 클래스
- SQLiteOpenHelper 상속 후 생성자 추가 및 onCreate(), onUpgrade()를 재정의
- 생성자: DB파일 명, 버전 지정
- onCreate(): 테이블을 SQL 사용하여 생성
❗ 앱을 기기에 깐 후 getReadableDatabase/getWritableDatabase 메소드를 호출하는 순간 DB에 접근하는데 맨 처음 접근하는 순간만 onCreate가 수행
❗ onCreate 메소드는 첫 호출 이후에는 호출되지 않음
-
- onUpgrade(): 테이블 변경시 사용
public class ContactDBHelper extends SQLiteOpenHelper {
private final String TAG = "ContactDBHelper";
// 테이블 명, 컬럼 명은 자주 사용되므로 상수로 지정
private final static String DB_NAME = "contact_db";
public final static String TABLE_NAME = "contact_table";
public final static String COL_NAME = "name";
public final static String COL_PHONE = "phone";
public final static String COL_CAT = "category";
// 생성자
public ContactDBHelper(Context context) {
// ContactDBHelper의 부모인 SQLiteOpenHelper의 생성자 호출
super(context, DB_NAME, null, 1);
/* 액티비티가 context역할. context 정보는 앱이 실행되는 환경 정보
액티비티가 환경 정보도 갖고 있기 때문에 액티비티가 이 자리에 들어가면 됨 */
}
@Override
// 만들어진 DB파일의 DB정보를 전달 받음 (시스템에서 알아서 전달)
public void onCreate(SQLiteDatabase db) {
String createSql = "create table " + TABLE_NAME + " ( _id integer primary key autoincrement, "
+ COL_NAME + " TEXT, " + COL_PHONE + " TEXT, " + COL_CAT + " TEXT);";
Log.d(TAG, createSql);
// execSql - DB 내용을 바꾸는 작업 (create, insert, delete, update)
db.execSQL(createSql);
// 필요한 경우 이 부분에 샘플 데이터 추가
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
3. DB 사용
- helper객체 생성
ContactDBHelper helper = new ContactDBHelper(this)
2. helper를 사용하여 SQLiteDatabase 객체 획득
// 읽기 전용
SQLiteDatabase db = helper.getReadableDatabase()
// 읽기/쓰기 겸용
SQLiteDatabase db = helper.getWritableDatabase()
3. SQLiteDatabase객체를 사용하여 쿼리 수행
// 메소드 사용
db.insert()
db.update()
db.delete()
db.query() // select
// 직접 SQL 사용
db.execSQL() // insert, delete, update
db.rawQuery() // select
4. helper객체 close 수행
helper.close()
// Cursor을 사용하였을 경우 close (메모리 낭비 방지)
Cursor.close()
❗ helper.close()를 안하면 commit이 안 되는 경우가 존재
(DB에서 실제 데이터를 쓰는 작업은 커밋이 이루어질 때 영구적으로 기록)
SQLiteDatabase Query
- Query 별로 전용의 메소드를 사용하거나 SQL문을 사용
1. 데이터 삽입 - insert() or execSQL()
SQLiteDatabase db = helper.getWritableDatabase();
/* 메소드 사용 */
ContentValues row = new ContentValues();
// 컬럼 명, 삽입할 값
row.put(ContactDBHelper.COL_NAME, etName.getText().toString());
row.put(ContactDBHelper.COL_PHONE, etPhone.getText().toString());
row.put(ContactDBHelper.COL_CATEGORY, etCategory.getText().toString());
long result = db.insert(ContactDBHelper.TABLE_NAME, null, row);
// insert는 long타입의 반환 값 존재 (영향을 받은 row의 개수 반환), result값이 0보다 크면 정상적으로 반환됐다고 판단 가능
/* SQL 사용 */
db.execSQL("insert into " + ContactDBHelper.TABLE_NAME + " values ( null, '"
+ etName.getText().toString() + "', '" + etPhone.getText().toString() + "', '"
+ etCategory.getText().toString() + "');");
// execSQL은 반환 값이 없으므로 기능이 잘 수행되었는지 판단 불가능 -> try-catch문 사용
helper.close();
❗ 컬럼명이 변수로 정의되어 있을 경우 문자열 결합이 복잡하므로 가능하면 메소드 사용
❗ SQL문 작은 따옴표 주의
2. 데이터 수정 - update() or execSQL()
SQLiteDatabase db = helper.getWritableDatabase();
/* 메소드 사용 */
ContentValues row = new ContentValues();
// 수정할 컬럼 명과 수정할 값
row.put(ContactDBHelper.COL_PHONE, etPhone.getText().toString());
// null일 경우 전체 행 삭제
String whereClause = ContactDBHelper.COL_NAME + "=? and " + ContactDBHelper.COL_CATEGORY + "=?";
String[] whereArgs = new String[] {etName.getText().toString(), etCategory.getText().toString()};
db.update(ContactDBHelper.TABLE_NAME, row, whereClause, whereArgs);
/* SQL 사용 */
db.execSQL("update " + ContactDBHelper.TABLE_NAME + " set " + ContactDBHelper.COL_PHONE
+ " = '" + etPhone.getText().toString() + "' where " + ContactDBHelper.COL_NAME
+ " = '" + etName.getText().toString() + "' and " + ContactDBHelper.COL_CATEGORY
+ " = '" + etCategory.getText().toString() + "';");
helper.close();
3. 데이터 삭제 - delete() or execSQL()
SQLiteDatabase db = helper.getWritableDatabase();
/* 메소드 사용 */
String whereClause = ContactDBHelper.COL_NAME + "=?"; // 조건
String[] whereArgs = new String[] {etName.getText().toString()}; // 조건 값 배열
db.delete(ContactDBHelper.TABLE_NAME, whereClause, whereArgs);
/* SQL 사용 */
db.execSQL("delete from " + ContactDBHelper.TABLE_NAME + " where " + ContactDBHelper.COL_NAME
+ " = '" + etName.getText().toString() + "';");
helper.close();
4. 데이터 검색 - query() or rawQuery()
SQLiteDatabase db = helper.getReadableDatabase();
/* 메소드 사용 */
String[] columns = {"_id", ContactDBHelper.COL_NAME, ContactDBHelper.COL_PHONE, ContactDBHelper.COL_CATEGORY};
String selection = ContactDBHelper.COL_NAME + "=?";
String[] selectArgs = new String[] {etName.getText().toString()};
// 모든 컬럼 선택시 columns 대신 null
Cursor cursor = db.query(ContactDBHelper.TABLE_NAME, columns, selection, selectArgs,
null, null, null, null);
/* SQL 직접 사용 */
// 모든 컬럼 선택시 * 사용
Cursor cursor = db.rawQuery("Select * From " + ContactDBHelper.TABLE_NAME + " where "
+ ContactDBHelper.COL_NAME + " = '" + etName.getText().toString() + "';", null);
// or where " + ContactDBHelper.COL_NAME + " =?;", new String[] {etName.getText().toString()}
- Cursor
- select문에 의해 반환한 레코드 집합 지정
- moveToNext() - 이동할 레코드가 있으면 true, 없으면 false
- get타입(컬럼 순서)를 사용해 값을 읽음
while (cursor.moveToNext()) {
int id = cursor.getInt(cursor.getColumnIndex("_id"));
String name = cursor.getString(cursor.getColumnIndex(ContactDBHelper.COL_NAME));
String phone = cursor.getString(cursor.getColumnIndex(ContactDBHelper.COL_PHONE));
String category = cursor.getString(cursor.getColumnIndex(ContactDBHelper.COL_CATEGORY));
// 결과를 객체에 저장할 경우 (DTO 필요)
ContactDto item = new ContactDto();
item.setId(id);
item.setName(name);
item.setPhone(phone);
item.setCategory(category);
list.add(item);
}
helper.close();
cursor.close();
'프로그래밍 > Android' 카테고리의 다른 글
[Android] 안드로이드 CursorAdapter 사용 (0) | 2021.09.26 |
---|