Android

Android 데이터베이스 사용법

Ms_Tony 2016. 3. 29. 15:04

데이터베이스(영어: databaseDB)는 작성된 목록으로써 여러 응용 시스템들의 통합된 정보들을 저장하여 운영할 수 있는 공용 데이터들의 묶음이다.


여러 사람들이 공유하고 사용할 목적으로 통합 관리되는 정보의 집합이다. 논리적으로 연관된 하나 이상의 자료의 모음으로 그 내용을 고도로 구조화함으로써 검색과 갱신의 효율화를 꾀한 것이다. 즉, 몇 개의 자료 파일을 조직적으로 통합하여 자료 항목의 중복을 없애고 자료를 구조화하여 기억시켜 놓은 자료의 집합체라고 할 수 있다.

공동 자료로서 각 사용자는 같은 데이터라 할지라도 각자의 응용 목적에 따라 다르게 사용할 수 있다.

- 위키 백과 사전



우선 안드로이드에서는 로그인을 포함한 유저의 정보를 보관하기 위해 로컬 면에서 데이터베이스를 사용하기도 합니다.

데이터베이스를 사용하기 위해서는 데이터베이스의 TABLE을 생성하는 일입니다.

코드의 설명에 있어서는 최대한 블로그의 글이 아닌 주석을 통해 설명을 하려고 노력하고 있으니 

주석을 보고 이해가 안가시는 부분이 있으시면 질문 부탁드립니다.

DataBases.java

/**
* 데이터베이스 테이블 생성
* Created by TonyChoi on 2016. 3. 29..
*/
public class DataBases {
//데이터베이스 호출 시 사용될 생성자
public static final class CreateDB implements BaseColumns {
public static final String NAME = "name";
public static final String CONTACT = "contact";
public static final String EMAIL = "email";
public static final String _TABLENAME = "address";
public static final String _CREATE =
"create table " + _TABLENAME + "("
+ _ID + " integer primary key autoincrement, "
+ NAME + " text not null , "
+ CONTACT + " text not null , "
+EMAIL + " text not null );";
}
}

이 후 DbOpenHelper Class를 생성해야합니다.

  DbOpenHelper.java

/**
* DbOpenHelper Class
* Created by TonyChoi on 2016. 3. 29..
*/
public class DbOpenHelper {

private static final String DATABASE_NAME = "addressbook.db";
private static final int DATABASE_VERSION = 1;
public static SQLiteDatabase mDB;
private DataBaseHelper mDBHelper;
private Context mCtx;

private class DataBaseHelper extends SQLiteOpenHelper {

/**
* 데이터베이스 헬퍼 생성자
* @param context context
* @param name Db Name
* @param factory CursorFactory
* @param version Db Version
*/
public DataBaseHelper(Context context, String name,
SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}

//최초 DB를 만들 때 한번만 호출
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DataBases.CreateDB._CREATE);
}

//버전이 업데이트 되었을 경우 DB를 다시 만들어주는 메소드
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//업데이트를 했는데 DB가 존재할 경우 onCreate를 다시 불러온다
db.execSQL("DROP TABLE IF EXISTS " + DataBases.CreateDB._TABLENAME);
onCreate(db);
}
}

//DbOpenHelper 생성자
public DbOpenHelper(Context context) {
this.mCtx = context;
}

//Db를 여는 메소드
public DbOpenHelper open() throws SQLException {
mDBHelper = new DataBaseHelper(mCtx, DATABASE_NAME, null, DATABASE_VERSION);
mDB = mDBHelper.getWritableDatabase();
return this;
}

//Db를 다 사용한 후 닫는 메소드
public void close() {
mDB.close();
}

/**
* 데이터베이스에 사용자가 입력한 값을 insert하는 메소드
* @param name 이름
* @param contact 전화번호
* @param email 이메일
* @return SQLiteDataBase에 입력한 값을 insert
*/
public long insertColumn(String name, String contact, String email) {
ContentValues values = new ContentValues();
values.put(DataBases.CreateDB.NAME, name);
values.put(DataBases.CreateDB.CONTACT, contact);
values.put(DataBases.CreateDB.EMAIL, email);
return mDB.insert(DataBases.CreateDB._TABLENAME, null, values);
}

