안녕, 세상!

12. 데이터 관리 본문

It공부/안드로이드

12. 데이터 관리

dev_Lumin 2020. 8. 29. 17:14

(1) SQLite 개요

SQLite는 모바일 환경에 최적화된 데이터베이스입니다.

기본적 개념과 동작은 PC용 데이터베이스와 거의 동일합니다.

 

① 데이터베이스의 개념

 

데이터베이스의 정의

지속적이고 대량으로 발생하는 다양한 형태의 정보를 보관하는데 기존의 파일 시스템으로 한계가 있어서 고안된 데이터를 보관, 관리하기 위한 시스템입니다.

대용량의 데이터 집합을 체계적으로 구성해 놓은 것으로 여러 사용자나 시스템이 서로 공유할 수 있어야 합니다.

 

데이터베이스 관리 시스템(DataBase Mangement System, DBMS)은 이러한 데이터 베이스를 관리하는 시스템 또는 소프트웨어를 말합니다.

DBMS는 크게 계층형(hierarchical), 망형(network), 관계형(relational), 객체지향형(object-oriented), 객체 관계형(object-relational) 등의 유형으로 나뉩니다.

실제로 관계형 DBMS를 가장 많이 사용합니다.

 

 

관계형 DBMS(RDBMS)

SQL server, Access, Oracle Database, DB2 등은 모두 관계형 DBMS에 속하며 SQLite 역시 RDBMS입니다.

관계형 DBMS는 다른 DBMS에 비해 변화에 쉽게 순응할 수 있는 구조로 되어 있고, 유지 및 보수 측면에서도 편리하다는 장점이 있습니다.

대용량 데이터 관리와 데이터 무결성을 잘 보장해주기 때문에 데이터에 동시에 접근하는 응용 프로그램을 사용한다면 RDBMS가 최적의 DBMS입니다.

 

RDBMS의 단점은 시스템 자원을 많이 차지하기 때문에 시스템이 전반적으로 느리다는 점입니다.

그러나 최근에는 하드웨어의 발전으로 단점이 많이 보완되었습니다.

모바일 환경에서 동작하는 SQLite는 관계형 DBMS의 단점을 극복하기 위해 동시 접근이나 대용량 데이터 관리에 제한을 두고 있지만 RDBMS의 표준 SQL이나 개념은 동일하게 적용됩니다.

 

 

데이터베이스 관련 용어

데이터베이스를 구축하려면 '데이터베이스 모델링'을 먼저 해야 합니다.

데이터베이스 모델링은 현실 세계에서 사용되는 데이터를 DBMS안에 어떻게 옮길 것인지 결정하는 과정입니다.

보통 정보들을 단편적으로 저장하는 것이 아니라 테이블이라는 표 형태의 틀에 맞춰서 정보를 넣습니다.

 

데이터 : 하나하나의 단편적인 정보

테이블 : 데이터가 표 형태로 정리된것을 말함, 데이터베이스에 여러 개의 테이블들이 존재함

데이터베이스(DB) : 테이블이 저장되는 장소로 주로 원통 모양으로 표현함. 각 DB는 고유한 이름을 가져야 함

열(column 또는 field) : 각 테이블은 1개 이상의 열로 구성됨

열 이름 : 각 열을 구별하는 이름이며 테이블 안 데이터의 카테고리 역할을 함. 열 이름은 각 테이블 안에서 중복 안됨.

데이터 형식 : 열의 데이터 형식을 말함

: 실제 데이터를 말함

 

 

 

② SQLite에서의 데이터베이스 구축

안드로이드 시스템에 SQLite가 이미 설치되어 있기 때문에 DBMS 설치 과정은 생략합니다.

 

1. 명령 프롬프트를 실행해서 adb.exe가 있는 폴더로 이동합니다.

cd C:\Users\사용자명\AppData\Local\Android\Sdk\platform-tools

DIR adb.exe

 

 

2. 명령 프롬프트에 다음 명령을 차례로 수행해서 SQLite 접속할 준비를 합니다.

 

adb root                                     //root 권한으로 adb를 재시작함

adb shell                                     // 셸을 실행함. AVD 내부로 들어가는 명령

cd /data/data/프로젝트패키지명       // 현재 디렉터리 변경

ls -l                                            // 현재 디렉터리 파일 및 디렉터리 목록 출력

mkdir databases                           // mkdir은 디렉터리를 생성함

cd databases              

pwd

 

 

3. 데이터 베이스 생성

sqlite3 명령을 실행하면서 데이터베이스 이름을 지정합니다.

 

sqlite3 myDB   // myDB는 데이터베이스 이름

 

 

4. 테이블 생성

테이블 생성하는 SQL 문의 원형은 다음과 같습니다.

 

CREATE TABLE 테이블이름 (열이름 데이터형식, 열이름2 데이터형식, ...);

 

입력은 다음과 같이 합니다.

 

