SQLite?

  • 클라이언트 어플리케이션에 주로 사용하는 경량 내장형 DBMS
  • 관계형 데이터베이스이므로 테이블 형태로 데이터 저장
  • 애플리케이션에 내장하므로 라이브러리 형태로 적용
  • 모바일 기기 앱 등에 DB를 사용하여 자료를 저장하여야 할 경우 사용

 

안드로이드 DB 사용 순서

  1. DB 설계
    • 요구사항(기능), UI(화면)을 고려하여 테이블 설계
  2. Helper 클래스 작성 - 테이블을 쉽게 접근 가능
    • SQLiteOpenHelper 상속
    • 설계를 바탕으로 DB 테이블 생성
    • 샘플 데이터 추가
  3. 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 사용

  1. 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
복사했습니다!