-
Notifications
You must be signed in to change notification settings - Fork 0
Back end
개발자에는 크게 세가지 종류가 있다.
- 프론트엔드 개발자 유저와의 소통을 위해 UI, UX를 만들고, 값을 입력받거나 세팅하는 등의 일을 하는 사람.
- 백엔드 개발자
데이터베이스, 서버 등등 화면에 보이는 것 뒤의 일을 하는 사람. - 풀스텍 개발자
프론트엔드와 백엔드를 모두 맡아서 하는 사람.
우리는 지금부터 백엔드 작업을 하기 위해 필요한 것들을 알아볼 것이다!
데이터베이스(DB)는 엑셀 같은거라고 생각하면 편할 듯 하다. 표 처럼 행(column)과 열(row)가 있다. 데이터베이스 회사? 브랜드?도 여러개가 있는데, 우리는 그 중에 무료이고 간단히 사용할 수 있는 SQLite database를 사용해볼 것이다.
SQLite 를 검색해보면 홈페이지가 나오고, 다른 개발 툴과 마찬가지로 개발자 문서가 있지만, 매우매우 가독성이 떨어지고 읽기가 싫어진다(...) 그리고 사실 엄청 간단한 데이터베이스라서 기업들에서는 MongoDB나 다른 데이터베이스를 더 많이 사용하는 것 같다.
+) SQL은 Structured Query Language의 약자이다. Query라는 구어랑 비슷한 느낌의 언어를 사용한다.
코드에서 int a = 1;
이런식으로 직접 정의하지 않은, 사용자가 입력하거나 바꾼 정보들은 저장되지 않는다. 정보가 저장되지 않으면 앱의 시간표나 알람 목록은 앱을 열 때마다 초기화 될 것이다. 그래서 정보를 저장하려면 핸드폰 내에 데이터베이스를 만든 후에 앱을 실행할 때마다 불러오고, 내용이 바뀌면 저장도 해줘야한다.
일단 우리 앱에서 필요한 데이터베이스가 알람, 시간표, 과목 이렇게 3개이기 때문에 DataBase도 3개가 필요하다. 그래서 아래처럼 Database 3개를 만들었다.
위에서부터 알람, 시간표, 과목 순이다.(데이터는 예시)
- alarmDB의 생김새
_ID alarmName hour min onOff 1 "기상" 7 30 1 2 "운동" 16 0 0 - timetableDB의 생김새
_ID mon tue wed thu fri sat sun 1 "과학" "국어" "수학" "음악" "창체" "휴식" "예배" 2 "체육" "정보" "종교" "예배" "불어" ... ... - subjectDB의 생김새
_ID subjectName id password color alarmBefore useAlarm 1 "과학" "1111111111" "1234" 23487 5 1 2 "체육" "2222222222" "12345" 38470 0
데이터세트는 기본적으로 id 값을 갖는다. 그 뒤로 쭉 나열된 alarmName, hour 등은 column(행) 이라고 부른다.
""으로 둘러쌓인 값은 String이고, 그렇지 않은 값들은 int(integer)이다. useDay, onOff, useAlarm은 참/거짓(bool) 값을 가져야하는게 맞는데 SQLite DB는 (내가 알기론..?) bool 값을 집어넣을 수가 없다. 참->1 거짓->0으로 대신했다.
데이터베이스를 사용하려면
- 데이터베이스 생성하기
- 불러오기
- 저장하기
- 삭제하기
이것만 알면 된다. 이미 전역함수로 기능은 다 만들어놓았고 가져다 쓰기만 하면 된다!
- 공통으로 쓰이는 함수
return형 함수명 설명 DBOpenHelper open(String DBName) DBName으로 alarm, subject, timetable 중 하나를 넣으면 됨. 데이터베이스를 사용하기 전에 꼭 해줘야 함! void close(String DBName) 데이터베이스 사용 후에 꼭 해줘야 함! boolean deleteColumn(long id, String DBName) 해당 id 위치의 데이터 삭제, 성공적으로 삭제되면 true를 반환한다. Cursor selectColumns(String DBName) 데이터를 읽어올 때 사용 void deleteAllColumns(String DBName) 모든 데이터 삭제 - 알람 디비 관련 함수
return형 함수 설명 boolean insertAlarm(AlarmData alarmData) 새 데이터를 데이터베이스 마지막 줄에 추가한다. boolean updateAlarm(long id, AlarmData alarmData 해당 위치에 있던 데이터를 새 데이터로 바꿈 - 과목 디비 관련 함수
return형 함수 설명 boolean insertSubject(SubjectData subjectData) 새 데이터를 데이터베이스 마지막 줄에 추가한다. boolean updateSubject(long id, SubjectData subjectData) 해당 위치에 있던 데이터를 새 데이터로 바꿈 - 시간표 디비 관련 함수
return형 함수 설명 boolean insertClasses(String[] classes, rowData mData) 새 데이터를 데이터베이스 마지막 줄에 추가한다. boolean updateClasses(long id, String[] classes, rowData mData) 해당 위치에 있던 데이터를 새 데이터로 바꿈
이 함수들을 사용할 때는 우선 DBOpenHelper 변수를 선언한 후 사용하면 된다.
public class MainActivity extends AppCompatActivity {
DBOpenHelper dbOpenHelper;
//onCreate 내부
dbOpenHelper.open("alarm"); //alarm, subject, timetable 중 하나를 String 형태로 넣으면 됨!
}
1.데이터베이스 생성하기
MainActivity 쪽에서 이미 생성해놓았다. 신경 안써도 됨!
2.cursor를 사용해서 데이터를 불러오기
subject DB를 불러오는 예시이다.
ArrayList<String> arrayIndex = new ArrayList<>();
//onCreate 내부
Cursor cursor = dbOpenHelper.selectColumns(SUBJECT); //일단 커서를 불러온다.
while (cursor.moveToNext()) { //데이터의 첫 행부터 마지막 행까지 차례로 이동
String tempIndex = cursor.getString(cursor.getColumnIndex("_id"));
String tempSubjectName = cursor.getString(cursor.getColumnIndex("subjectName"));
String tempID = cursor.getString(cursor.getColumnIndex("id"));
String tempPW = cursor.getString(cursor.getColumnIndex("password"));
int tempColor = cursor.getInt(cursor.getColumnIndex("color"));
String tempAlarmTime = cursor.getString(cursor.getColumnIndex("alarm_before"));
boolean tempUseAlarm = (cursor.getInt(cursor.getColumnIndex("useAlarm")) == 1); //숫자였던 데이터를 boolean으로 바꿔준다.
arrayIndex.add(tempIndex); //데이터의 id를 순서대로 저장해놓는 것이다. 나중에 데이터 삭제할 때 필요하다.
}
cursor.close(); //커서 다 쓰면 꼭 닫아줘야함
완전 복잡해보이지만 같은 형식이 단순히 반복되고 있다!
자료형 변수이름 = cursor.get자료형(cursor.getColumnIndex("column이름"))
String tempData = cursor.getString(cursor.getColumnIndex("column")) //ex
이처럼 데이터베이스에서 커서를 이용해 데이터를 불러오면 column 별로 각각 불려진다. 하지만 데이터를 추가할 때는 다르다. 3.데이터 추가/수정하기
//데이터 추가
dbOpenHelper.insertSubject(subjectData);
//데이터수정
id = Long.parseLong(arrayIndex.get(position)); //position은 정수임
dbOpenHelper.updateSubject(id, subjectData);
예시에 나온 것은 subject DB 관련 함수인데, 위에 함수 소개할 때 나온것처럼 ( ) 안에는 각 함수에 맞는 인자를 넣어줘야한다.
alarm DB는 AlarmData, subject DB는 SubjectData, timetable DB는 해당 교시 월~일의 과목 이름과 그 교시에 해당하는 rowData를 인자로 가진다.
AlarmData, SubjectData, rowData는 모두 클라스 변수이다. 클라스변수에 대한 설명은 맨 아래에 자세히 쓰여있고, 간단히 사용법만 알아보자면
AlarmData alarmData = new AlarmData();
alarmData.setAlarmName("기상");
이런식으로 알람이름, 시작시간, 사용여부 등을 함수를 이용해서 설정해주면 된다. 어떤 어떤 함수가 있는지는 안드로이드 스튜디오 파일에서 AlarmData, SubjectData, rowData 자바 파일을 찾아 들어가보면 나와있다! 더 자세한 예제는 아래에 있다.
4.데이터 삭제하기
//position은 id가 몇번째 데이터였는지 이다! 0부터 시작함
Long id = Long.parseLong(arrayIndex.get(position)); //불러올 때 저장했던 id
dbOpenHelper.deleteColumn(id, "subject");
DB를 open()
하면 꼭 close()
를 해줘야한다.
@Override
protected void onPause() {
super.onPause();
dbOpenHelper.close(SUBJECT);
} //현재 화면에서 다른 화면으로 넘어갈 때 닫기
@Override
protected void onResume() {
super.onResume();
dbOpenHelper.open(SUBJECT);
} //화면이 다시 시작되면 열기
onPause()
, onResume()
, onCreate()
에 관한건 activity 생명주기나 fragment 생명주기를 참고하면 됨!
최종적으로 사용방법이 정리된 예제를 써보았다. alarm DB 관련해서 써봤다!
public class MainActivity extends AppCompatActivity {
DBOpenHelper dbOpenHelper;
ArrayList<String> arrayIndex = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm_setting);
dbOpenHelper = new DBOpenHelper(this);
dbOpenHelper.open("alarm");
Cursor cursor = dbOpenHelper.selectColumns("alarm");
while (cursor.moveToNext()) {
String tempIndex = cursor.getString(cursor.getColumnIndex("_id"));
String tempAlarmName = cursor.getString(cursor.getColumnIndex("alarmName"));
int tempHour = cursor.getInt(cursor.getColumnIndex("Hour"));
int tempMin = cursor.getInt(cursor.getColumnIndex("Min"));
boolean tempOnOff = (cursor.getInt(cursor.getColumnIndex("onOff")) == 1); //숫자인 onOff를 boolean으로 만들기
//...가져온 데이터를 이용하기(리사이클러뷰에 추가하기 등등)...
AlarmData tempData = new AlarmData();
alarmData.setAlarmName(tempAlarmName);
alarmData.setHour(tempHour);
alarmData.setMin(tempMin);
alarmData.setOnOff(tempOnOff);
adapter.items.add(tempData);
//id 저장하기
arrayIndex.add(tempIndex);
}
cursor.close();
AlarmData alarmData = new AlarmData();
alarmData.setAlarmName("기상");
alarmData.setHour(16);
alarmData.setMin(30);
alarmData.setOnOff(true);
dbOpenHelper.insertAlarm(alarmData);
arrayIndex.add(arrayIndex.get(arrayIndex.size()) + 1); //마지막 id보다 +1해서 저장
dbOpenHelper.updateAlarm(arrayIndex.get(5), alarmData); //6번째 데이터를 alarmData로 바꿈
dbOpenHelper.deleteColumn(arrayIndex.get(2), "alarm"); //3번째 제이터 삭제
}
//온크리에이트 밖에 쓰는 것이다!
@Override
protected void onPause() {
super.onPause();
dbOpenHelper.close("alarm");
}
@Override
protected void onResume() {
super.onResume();
dbOpenHelper.open("alarm");
}
}