CREATE TABLE userTable ( id char(4), userName char(18), email char(19), birthYear int);

.table                        // 현재 데이터베이스의 테이블 목록을 보여줌

.schema userTable       // 해당 테이블의 열, 데이터 형식 등의 정보를 보여줌

 

SQL 규칙문

SQL문은 대소문자를 구분하지 않습니다.

또한 모든 SQL 문의 끝에 세미콜론(;)을 붙여야 합니다.

예외적으로 SQLite 자체 명령은 소문자로 써야 하고 시작에 마침표(.)를 붙이며 끝에 세미콜론을 붙이지 않아도 됩니다.

자주 사용하는 SQLite 명령

.table : 현재 데이터베이스의 테이블 목록을 보여줌

.schema 테이블이름 : 테이블 열, 데이터 형식 등의 정보를 보여줌

.header on : SELECT문으로 출력할 때 헤더를 보여줌

.mode column : SELECT문으로 출력할 때 칼럼 모드로 출력해줌

.exit : SQLite를 종료함

 

 

 

5. 데이터 입력

생성한 테이블에 행 데이터를 입력하는 SQL 문의 원형은 다음과 같습니다.

 

INSERT INTO 테이블이름 VALUES(값1, 값2, ... )

 

INSERT INTO userTable VALUES('a' , 'Alice', 'Alice@naver.com', 1993);

INSERT INTO userTable VALUES('b' , 'Bob' , 'Bob@naver.com', 1994);

INSERT INTO userTable VALUES('c' , 'Chris' , 'Chris@naver.com', 1996);

INSERT INTO userTable VALUES('d', 'David' , 'David@naver.com', 1998);

 

 

 

 

6. 데이터 조회 및 활용

데이터를 조회, 활용하는 SQL문은 SELECT인데 주로 WHERE절과 함께 사용합니다.

일반적 원형은 다음과 같습니다.

 

SELECT 열이름1, 열이름2, ... FROM 테이블이름 WHERE 조건;

 

다음은 데이터를 조회하는 몇 가지 예시입니다.

.header on                         

.mode column

SELECT * FROM userTable;      //userTable의 모든 데이터를 출력

SELECT id, birthYear FROM userTable WHERE birthYear <= 1997;    

SELECT * FROM userTable WHERE id = 'd';

데이터베이스의 데이터를 확인할 수 있습니다.

모두 확인했으면 .exit와 exit로 SQLite를 종료합니다.

 

 

 

(2) SQLite 활용

① SQLite 프로그래밍

안드로이드 앱에서 SQLite를 사용할 때는 일반적으로 SQLiteOpenHelper 클래스, SQLiteDatabase 클래스, Cursor인터페이스를 활용합니다.

 

SQLiteOpenHelper 클래스를 상속받은 새로운 클래스를 생성합니다.

생성한 클래스에 데이터베이스 파일과 테이블을 생성하는 내용을 코딩합니다.

SQLiteOpenHelper의 getWriteableDatabase()를 이용하면 SQLiteDatabase를 반환받고, execSQL() 또는 rawQuery() 등으로 SQL문을 실행합니다.

SELECT문은 Cursor 인터페이스를 반환받은 후에 반복해서 테이블의 행 데이터에 접근하게 됩니다.

 

 

SQLite 관련 클래스 및 인터페이스와 메소드

클래스 or 인터페이스 메소드 용도
SQLiteOpenHelper 클래스 생성자 DB생성
onCreate() 테이블 생성
onUpgrade() 테이블 삭제 후 다시 생성
getReadableDatabase() 읽기 전용 DB열기, SQLiteDatabase 반환
getWritableDatabase() 읽고 쓰기용 DB열기, SQLiteDatabase 반환
SQLiteDatabase 클래스 execSQL() SQL문(Insert/Update/Delete) 실행
close() DB닫기
query(), rawQuery() Select 실행 후 커서 반환
Cursor 인터페이스 moveToFirst() 커서의 첫 행으로 이동
moveToLast() 커서의 마지막 행으로 이동
moveToNext() 현재 커서의 다음 행으로 이동

 

 

 

activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:orientation="horizontal">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="이름: " />
    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/edtName"
        android:layout_weight="1" />
    </LinearLayout>
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:orientation="horizontal" >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="인원: " />
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/edtNum" />
    </LinearLayout>
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:orientation="horizontal" >
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/btnInit"
            android:text="초기화" />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/btnInsert"
            android:text="입력" />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/btnView"
            android:text="조회" />
    </LinearLayout>
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="8"
        android:background="#00FF00"
        android:orientation="horizontal">
        <EditText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:id="@+id/edtNameResult" />
        <EditText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:id="@+id/edtNumberResult" />
    </LinearLayout>
</LinearLayout>
cs

 

 

MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
 