/**
* 기존 데이터베이스에 사용자가 변경할 값을 입력하면 값이 변경됨(업데이트)
* @param id 데이터베이스 아이디
* @param name 이름
* @param contact 전화번호
* @param email 이메일
* @return SQLiteDataBase에 입력한 값을 update
*/
public boolean updateColumn(long id, String name, String contact, String email) {
ContentValues values = new ContentValues();
values.put(DataBases.CreateDB.NAME, name);
values.put(DataBases.CreateDB.CONTACT, contact);
values.put(DataBases.CreateDB.EMAIL, email);
return mDB.update(DataBases.CreateDB._TABLENAME, values, "_id="+id, null) > 0;
}

//입력한 id값을 가진 DB를 지우는 메소드
public boolean deleteColumn(long id) {
return mDB.delete(DataBases.CreateDB._TABLENAME, "_id=" + id, null) > 0;
}

//입력한 전화번호 값을 가진 DB를 지우는 메소드
public boolean deleteColumn(String number) {
return mDB.delete(DataBases.CreateDB._TABLENAME, "contact="+number, null) > 0;
}

//커서 전체를 선택하는 메소드
public Cursor getAllColumns() {
return mDB.query(DataBases.CreateDB._TABLENAME, null, null, null, null, null, null);
}

//ID 컬럼 얻어오기
public Cursor getColumn(long id) {
Cursor c = mDB.query(DataBases.CreateDB._TABLENAME, null,
"_id="+id, null, null, null, null);
//받아온 컬럼이 null이 아니고 0번째가 아닐경우 제일 처음으로 보냄
if (c != null && c.getCount() != 0)
c.moveToFirst();
return c;
}

//이름으로 검색하기 (rawQuery)
public Cursor getMatchName(String name) {
Cursor c = mDB.rawQuery( "Select * from address where name" + "'" + name + "'", null);
return c;
}
}

마지막으로 Constants Class를 선언해 줍니다.

Constants.java

/**
* Created by TonyChoi on 2016. 3. 29..
*/
public class Constants {

public static final int NAME = 0;
public static final int CONTACT = 1;
public static final int EMAIL = 2;
}


여기까지 하면 이제 데이터베이스의 세팅은 마무리가 되었고, 이제 데이터를 입력하고 표현할 액티비티와 

그에 맞는 리스트뷰 어댑터, 데이터 클래스를 만들어주면 될 것 같습니다.

InfoClass(데이터클래스) 코드입니다. 특별한 것 없이 생성자를 만들어놓고 Getter And Setter가 전부입니다.

InfoClass.java

