Bucket Place/Android

[Android] SQLite 데이터베이스 사용하기

Cloud Travel 2014. 4. 24. 13:25


  들어가면서... 


 안녕하세요. 오늘은 안드로이드에 내장으로 들어있는 SQLite 사용법에 대해서 알아보도록 하겠습니다. SQLite는  MySQL, Oracle 10g, 11g 등과 같은 RDBMS입니다. 문법 또한 거의 95%이상 동일하다고 보시면 됩니다. 제가 SQLite를 안드로이드에서 처음 사용해본 것은 한 3년 전 이었던것 같습니다. 그때는 아무것도 모르고 SQL문을 모두 적어서 사용했었는데, 내장되있는 훌륭한 함수가 많은 것을 알게되었죠 ' ' /


 SQLite를 사용하는 방법은 단순합니다. 데이터베이스를 컨트롤 해줄 SQLiteOpenHelper 클래스를 생성해주고, 데이터를 저장할 클래스를 만들어 줍니다.



  목표 


 오늘의 목표는  간단한  SQLiteOpenHelper 클래스를 정의하고 이를 사용하여 Database를 컨트롤하는 것을 로그를 이용해서 찍어보는 것이 되겠습니다. 제가 만들 데이터베이스는 간단하게 하나의 테이블을 가지고 있으며 아래의 그림과 같습니다.



    기본 지식


 Android SQLite를 사용하면서 알아야될 몇몇 가지에 대해서 집어 볼가 합니다.

 

 1. SQLiteOpenHelper

   - Database를 생성하거나 버젼을 관리해주는 역할을 해주는 클래스입니다.

   - Database를 생성하는 추상 함수로 onCreate( ) 와 데이터베이스를 업데이트하는 onUpgrade( ) 를 제공합니다.

   - onCreate() 함수는 어플리케이션에서 처음으로 데이터베이스를 생성할때 한 번 호출이 일어납니다.

   - onUpdate() 함수는 데이터베이스 ALTER 기능을 수행하는 역할을 합니다.


 2. Cursor

   - 데이터베이스에 접근하여 데이터를 읽어오는데 사용이됩니다.

   - 데이터베이스의 튜플(Tuple)위치를 변경하거나 하나의 튜플에서 데이터를 읽어오는데 사용됩니다.


 3. SQLiteOpenHelper 내부에 새로 만든 함수에서 사용한 SQLiteDatabse의 객체는 모두 close를 해줘야한다.



   데이터 저장 객체 생성하기

 

 데이터를 저장할 객체는 간단하게 필요한 형태의 생성자와 getter, setter를 정의해주시면 됩니다.

 위 Friend데이터 베이스를 컨트롤할 Friend.java 를 보도록 합시다. 어떻게 보면 ORDB를 사용하는 샘이되는 것이죠.

public class Friend {
	private int id;
	private String name;
	private String email;
	private String phone;
	
	// To use for selecting Friend List
	public Friend(int id, String name, String email, String phone){
		this.setId(id);
		this.setName(name);
		this.setEmail(email);
		this.setPhone(phone);
	}
	
	// To use for inserting Friend List
	public Friend(String name, String email, String phone){
		this.setName(name);
		this.setEmail(email);
		this.setPhone(phone);
	}
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}
	
}

 


  SQLiteOpenHelper  


 SQLiteOpenHelper 클래스를 상속받아서 클래스를 생성하면 위에서 설명한 두 개의 함수가 자동으로 생성됩니다. 기본적으로 이 함수를 작성해야 하고, 생성자를 만들어 줘야합니다.

 

 추가적으로 다음은 선택사항이지만, 테이블 이름과 컬럼이름의 오타로 인한 비정상적 종료등을 방지하기 위해 상수변수를 미리 정의해서 사용할때는 이를 참조해서 사용하는 것이 좋습니다.


 제가 만든 SQLiteFriendListHelper.java 의 모습을 보도록 하겠습니다.

public class SQLiteFriendListHelper extends SQLiteOpenHelper {

	// 테이블에 관련된 변수들을 상수로 미리 선언해줍니다.
	private static final int DATABASE_VERSION = 1; 				// 어플리케이션 데이터베이스 버전관리
	
	private static final String DATABASE_NAME = "SQLiteTest";	// 데이터베이스 이름
	
	/* define Friend Table */
	private static final String TABLE_FRIEND = "Friend";		// 테이블 이름
	
	private static final String PRIMARY_KEY_ID = "id";			// Friend 테이블 Columns 정의 시작
	private static final String FRIEND_NAME = "name";
	private static final String FRIEND_EMAIL = "email";
	private static final String FRIEND_PHONE = "phone";			// Friend 테이블 Columns 정의 끝
	/* Friend Table End */
	
	public SQLiteFriendListHelper(Context context){
		super(context, DATABASE_NAME, null, DATABASE_VERSION);
	}
	