intent에 관련된 내용은 이 글에 정리해두었다.
(안봐도 되긴 하지만,,,)
자바를 사용하다보면 C나 python이랑은 다른 점이 드러난다. 자바는 객체지향언어(object oriented)인데, 초보자가 보기에는 개념이 살짝 어려울 수도 있지만, 위의 내용을 보다 낫게 이해하기 위해서 설명하려고 한다.
코딩을 할 때 시작은 변수 선언이다.
int a = 0;
변수에는 int, string, float, char, arrayList, Map등 여러가지 자료형이 있다. 위에 나열한 자료형들은 파이썬이나 C 등 다른 언어에서도 볼 수 있다. 하지만 TextView, RecyclerView, Button 등등은 안드로이드 스튜디오에서만 볼 수 있는 형태이다. 이 친구들은 안드로이드 스튜디오에서 미리 어떤 형태인지, 어떤 기능을 가지는지 클라스(class)로 정의해놓은 것이다.
클라스 변수는 이들과 비슷하다고 생각하면 된다(실제로 같은 개념은 아닌데, 초보자 입장에선 이게 편하다). 클라스를 변수로 사용하자! 이게 객체지향의 특징인 것 같다.
예를 들어서 여기 hat이라는 class를 정의한다고 해보자. 모자는 여러가지 속성을 가질 것이다.
public class hat {
int height;
int color;
boolean isHandmade;
}
뭐 등등등... 이제 다른 클라스에서 이 친구를 불러와보자.
public class main {
hat myHat;
}
이런 식으로 클라스를 변수로 사용할 수 있다. 그리고, 모자의 속성들 앞에 public을 붙여주거나 getter, setter를 만들면
public class hat {
public int height;
public int color;
public boolean isHandmade;
//보통 getter setter를 정의하고 이 변수들은 private로 둔다.
//getter
public int getHeight() {
return height;
}
//setter
public void setHeight(int height) {
this.height = height;
//this.height가 맨 윗줄 height이고, 그냥 height가 함수의 인자이다.
}
//...다른 변수들에 대한 getter와 setter 정의...
}
다른 클라스에서도 접근 할 수 있다.
public class main {
hat myHat;
myHat.height = 2; //public 변수에 접근하는 방법
myHat.setHeight(4); //setter 사용
int height = myHat.getHeight(); //getter 사용
//height라는 정수형 변수는 4라는 값을 가지게 되었다.
}
hat 변수를 여러개 만들면 각각 다른 값을 가질 수 있다.
public class main {
hat myHat1;
hat myHat2;
myHat1.setHeight(4);
myHat1.setColor(Color.parseColor("#000000"));
myHat1.setHandmade(true);
//myHat1은 길이가 4고 검정색이며 수공예 제품이다.
myHat2.setHeight(7);
myHat2.setColor(Color.parseColor("#FFFFFF"));
mtHat2.setHandmade(false);
//myHat2는 길이가 7이고 하얀색이며 수공예 제품은 아니다.
}
이걸 이용하면 다양한 것들을 할 수 있는데, 예를 들면
public class main {
ArrayList<hat> hatItems = new ArrayList<>();
//arrayList의 형식으로 사용하거나(리사이클러뷰에서 많이 쓰임)
void function(hat myHat) {...}
//함수의 인자로도 사용할 수 있다.
}
나도 객체지향에 대해서 완벽하게 이해한건 아니지만,,, 객체지향적 사고는 많은 (어려운!) 자바 예제들을 이해하는데 많은 도움을 주었담ㅎㅎ