안드로이드 데이터베이스(DB) 프로그래밍 3. [SQLiteDatabase 사용 예제] (Android Database 3)

2017. 4. 14. 17:52


1. SQLiteDatabase.

안드로이드에서 기본적으로 제공하는 데이터베이스는 SQLite입니다. SQLite는 관계형 데이터베이스이며, 관계형 데이터베이스에 대한 개념과 용어에 대해서는 [안드로이드 데이터베이스(DB) 프로그래밍 1 - 관계형 데이터베이스]에서 간단히 설명하였습니다.


안드로이드에서 SQLite 데이터베이스를 사용할 때 가장 중요한 핵심 요소는 SQLiteDatabase 클래스입니다. SQLite 데이터베이스를 다루는 기능들이 SQLiteDatabase 클래스에 정의되어 있죠.


SQLite 데이터베이스를 열고 SQLiteDatabase 클래스의 객체를 획득하는 과정은 [안드로이드 데이터베이스(DB) 프로그래밍 2 - SQLiteDatabase]에서 설명하였습니다. 그리고 획득한 SQLiteDatabase 객체를 사용하여 데이터를 추가하거나, 삭제, 조회하는 방법에 대해서도 설명하였죠.


그럼, 지금부터는 실질적인 앱 작성을 통해 SQLite 데이터베이스에 데이터를 저장하고, 읽어들이는 방법에 대해 알아보도록 하겠습니다. 하지만 이 글에서 작성하는 예제는 SQLiteDatabase의 사용 방법을 소개하는데 초점이 맞춰져있기 때문에, 실제 앱 구현에 적용하기에는 다소 부족한 것이 사실입니다.


그러므로 본문의 예제는 SQLiteDatabase에 대한 이해 용도로만 살펴봐주시기 바라며, 좀 더 다듬어진 예제는 따로 정리하여 설명하겠습니다.

2. SQLiteDatabase 사용 예제

이제 앱 작성을 통해 SQLiteDatabase를 사용하여 데이터를 저장하고, 조회하는 방법에 대해 살펴보도록 하겠습니다.


예제로 작성되는 앱의 실행 화면은 아래 그림과 같이 구성됩니다.

예제 MainActivity 레이아웃


데이터베이스는 아래와 같은 구조를 가집니다.

데이터베이스 테이블 구조


참고로, 보통 데이터베이스를 사용할 때는 동일한 컬럼(Column)에 따라 식별된 많은 양의 로우(Row)를 저장하는데, 본문의 예제는 하나의 로우(Row)만 저장합니다. 이는 앱의 설정 정보 등을 저장할 때 사용하는 방법인데, 설정 정보는 최종적으로 저장된 단 하나의 값만 있으면 되기 때문입니다.

2.1 MainActivity의 레이아웃 작성.

앱 작성 시, 첫 번째로 할 일은 MainActivity의 레이아웃을 작성하는 것입니다. 앞서 설계한 예제 화면 구성도에 따라, 아래와 같이 MainActivity에 표시될 레아아웃 XML 코드를 작성합니다.

[STEP-1] "activity_main.xml" - MainActivity의 레이아웃 XML 코드 작성.
    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:stretchColumns="1">

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:textSize="24sp"
                android:text="No" />

            <EditText
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="20dp"
                android:textSize="24sp"
                android:id="@+id/editTextNo"/>
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:textSize="24sp"
                android:text="Name" />

            <EditText
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="20dp"
                android:textSize="24sp"
                android:id="@+id/editTextName"/>
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:textSize="24sp"
                android:text="Phone" />

            <EditText
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="20dp"
                android:textSize="24sp"
                android:id="@+id/editTextPhone"/>
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:textSize="24sp"
                android:text="Over20" />

            <CheckBox
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="20dp"
                android:id="@+id/checkBoxOver20"/>
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_span="2">

                <Button
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:textSize="24dp"
                    android:text="Save"
                    android:id="@+id/buttonSave" />

                <Button
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:textSize="24dp"
                    android:text="CLEAR"
                    android:id="@+id/buttonClear" />
            </LinearLayout>

        </TableRow>
    </TableLayout>

2.2 SQLiteDatabase 클래스 변수 선언 및 데이터베이스 열기.