	/**
	 * 데이터베이스를 생성하는 함수입니다.
	 *  - 이 함수는 어플리케이션이 설치되고 데이터베이스가 불릴때 한번만 실행됩니다.
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		// createTableQuery = CREATE TABLE Friend(id INTEGER PRIMARY KEY, name TEXT, email TEXT, phone TEXT)
		String createTableQuery = "CREATE TABLE " + TABLE_FRIEND + "(" 
									+ PRIMARY_KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
									+ FRIEND_NAME + " TEXT UNIQUE," 
									+ FRIEND_EMAIL + " TEXT,"
									+ FRIEND_PHONE + " TEXT" + ")";
		db.execSQL(createTableQuery);
	}

	/**
	 * 데이터베이스의 형태가 변경되면 실행하여 데이터베이스 구조를 변경합니다.
	 */
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub
		// dropOldVersionQuery = DROP TABLE IF EXISTS FRIEND
		String dropOldVersionQuery = "DROP TABLE IF EXISTS " + TABLE_FRIEND;
		db.execSQL(dropOldVersionQuery);
		// create new database
		onCreate(db);
	}
}

 상수를 이용해서 각종 이름을 선언 해주었습니다. 어느 플랫폼이나 마찬가지지만 공간을 주는 것에 유의하도록 합시다.

 스페이스 한칸 안띄어서 안되는 경우가 수두룩하니... 주의합시다.


 위의 내용으로 기본적인 SQLiteOpenHelper 클래스의 정의는 끝난것입니다. 이제 여기에 추가적으로 사용자가 필요로 하는 함수를 추가시켜주면 됩니다. 저의 경우에는 insert, delete, update, select * 기능을 하는 함수를 생성하여 만들어 보았습니다. 이 함수가 추가된 SQLiteFriendListHelper.java 의 전문을 보도록 합시다.


public class SQLiteFriendListHelper extends SQLiteOpenHelper {

	// 테이블에 관련된 변수들을 상수로 미리 선언해줍니다.
	private static final int DATABASE_VERSION = 1; 				// 어플리케이션 데이터베이스 버전관리
	
	private static final String DATABASE_NAME = "SQLiteTest";	// 데이터베이스 이름
	
	/* define Friend Table */
	private static final String TABLE_FRIEND = "Friend";		// 테이블 이름
	
	private static final String PRIMARY_KEY_ID = "id";			// Friend 테이블 Columns 정의 시작
	private static final String FRIEND_NAME = "name";
	private static final String FRIEND_EMAIL = "email";
	private static final String FRIEND_PHONE = "phone";			// Friend 테이블 Columns 정의 끝
	/* Friend Table End */
	
	public SQLiteFriendListHelper(Context context){
		super(context, DATABASE_NAME, null, DATABASE_VERSION);
	}
	