public class MainActivity extends AppCompatActivity {
    myDBHelper myHelper;
    EditText edtName, edtNumber, edtNameResult, edtNumberResult;
    Button btnInit, btnInsert, btnView;
    SQLiteDatabase sqlDB;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("Kpop그룹 관리 DB");
 
        edtName=(EditText) findViewById(R.id.edtName);
        edtNumber = (EditText) findViewById(R.id.edtNum);
        edtNameResult = (EditText) findViewById(R.id.edtNameResult);
        edtNumberResult = (EditText) findViewById(R.id.edtNumberResult);
        btnInit = (Button) findViewById(R.id.btnInit);
        btnInsert= (Button) findViewById(R.id.btnInsert);
        btnView = (Button) findViewById(R.id.btnView);
 
        myHelper = new myDBHelper(this);  // myDBHelper 객체 생성
        btnInit.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v){
                sqlDB = myHelper.getWritableDatabase(); //groupDB를 쓰기용 데이터베이스로 열고
                myHelper.onUpgrade(sqlDB,1,2); // onUpgrade()메소드 호출해서
                //groupTB 테이블이 있으면 삭제한 후 새로 생성. 2,3번째 파라미터는 받아도 안쓰니 아무숫자 써도됨
                sqlDB.close(); // 데이터베이스 닫음
            }
        });
 
        btnInsert.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v){
                sqlDB=myHelper.getWritableDatabase();
                sqlDB.execSQL("INSERT INTO groupTB VALUES ( '"+edtName.getText().toString()+"',"+edtNumber.getText().toString()+");");
                // Insert문을 생성한 다음 execSQL()메소드로 실행함
                sqlDB.close();
                Toast.makeText(getApplicationContext(),"입력됨",0).show();
            }
        });
 
        btnView.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v){
                sqlDB = myHelper.getReadableDatabase();
                Cursor cursor;  // 커서 선언
                cursor = sqlDB.rawQuery("SELECT * FROM groupTB;"null); // 모든 테이블 조회후 커서에 대입
                // 즉 테이블에 입력된 모든 행 데이터가 커서 변수에 들어있는 상태가 되며, 현재는 첫번째 행을 가리킴
 
                String strNames = "그룹 이름"+"\r\n"+"------"+"\r\n";
                String strNumbers = "인원"+"\r\n"+"------"+"\r\n";
 
                while(cursor.moveToNext()){ // 행 데이터의 개수 만큼 반복
                    strNames += cursor.getString(0+"\r\n";
                    strNumbers += cursor.getString(1)+"\r\n";
                }
 
                edtNameResult.setText(strNames); // 결과에디트텍스트위젯에 출력
                edtNumberResult.setText(strNumbers);
 
                cursor.close();
                sqlDB.close();  // 커서와 데이터베이스를 닫음
            }
        });
    }
 
    public class myDBHelper extends SQLiteOpenHelper{
        public myDBHelper(Context context){  // 생성자
            super(context, "groupDB",null,1);
            // 두번째 파라미터는 새로 생성될 데이터베이스의 파일명 지정
            // 마지막 파라미터는 데이터베이스 버전을 처음에는 1을 지정
        }
 
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("CREATE TABLE groupTB (gName CHAR(20) PRIMARY KEY,gNumber INTEGER);");
        }
 
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS groupTB");
            onCreate(db);
 
        }
    }
}
cs

 61 : moveToNext() 메소드는 커서 변수의 다음 행으로 넘어가고 만약 다음 행이 없다면 false를 반환함

 

이름과 인원에 데이터를 넣고 '입력'버튼을 누르면 토스트가 잘 나오면서 데이터베이스에 데이터가 저장됩니다.

 

'조회' 버튼을 누르면 데이터베이스의 테이블의 데이터들을 조회할 수 있습니다.

'초기화' 버튼을 누르면 데이터베이스의 테이블의 데이터들이 초기화됩니다.

 

직접 명령 프롬프트를 사용해 데이터베이스에 접근해서 데이터를 확인할 수 있습니다.

cd C:\Users\사용자명\AppData\Local\Android\Sdk\platform-tools

adb root

adb shell

# cd /data/data/패키지명

# sqlite3 groupDB

sqlite> .header on

sqlite> .mode column

sqlite> SELECT * FROM groupTB;

 

 

 

 

 

② SQLite GUI 툴

지금까지는 SQLite에 접근하기 위해서 명령 프롬프트를 이용했지만 DB Browser for SQLite라는 GUI툴을 사용할 수 도 있습니다.

SQLite Developer이라는 툴도 있습니다.

 

 

'It공부 > 안드로이드' 카테고리의 다른 글

14. 구글지도  (0) 2020.08.31
13. 멀티미디어  (0) 2020.08.30
11. 어댑터뷰  (0) 2020.08.27
10. 액티비티와 인텐트  (0) 2020.08.26
9. 그래픽  (0) 2020.08.25
Comments