다음 단계로, SQLite 데이터베이스를 사용하는데 있어 가장 중요한 요소인, SQLiteDatabase 클래스의 객체를 초기화하는 코드를 작성합니다. SQLiteDatabase 클래스 객체는 MainActivity의 전역에서 사용되므로, 클래스 변수로 선언합니다. 참고로 SQLiteDatabase 초기화에 관한 내용은 [안드로이드 데이터베이스(DB) 프로그래밍 2 - SQLiteDatabase]에서 확인할 수 있습니다.


그리고 최초 앱 실행 시, SQLite 데이터베이스 파일이 존재하지 않으면 새로운 파일을 만들고 데이터베이스를 열도록 SQLiteDatabase.openOrCreateDatabase() 함수를 사용합니다. 이러한 과정은 init_database() 라는 함수에 작성하고, MainActivity의 onCreate() 함수에서 호출하도록 만듭니다.

[STEP-2] "MainActivity.java" - SQLDatabase 클래스 변수 선언 및 초기화.
public class MainActivity extends AppCompatActivity {

    SQLiteDatabase sqliteDB ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // ... 코드 계속
        sqliteDB = init_database() ;

        // 코드 계속  ...
    }

    // ... 코드 계속
    private SQLiteDatabase init_database() {

        SQLiteDatabase db = null ;
        // File file = getDatabasePath("contact.db") ;
        File file = new File(getFilesDir(), "contact.db") ;

        System.out.println("PATH : " + file.toString()) ;
        try {
            db = SQLiteDatabase.openOrCreateDatabase(file, null) ;
        } catch (SQLiteException e) {
            e.printStackTrace() ;
        }

        if (db == null) {
            System.out.println("DB creation failed. " + file.getAbsolutePath()) ;
        }

        return db ;
    }

    // 코드 계속  ...
}

2.3 SQLite 데이터베이스를 새로 만들 때, 테이블 생성. (CREATE TABLE)

SQLite 데이터베이스를 열어 SQLiteDatabase에 대한 참조를 확보했다면, 이제 데이터베이스 테이블에 데이터를 추가하거나 조회할 수 있습니다. 그런데 만약 데이터베이스 파일을 새로 생성한 경우라면 테이블은 존재하지 않기 때문에, CREATE TABLE 문을 사용하여 테이블을 생성해야 합니다. 물론 테이블이 존재하는 경우도 가정해야겠죠. 이를 위해 CREATE TABLE 문에 IF NOT EXISTS를 더하여 테이블을 생성합니다.

    CONTACT_T 테이블 생성을 위한 SQL 문.
CREATE TABLE IF NOT EXISTS CONTACT_T (NO INTEGER NOT NULL, NAME TEXT, PHONE TEXT, OVER20 INTEGER)

아래와 같이 init_table() 이라는 함수를 새로 추가하고, onCreate()에서 init_database() 함수 다음에 호출하도록 작성합니다.

[STEP-3] "MainActivity.java" - SQLDatabase 클래스 변수 선언 및 초기화.
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // ... 코드 계속

        sqliteDB = init_database() ;

        init_tables() ;

        // 코드 계속  ...
    }

    // ... 코드 계속
    private void init_tables() {

        if (sqliteDB != null) {
            String sqlCreateTbl = "CREATE TABLE IF NOT EXISTS CONTACT_T (" +
                    "NO "           + "INTEGER NOT NULL," +
                    "NAME "         + "TEXT," +
                    "PHONE "        + "TEXT," +
                    "OVER20 "       + "INTEGER" + ")" ;

            System.out.println(sqlCreateTbl) ;

            sqliteDB.execSQL(sqlCreateTbl) ;
        }
    }

    // 코드 계속  ...
}

2.4 앱 실행 시, 테이블 데이터 조회하여 표시. (SELECT)

최초 앱이 실행되면 데이터베이스에 저장된 데이터를 로딩하여 화면에 표시하는 코드를 작성합니다. [안드로이드 데이터베이스(DB) 프로그래밍 2 - SQLiteDatabase]에서 설명한대로, 데이터 조회를 위한 SELECT문 실행 결과 데이터를 Cursor 타입으로 리턴받은 다음, moveToNext() 함수를 통해 커서로 전달된 레코드 집합(Record Set)을 탐색합니다.

    CONTACT_T 테이블에서 모든 데이터를 조회하는 SQL 문.
SELECT * FROM CONTACT_T

데이터를 조회하는 함수는 load_values() 라는 함수에 작성하고, MainActivity의 onCreate() 함수에서 init_table() 함수 바로 다음에 호출합니다.