/**
* Created by TonyChoi on 2016. 3. 29..
*/
public class InfoClass {

public int _id;
public String name;
public String contact;
public String email;

//생성자
public InfoClass(){}

/**
* 실질적으로 값을 입력할 때 사용되는 생성자(getter and setter)
* @param _id 테이블 아이디
* @param name 이름
* @param contact 전화번호
* @param email 이메일
*/
public InfoClass(int _id, String name, String contact, String email) {
this._id = _id;
this.name = name;
this.contact = contact;
this.email = email;
}

public int get_id() {
return _id;
}

public void set_id(int _id) {
this._id = _id;
}

public String getName() {
return name;
}

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

public String getContact() {
return contact;
}

public void setContact(String contact) {
this.contact = contact;
}

public String getEmail() {
return email;
}

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

리스트뷰에 사용될 어댑터의 코드입니다.

간단한 내용만 표현할 예정이라 BaseAdapter를 상속받아 사용했습니다.

CustomAdapter.java

/**
* Created by TonyChoi on 2016. 3. 29..
*/
public class CustomAdapter extends BaseAdapter{

private LayoutInflater mInflater;
private ArrayList<InfoClass> InfoArr;
private ViewHolder holder;

public CustomAdapter(Context c, ArrayList<InfoClass> array) {
mInflater = LayoutInflater.from(c);
InfoArr = array;
}
@Override
public int getCount() {
return InfoArr.size();
}

@Override
public Object getItem(int position) {
return null;
}

@Override
public long getItemId(int position) {
return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;

if (v == null) {
holder = new ViewHolder();
v = mInflater.inflate(R.layout.listview_item, null);
holder.name = (TextView)v.findViewById(R.id.tvName);
holder.contact = (TextView)v.findViewById(R.id.tvContact);
holder.email = (TextView)v.findViewById(R.id.tvEmail);

v.setTag(holder);
} else {
holder = (ViewHolder)v.getTag();
}

//InfoClass를 생성하여 각 뷰의 포지션에 맞는 데이터를 가져옴
InfoClass info = InfoArr.get(position);

//리스트뷰의 아이템에 맞는 String값을 입력
holder.name.setText(info.name);
holder.contact.setText(info.contact);
holder.email.setText(info.email);

return v;
}

//ArrayList Getter And Setter
public void setArrayList(ArrayList<InfoClass> arrays) {
this.InfoArr = arrays;
}

public ArrayList<InfoClass> getArrayList(){
return InfoArr;
}


/**
* ViewHolder Class 생성
*/
private class ViewHolder {
TextView name;
TextView contact;
TextView email;
}
}


다음은 메인 엑티비티와 리스트뷰 row의 layout 소스코드입니다.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>

<LinearLayout
android:id="@+id/ll_top"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<EditText
android:id="@+id/etName"
android:layout_width="80dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="이름"
android:singleLine="true"/>

<EditText
android:id="@+id/etContact"
android:layout_width="80dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="연락처"
android:singleLine="true"/>

<EditText
android:id="@+id/etEmail"
android:layout_width="80dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="이메일"
android:singleLine="true"/>

<Button
android:id="@+id/btnAdd"
android:layout_width="80dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:onClick="btnAdd"
android:text="추가"/>
</LinearLayout>

<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/ll_top"></ListView>
</RelativeLayout>

리스트뷰 row의 xml파일입니다.

listview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dip"
android:gravity="center_vertical">

<TextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"/>

<TextView
android:id="@+id/tvContact"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/tvEmail"
android:layout_toRightOf="@+id/tvName"
android:gravity="center"/>

<TextView
android:id="@+id/tvEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"/>
</RelativeLayout>

</RelativeLayout>


마지막으로 메인 엑티비티 소스코드 입니다.
MainActivity.java


public class MainActivity extends Activity {

private static final String TAG = "TestDataBase";
private DbOpenHelper mDbOpenHelper;
private Cursor mCursor;
private InfoClass mInfoClass;
private ArrayList<InfoClass> mInfoArr;
private CustomAdapter mAdapter;

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

setLayout();

//데이터베이스 생성(파라메터 Context) 및 오픈
mDbOpenHelper = new DbOpenHelper(this);
try {
mDbOpenHelper.open();
} catch (SQLException e) {
e.printStackTrace();
}

//DataBase에 값을 입력
mDbOpenHelper.insertColumn("송중기", "01011223344", "angel@google.com");
mDbOpenHelper.insertColumn("송혜교", "01333331111", "asdffff@emdo.com");
mDbOpenHelper.insertColumn("제시카", "01234001111", "yaya@hhh.com");
mDbOpenHelper.insertColumn("말보루", "01600001111", "tree777@atat.com");
mDbOpenHelper.insertColumn("데이브", "01700001111", "tiger@tttt.com");
mDbOpenHelper.insertColumn("엠씨더맥스", "01800001111", "gril@zzz.com");

//ArrayList 초기화
mInfoArr = new ArrayList<InfoClass>();

doWhileCursorToArray();

//값이 제대로 입력됬는지 확인하기 위해 로그를 찍어본다
for (InfoClass i : mInfoArr) {
Log.i(TAG, "ID = " + i._id);
Log.i(TAG, "NAME = " + i.name);
Log.i(TAG, "CONTACT = " + i.contact);
Log.i(TAG, "EMAIL = " + i.email);
}

//리스트뷰에 사용할 어댑터 초기화(파라메터 Context, ArrayList<InfoClass>)
mAdapter = new CustomAdapter(this, mInfoArr);
mListView.setAdapter(mAdapter);
//리스트뷰의 아이템을 길게 눌렀을 경우 삭제하기 위해 롱클릭 리스너 따로 설정
mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent,
View view, int position, long id) {
Log.i(TAG, "position = " + position);
//리스트뷰의 position은 0부터 시작하므로 1을 더함
boolean result = mDbOpenHelper.deleteColumn(position + 1);
Log.i(TAG, "result = " + result);

if (result) {
//정상적인 position을 가져왔을 경우 ArrayList의 position과 일치하는 index 정보를 remove
mInfoArr.remove(position);
//어댑터에 ArrayList를 다시 세팅 후 값이 변경됬다고 어댑터에 알림
mAdapter.setArrayList(mInfoArr);
mAdapter.notifyDataSetChanged();
} else {
//잘못된 position을 가져왔을 경우 다시 확인 요청
Toast.makeText(MainActivity.this, "INDEX를 확인해 주세요",
Toast.LENGTH_SHORT).show();
}
return false;
}
});

}