	/**
	 * 데이터베이스를 생성하는 함수입니다.
	 *  - 이 함수는 어플리케이션이 설치되고 데이터베이스가 불릴때 한번만 실행됩니다.
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		// createTableQuery = CREATE TABLE Friend(id INTEGER PRIMARY KEY, name TEXT, email TEXT, phone TEXT)
		String createTableQuery = "CREATE TABLE " + TABLE_FRIEND + "(" 
									+ PRIMARY_KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
									+ FRIEND_NAME + " TEXT UNIQUE," 
									+ FRIEND_EMAIL + " TEXT,"
									+ FRIEND_PHONE + " TEXT" + ")";
		db.execSQL(createTableQuery);
	}

	/**
	 * 데이터베이스의 형태가 변경되면 실행하여 데이터베이스 구조를 변경합니다.
	 */
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub
		// dropOldVersionQuery = DROP TABLE IF EXISTS FRIEND
		String dropOldVersionQuery = "DROP TABLE IF EXISTS " + TABLE_FRIEND;
		db.execSQL(dropOldVersionQuery);
		// create new database
		onCreate(db);
	}
	
	/**
	 * 데이터베이스 관리를 위해 필요한 함수들을 정의해준다.
	 */
	
	// insert  
	public void insertFriend(Friend friend){
		// 읽기와 쓰기가 가능한 데이터베이스를 참조
		SQLiteDatabase db = this.getWritableDatabase();
		
		// 데이터베이스에 넣을 데이터를 Key-Value 형식으로 정의
		ContentValues values = new ContentValues();
		values.put(FRIEND_NAME, friend.getName());
		values.put(FRIEND_EMAIL, friend.getEmail());
		values.put(FRIEND_PHONE, friend.getPhone()); 
		
		// insert! 
		db.insert(TABLE_FRIEND, null, values);
		db.close();
	}
	 
	// select all
	public List<Friend> selectAllFriend(){
		// 모든 정보를 저장할 리스트를 하나 만들어준다.
		List<Friend> friendList = new ArrayList<Friend>();
		
		// SelectAllQuery = SELECT * FROM FRIEND
		String selectAllQuery = "SELECT * FROM " + TABLE_FRIEND;
		// 읽기와 쓰기가 가능한 데이터베이스를 참조
		SQLiteDatabase db = this.getWritableDatabase();
		// Cursor 객체 생성
		Cursor cursor = db.rawQuery(selectAllQuery, null);
		
		// cursor를 이용하여 가져온 데이터를 읽어온다.
		if ( cursor.moveToFirst() ){	// 데이터베이스에 데이터가 존재한다면...
			do {
				// 현재 데이터가 가르키고 있는 데이터를 이용하여 데이터 객체를 생성하고 리스트에 추가를 한다.
				friendList.add(new Friend(
								Integer.parseInt(cursor.getString(0)), 
								cursor.getString(1), 
								cursor.getString(2), 
								cursor.getString(3)));
			} while ( cursor.moveToNext() );
		}
        cursor.close();
        db.close();

		return friendList;
	}
	
	// update : update return 값 : the number of rows affected
	public int updateFriend(Friend friend){
		int updateRow;		// return value
		
		SQLiteDatabase db = this.getWritableDatabase();
		
		ContentValues values = new ContentValues();
		values.put(FRIEND_NAME, friend.getName());
		values.put(FRIEND_EMAIL, friend.getEmail());
		values.put(FRIEND_PHONE, friend.getPhone());
		
		// update = ... WHERE id = "getId()"
		updateRow = db.update(TABLE_FRIEND, values, PRIMARY_KEY_ID + " = ?", 
								new String[]{String.valueOf(friend.getId())});
		db.close();
		return updateRow;
	}
	
	// delete
	public void deleteFriend(Friend friend){
		SQLiteDatabase db = this.getWritableDatabase();
		
		// delete = ... WHERE id = "getId()"
		db.delete(TABLE_FRIEND, PRIMARY_KEY_ID + " = ?",  
								new String[]{String.valueOf(friend.getId())});
		db.close();
	}
}



  사용하기  


  자 이제 SQLite 데이터베이스를 사용할 준비가 모두 되었습니다.

  프로젝트를 생성할 때 생성된 MainActivity.java 에 TestCode를 작성하였습니다.

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// helper 생성
		SQLiteFriendListHelper dbHelper = new SQLiteFriendListHelper(this);

		Log.d("destiny", "Insert Data...");
		dbHelper.insertFriend(new Friend("Kim", "gmailcom", "000-1234-5678"));
		dbHelper.insertFriend(new Friend("Lee", "naver.com", "010-9876-5432"));
		dbHelper.insertFriend(new Friend("Park", "hanmail.com", "010-0000-0000"));
		Log.d("destiny", "=======================");

		Log.d("destiny", "Read all data");
		List<Friend> friendList = dbHelper.selectAllFriend();
		for (Friend friend : friendList) {
			Log.d("destiny", "Name : " + friend.getName() + "  Email : "
					+ friend.getEmail() + "  Phone : " + friend.getPhone());
		}
		Log.d("destiny", "=======================");

		Log.d("destiny", "update Park : change email and phone number");
		friendList = dbHelper.selectAllFriend();
		for (Friend friend : friendList) {
			if (friend.getName().equals("Park")) {
				Friend updateFriend = new Friend(friend.getId(), "Park",
						"nate.com", "010-0000-0123");
				dbHelper.updateFriend(updateFriend);
			}
		}

		Log.d("destiny", "After Update");
		friendList = dbHelper.selectAllFriend();
		for (Friend friend : friendList) {
			Log.d("destiny", "Name : " + friend.getName() + "  Email : "
					+ friend.getEmail() + "  Phone : " + friend.getPhone());
		}
		Log.d("destiny", "=======================");

		Log.d("destiny", "Delete Lee");
		friendList = dbHelper.selectAllFriend();
		for (Friend friend : friendList) {
			if (friend.getName().equals("Lee")) {
				dbHelper.deleteFriend(friend);
			}
		}

		Log.d("destiny", "After Delete");
		friendList = dbHelper.selectAllFriend();
		for (Friend friend : friendList) {
			Log.d("destiny", "Name : " + friend.getName() + "  Email : "
					+ friend.getEmail() + "  Phone : " + friend.getPhone());
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

 다음은 실행 결과입니다. 화실이 약간좋지 않지만 양해바랍니다. 업로드하면 화질이 깨지내요 ㅠ




  마치며


 Android 의 SQLite 함수는 위의 소스를 한 번씩 옮겨 적어보는 것만으로도 많은 공부가되며, 바로 사용이 가능한 상태까지 됩니다. 요즘은 웹서버상의 데이터베이스를 많이 사용하여 사용이 적지만, 기본적으로 데이터베이스에 저장해야할 데이터를 위해서 사용되는 경우가 많습니다. 사용법 또한 많이 쉬우니 한번 해보시기 바랍니다.

 

 마지막으로 위 소스 전문 압축파일을 올려드립니다.

 

SQLiteTest.zip


 수고하십시요~