[STEP-4] "MainActivity.java" - SELECT 문을 통해 데이터 조회 및 표시.
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // ... 코드 계속

        sqliteDB = init_database() ;
        init_tables() ;

        load_values() ;

        // 코드 계속  ...
    }

    // ... 코드 계속
    private void load_values() {

        if (sqliteDB != null) {
            String sqlQueryTbl = "SELECT * FROM CONTACT_T" ;
            Cursor cursor = null ;

            // 쿼리 실행
            cursor = sqliteDB.rawQuery(sqlQueryTbl, null) ;

            if (cursor.moveToNext()) { // 레코드가 존재한다면,
                // no (INTEGER) 값 가져오기. 
                int no = cursor.getInt(0) ;
                EditText editTextNo = (EditText) findViewById(R.id.editTextNo) ;
                editTextNo.setText(Integer.toString(no)) ;

                // name (TEXT) 값 가져오기
                String name = cursor.getString(1) ;
                EditText editTextName = (EditText) findViewById(R.id.editTextName) ;
                editTextName.setText(name) ;

                // phone (TEXT) 값 가져오기
                String phone = cursor.getString(2) ;
                EditText editTextPhone = (EditText) findViewById(R.id.editTextPhone) ;
                editTextPhone.setText(phone) ;

                // over20 (INTEGER) 값 가져오기.
                int over20 = cursor.getInt(3) ;
                CheckBox checkBoxOver20 = (CheckBox) findViewById(R.id.checkBoxOver20) ;
                if (over20 == 0) {
                    checkBoxOver20.setChecked(false) ;
                } else {
                    checkBoxOver20.setChecked(true) ;
                }
            }
        }
    }

    // 코드 계속  ...
}

2.5 입력 데이터 저장하기. (INSERT INTO)

이제 "Add" 버튼을 누르면, 데이터를 저장하는 기능을 구현하겠습니다. 데이터를 추가할 때는 INSERT INTO문을 사용합니다. 그런데 예제에서는 테이블 내에 단 하나의 레코드만 저장하므로, 저장되어 있는 레코드를 지우고 나서 새로 추가하도록 만들겠습니다.

    CONTACT_T 테이블에서 데이터를 추가하는 SQL 문.
INSERT INTO CONTACT_T (NO, NAME, PHONE, OVER20) VALUES (1, 'ppotta', '010-8888-9999', 1)
    CONTACT_T 테이블의 모든 레코드를 삭제하는 SQL 문.
DELETE FROM CONTACT_T

데이터를 저장하는 코드는 save_values() 함수에 작성한 다음, buttonSave 버튼의 클릭 이벤트 핸들러에서 해당 함수에서 호출하도록 작성합니다.

[STEP-5] "MainActivity.java" - 데이터 저장하기.
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // ... 코드 계속

        Button buttonSave = (Button) findViewById(R.id.buttonSave) ;
        buttonSave.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                save_values() ;
            }
        });

        // 코드 계속  ...
    }

    // ... 코드 계속
    private void save_values() {
        if (sqliteDB != null) {
            
            // delete
            sqliteDB.execSQL("DELETE FROM CONTACT_T") ;

            EditText editTextNo = (EditText) findViewById(R.id.editTextNo) ;
            String noText = editTextNo.getText().toString() ;
            int no = 0 ;
            if (noText != null && !noText.isEmpty()) {
                no = Integer.parseInt(noText) ;
            }

            EditText editTextName = (EditText) findViewById(R.id.editTextName) ;
            String name = editTextName.getText().toString() ;

            EditText editTextPhone = (EditText) findViewById(R.id.editTextPhone) ;
            String phone = editTextPhone.getText().toString() ;

            CheckBox checkBoxOver20 = (CheckBox) findViewById(R.id.checkBoxOver20) ;
            boolean isOver20 = checkBoxOver20.isChecked() ;

            String sqlInsert = "INSERT INTO CONTACT_T " +
                    "(NO, NAME, PHONE, OVER20) VALUES (" +
                    Integer.toString(no) + "," +
                    "'" + name + "'," +
                    "'" + phone + "'," +
                    ((isOver20 == true) ? "1" : "0") + ")" ;

            System.out.println(sqlInsert) ;

            sqliteDB.execSQL(sqlInsert) ;
        }
    }

    // 코드 계속 ...
}

2.6 데이터 삭제하기. (DELETE)

마지막으로 "Clear" 버튼이 눌려지면 입력된 모든 내용을 지우고, 테이블의 데이터를 삭제합니다. 이를 위해 DELETE 문을 사용합니다.

    CONTACT_T 테이블의 모든 레코드를 삭제하는 SQL 문.