//doWhile문을 이용하여 Cursor에 내용을 다 InfoClass에 입력 후 InfoClass를 ArrayList에 Add
private void doWhileCursorToArray() {

mCursor = null;
//DB에 있는 모든 컬럼을 가져옴
mCursor = mDbOpenHelper.getAllColumns();
//컬럼의 갯수 확인
Log.i(TAG, "Count = " + mCursor.getCount());

while (mCursor.moveToNext()) {
//InfoClass에 입력된 값을 압력
mInfoClass = new InfoClass(
mCursor.getInt(mCursor.getColumnIndex("_id")),
mCursor.getString(mCursor.getColumnIndex("name")),
mCursor.getString(mCursor.getColumnIndex("contact")),
mCursor.getString(mCursor.getColumnIndex("email"))
);
//입력된 값을 가지고 있는 InfoClass를 InfoArray에 add
mInfoArr.add(mInfoClass);
}
//Cursor 닫기
mCursor.close();
}

/**
* 추가 버튼 클릭 메소드.
*
* @param v
*/
public void btnAdd(View v) {
//추가를 누를 경우 EditText에 있는 String 값을 다 가져옴
mDbOpenHelper.insertColumn(
mEditTexts[Constants.NAME].getText().toString().trim(),
mEditTexts[Constants.CONTACT].getText().toString().trim(),
mEditTexts[Constants.EMAIL].getText().toString().trim()
);
//ArrayList 내용 삭제
mInfoArr.clear();

doWhileCursorToArray();

mAdapter.setArrayList(mInfoArr);
mAdapter.notifyDataSetChanged();
//Cursor 닫기
mCursor.close();
}

/**
* 레이아웃 세팅하는 메소드
*/
private EditText[] mEditTexts;
private ListView mListView;

private void setLayout() {
mEditTexts = new EditText[]{
(EditText) findViewById(R.id.etName),
(EditText) findViewById(R.id.etContact),
(EditText) findViewById(R.id.etEmail)
};

mListView = (ListView) findViewById(R.id.list);
}

//액티비티가 종료 될 때 디비를 닫아준다
@Override
protected void onDestroy() {
mDbOpenHelper.close();
super.onDestroy();
}
}

소스코드를 모두 작성하시면 이러한 화면을 보실 수 있습니다.

차례대로 이름, 전화번호, 이메일을 입력 후 오른쪽의 추가 버튼을 누르시면 

리스트뷰에 새로운 아이템이 추가되며 DB에도 그 정보가 저장되는 것을 알 수 있습니다.

원치 않는 내용을 삭제하고 싶으실 때는 리스트뷰 아이템을 롱클릭 할 경우

해당 row 삭제와 함께 데이터베이스에서 정보를 삭제하게 되있습니다.

프로젝트 소스 입니다.

DataBaseTest.zip

마지막으로 공부하는데 도움을 주신 커니님께 감사의 말씀 드립니다.

출처 : 커니의 안드로이드 이야기 DB 예제 소스

URL :  http://androidhuman.tistory.com/ 


'Android' 카테고리의 다른 글

ProgressDialog 만들기 예제  (0) 2016.03.31
TouchEvent 사용법  (0) 2016.03.31
ScrollView 안에 ListView 또는 GridView 사용 시  (0) 2015.11.03
안드로이드 공유 기능  (0) 2015.10.16
Android Text ClipBoard에 복사하기  (0) 2015.10.15