DELETE FROM CONTACT_T

delete_values() 함수에 데이터 삭제 코드를 작성하고, buttonClear 버튼이 눌려지면 호출하도록 만듭니다.

[STEP-6] "MainActivity.java" - 데이터 삭제하기.
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // ... 코드 계속

        Button buttonClear = (Button) findViewById(R.id.buttonClear) ;
        buttonClear.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                delete_values() ;
            }
        });

        // 코드 계속  ...
    }

    // ... 코드 계속

    private void delete_values() {
        if (sqliteDB != null) {
            String sqlDelete = "DELETE FROM CONTACT_T" ;

            sqliteDB.execSQL(sqlDelete) ;

            EditText editTextNo = (EditText) findViewById(R.id.editTextNo) ;
            editTextNo.setText("") ;

            EditText editTextName = (EditText) findViewById(R.id.editTextName) ;
            editTextName.setText("") ;

            EditText editTextPhone = (EditText) findViewById(R.id.editTextPhone) ;
            editTextPhone.setText("") ;

            CheckBox checkBoxOver20 = (CheckBox) findViewById(R.id.checkBoxOver20) ;
            checkBoxOver20.setChecked(false) ;
        }
    }
}

3. 예제 실행 화면

예제를 작성하고 실행하면, 아래와 같은 실행 화면이 나타납니다.

예제 실행 화면


각 필드에 값을 입력하고 "SAVE" 버튼을 누르면, 입력된 값들이 데이터베이스에 저장됩니다. 그리고 앱을 다시 실행하면, 데이터베이스에 저장된 값이 화면에 표시되는 것을 확인할 수 있습니다.

데이터베이스 저장 및 저장된 데이터 표시


"CLEAR" 버튼을 누르면 데이터베이스에 저장된 값이 지워지고, 화면에 표시된 내용이 초기화되는 것을 확인할 수 있습니다.

데이터베이스 레코드 삭제 및 표시 값 초기화


4. 참고.

.END.


ANDROID 프로그래밍/DB , , , , , , , ,

  1. 멋진 샘플 잘 보았습니다.
    혹시 이 페이지 소스 보고 이해가 부족한 분 참고하시라고 링크 남깁니다.
    Database 프로젝트(1) 기초적인 이해/[Android]
    http://blog.daum.net/andro_java/1241
    감사합니다.

  2. 방문해 주셔서 감사합니다.

  3. Blog Icon
    1

    내용을 입력하고 save를 누르면 앱이 꺼져버리네요..
    어떤점이 문제인지 모르겠습니다..

  4. 올려주신 증상 만으로는 문제점을 확인할 수가 없을 것 같습니다. 조금 번거로우시더라도, 앱이 비정상 종료될 때의 에러 메시지를 복사하여 올려주시면 도움을 드리기가 더 용이할 것 같습니다.

    그리고 작성하신 코드와 본문의 내용을 다시 한번 비교해보시길 바래요. 제가 직접 실행해보고 올려놓은 내용이라 그대로만 하면 문제는 생기지 않을 것입니다.

    확인해보시고, 다시 글 올려주시길 부탁드릴게요.
    감사합니다.

  5. 저도 같은 현상이네요 저장하기 하면 크래시 나는데
    android.database.sqlite.SQLiteException: table LOGIN has no column named LOGIN_ID (code 1): , while compiling: INSERT INTO LOGIN (NO, LOGIN_ID, PW) VALUES (17039369,'ㅋㅇ','ㅇㅌ')
    #################################################################
    Error Code : 1 (SQLITE_ERROR)
    Caused By : SQL(query) error or missing database.
    (table LOGIN has no column named LOGIN_ID (code 1): , while compiling: INSERT INTO LOGIN (NO, LOGIN_ID, PW) VALUES (17039369,'ㅋㅇ','ㅇㅌ'))
    #################################################################

  6. 쿼리는 수정핸쓴데
    잘못된게 없는거 같아요

    private void init_tables() {
    if (sqliteDB != null) {
    String sqlCreateTbl = "CREATE TABLE IF NOT EXISTS LOGIN (" +
    "NO " + "INTEGER NOT NULL," +
    "LOGIN_ID " + "TEXT," +
    "PW " + "TEXT" +
    ")";
    System.out.println(sqlCreateTbl);
    sqliteDB.execSQL(sqlCreateTbl);
    }
    }

  7. 아래 내용 참고 바랍니다.

  8. insert 쿼리
    String sqlInsert = "INSERT INTO LOGIN " + "(NO, LOGIN_ID, PW) VALUES (" +
    Integer.toString(no) + "," +
    "'" + id + "',"+
    "'" + pw + "'"+
    ")";

  9. 일단 질문글에 올려주신 코드를 보면, 잘못된 내용이 전혀 없고 문제가 발생하는 것이 납득이 가지 않는 상황입니다.

    하지만 이전에 했던 작업에 대해 상기해볼 필요는 있을 듯 하네요.

    혹시 LOGIN 이라는 테이블을 설계할 때, 처음에는 LOGIN_ID 라는 컬럼 대신 다른 이름을 사용하지 않았나요?

    저의 상상만으로 문제 사항을 되짚어보자면,
    처음에 LOGIN_ID가 아닌 다른 컬럼명으로 테이블을 만들었고, 테이블이 생성된 다음 컬럼명을 LOGIN_ID로 바꾼 것이 아닌가 생각됩니다.
    그리고 나서 LOGIN_ID로 테이블을 접근하니, 존재하지 않는 컬럼이라고 나오는 거라 생각되네요.

    일단 이 문제인지 여부를 정확히 판단하기 위해, 최초 앱이 시작되고 "CREATE TABLE ..." 명령을 실행하기 전에, "DROP TABLE ..." 명령을 한번 실행해주세요. 그런 다음 결과를 확인해보시기 바랍니다.

    아마 정상적으로 수행되지 않을까... 생각됩니다.

    감사합니다.

  10. Blog Icon
    지니

    안드로이드 앱 혼자 만들어보고 있었는데 이해하기 쉽게 설명을 해주셔서 많은 도움이 되었습니다. 감사합니다!
    그런데 궁금한 것이 있어요.
    앱 초기 실행했을 때 listview로 뿌려지게 하려면 어떻게 해야 할까요..?
    load_data() 에서 db에 저장된 내용을 전부 listview로 생성되게 하면 될까요?
    그리고 db에 데이터가 잘 저장되었는지 터미널로 확인하는 방법 같은게 없을까요? ^^
    감사합니다 좋은 하루 되세요~!

  11. 말씀하신대로, 앱이 실행될 때 db에 저장된 데이터를 모두 읽어들인 다음, listview에 추가하면 됩니다.
    단, db에 저장된 데이터가 많아서 로딩 시간이 오래 걸리면 ANR이 걸릴 수가 있으니, 그런 경우에는 별도의 스레드에서 수행하면 됩니다. 다루는 데이터에 따라 선택적으로 구현하시면 됩니다.

    그리고 안드로이드에는 db를 직접
    관리할 수 있는 sqlite3 라는 프로그램이 제공되는데요. 터미널에서 "sqlite3"를 입력하시면 실행하실 수 있습니다.

    .help 명령을 통해 도움말을 확인하실 수 있고, 웹에서 찾아보시면 사용법에 대해 알아보실 수 있을 것입니다. (저는 관련 글을 계획만 하고 아직 정리를 못했네요.)

    추가적으로 도움 드릴 내용이 있으면 다시 질문글 남겨주세요.

    감사합니다.

  12. Blog Icon
    GODISGOOD

    대애애애애애바아아아아아악....ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ
    처음으로 db예제가 제대로 돌아가요ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ
    진짜.... 설명 짱짱짱짱 감사합니다 너무무무뭄

  13. 도오오오오오오오우우우우움이 된 것 같아서 다행입니다.... ㅠㅠ
    격한 감정이 느껴지네요. ㅠㅠ
    도움이 필요하면 언제든 질문글 남겨주세요.

    감사합니다.

  14. Blog Icon
    student

    잘 보았습니다
    좋은 강의 감사합니다! 글이 되게 읽기가 쉽네요

  15. 칭찬 글 남겨주셔서 감사합니다.
    최대한 쉽게 적으려고 노력했지만, 부족함을 많이 느끼네요.

    감사합니다.

  16. Blog Icon
    빤딱

    다른 클래스에서 이 데이터베이스를 사용하려면 어떻게 해야 할까요??ㅠㅠ

  17. "그냥 사용하시면 됩니다."

    답변이 넘 성의가 없게 느껴지시나요? ^^
    하지만 그게 다 입니다. 그냥 사용하시면 됩니다.
    어려워 하지 마세요. 그냥 구현하시면 됩니다.

    변수 추가하고, 메서드 추가하고, 그냥 구현하세요.

    안해보니 어려운 것이지요. 일단 하면 쉽습니다.

    구현하다가 잘 안되거나 문제가 생기면 질문글 올려주세요. (에러 메시지와 함께..)

    언제든 도움드릴게요.
    일단 해보세요.

    감사합니다.

  18. Blog Icon
    초보 개발자 1호

    리스트뷰, 레이아웃 종류랑 각 속성들..
    이번에도 너무 깔끔하고 친절한 정리 감사드립니다.
    이번엔 메신저 앱에서 대화내역 데이터 저장을
    단말기 내부DB에 구현하려고 SQLite를 공부하고 있습니다.
    정말정말 큰 도움 되고 있습니다.
    윗글에서 말씀하신 것처럼 일단 도전해 보겠습니다ㅋㅋ

  19. 네. 도전한다는 것이 중요합니다!!
    일단 해봐야 죽이되든 앱이되든 되는 거죠!
    제가 쓴 글들이 많은 도움 되면 좋겠네요.

    감사합니다.

  20. Blog Icon
    체리블루

    책 보면서 이해가 잘 안가던 것들을 너무 자세히 설명해 주셔서 감사합니다. ^^

    그런데 이번 예제 프로그램 따라서 만들어 봤는데
    내용을 입력하고 save를 누르면 앱이 중단되버리네요. 코딩도 별문제 없는것 같고...
    그런데 혹시 contact.db가 생성되지 않은것 같은 의심은 들어요
    도와주세요...^^

    Unfortunately. MyDatabaseTest has stopped. 라는 메시지 나오네요...ㅠㅠ

  21. 일단 작성하신 코드와 본문의 내용을 다시 한번 꼼꼼하게 비교해보시는 게 좋을 것 같습니다.

    만약 작성하신 코드가 문제없다면, 테이블 작성이 잘못되어 있어서 그럴 수도 있을텐데요, "DROP TABLE"을 한번 실해서 테이블을 없앤 다음, 코드를 실행해 보세요.

    아니면 adb를 통해 sqlite3 명령을 사용하면 DB 파일의 내용을 확인할 수 있습니다. 관련 내용 찾아보시는 것도 좋을 것 같구요.

    어떻게 해결해야 할지 감이 오지 않는다면, 에러 발생 시 출력되는 로그메시지를 올려주세요. 그러면 문제를 찾는데 도움을 드리기가 용이할 것 같습니다.

    감사합니다.

  22. 안녕하세요. 안드로이드와 데이터베이스를 공부하고 있는 학생입니다. mac상에서 본 예제 코드를 동작하려고하는데, 시작자체가 잘 안되는 오류가 발생합니다.
    쿼리부문이 이상하게 문자열이아니라 특정 기능으로서 인식하는게 의심스러운데요,
    sqliteDB.execSQL("DELETE FROM CONTACT_T");
    "INSERT INTO CONTACT_T "
    "DELETE FROM CONTACT_T"
    "CREATE TABLE IF NOT EXISTS CONTACT_T ("
    "NO " + "INTEGER NOT NULL,"
    "SELECT * FROM CONTACT_T" 에서 "" 안에 있음에도 불구하고 쿼리문이 주황색으로 보이네요.
    특히 "NO " + "INTEGER NOT NULL," 부분에서는 expected, got 'NO' 오류까지 발생합니다.
    어떻게 해결 하면 좋을까요?

  23. 답글을 늦게 달아서 죄송합니다.
    이미 문제를 해결하셨겠지만, 혹시라도 해결하지 못하셨다면 다시 질문글 남겨주세요.

    도움드릴 수 있도록 노력하겠습니다.

    죄송하고, 감사합니다.

  24. Blog Icon
    ocs

    먼저 좋은 글 감사 드립니다.

    기초적인 질문인듯한데요...

    [STEP-2] SQLDatabase 클래스 변수 선언 및 초기화에 보면
    상수로
    SQLiteDatabase sqlDB;

    아래
    init_databae() 메서드에
    SQLiteDatabase db = null;
    로 선언 되어 있는데요....

    init_database() 로 바로 호출하고
    메서드에서
    sqlDB를 그냥 쓰면 안되는 이유가 있는지요?

  25. 아닙니다. 전혀 문제 없고, 클래스 변수로 선언된 변수를 바로 사용해도 됩니다.

    본문에서 작성한 것은, 개인 취향에 따른 코딩 패턴이라고 보면 될 것 같습니다.

    감사합니다.