[6] 데이터 저장 [3] 데이터를 SQL Database로 저장하기

Saving Data in SQL Databases

THIS LESSON TEACHES YOU TO

  1. Define a Schema and Contract
  2. Create a Database Using a SQL Helper
  3. Put Information into a Database
  4. Read Information from a Database
  5. Delete Information from a Database
  6. Update a Database

YOU SHOULD ALSO READ


저는 DB를 모르지만 그냥 해석하는 척 해 봤습니다.
이 글은 참고하시지 마시길 바랍니다.

Saving data to a database is ideal for repeating or structured data, such as contact information. This class assumes that you are familiar with SQL databases in general and helps you get started with SQLite databases on Android. The APIs you’ll need to use a database on Android are available in theandroid.database.sqlite package.

반복적이고 구조적인 데이터는 데이타베이스에  저장하는것이 좋습니다. 예를 들어 연락처 정보같은 것들이지요. 이 시간에는 여러분이 SQL 데이타베이스에 친숙하다는 것을 전제하에 진행됩니다. 그리고 안드로이드에서 SQLight 데이타베이스를 시작하는 데에 도움을 줍니다. 우리가 사용할 API는 android.database.sqlite 패키지 안에 있습니다.

Define a Schema and Contract


One of the main principles of SQL databases is the schema: a formal declaration of how the database is organized. The schema is reflected in the SQL statements that you use to create your database. You may find it helpful to create a companion class, known as a contract class, which explicitly specifies the layout of your schema in a systematic and self-documenting way.

SQL 데이타베이스의 기본 원칙중 하나는 스키마입니다: 어떻게 데이타베이스가 조직되는지 양식에 맞는 선언 이지요. 스키마는 우리가 우리의 데이터베이스를 생성할 SQL 상태에 반영됩니다.  챔피언 클래스를 생성하는 데에 도움이 되도록 찾을 수도 있습니다.  contract 클래스같이 알려진 것이지요. 이 것은 명시적으로 systematic 하고self-documenting방식으로 스키마의 레이아웃으로 명세됩니다. (하하 아무것도 모르겠어요 ^^)

A contract class is a container for constants that define names for URIs, tables, and columns. The contract class allows you to use the same constants across all the other classes in the same package. This lets you change a column name in one place and have it propagate throughout your code.

contract 클래스는 컨테이너입니다. 상수를 위한 컨테이너입니다. URI, table, column들을 위한 이름들을 정의하지요. contract 클래스는 우리가 같은 상수들을 사용할 수 있도록 허용합니다. 같은 패키지 내에서 다른 클래스에서의 상수를 사용할 수 있는것이지요. 이것은 우리가 한 곳에서 column이름을 바꿀 수 있게 해 줍니다. 그리고 코드에 전파할 수 있게 합니다.

A good way to organize a contract class is to put definitions that are global to your whole database in the root level of the class. Then create an inner class for each table that enumerates its columns.

Contract 클래스를 조직하는 데에 좋은 방법은 글로벌한 정의를 전체 데이터베이스에 넣는 방식입니다. 클래스의 Root레벨에 넣는 것이지요. 그리고 내부 클래스를 각각의 테이블(comlumn을 열거하는) 에 생성하세요.

Note: By implementing the BaseColumns interface, your inner class can inherit a primary key field called _IDthat some Android classes such as cursor adaptors will expect it to have. It’s not required, but this can help your database work harmoniously with the Android framework.

노트: BaseColums인터페이스를 구현함으로써, 우리의 내부 클래스는 프라이머리 키 필드를 생송할 수 있습니다. _ID라고 불리우지요. 이 것은 일부 안드로이드 클래스들이 (예: 커서 어댑터) 이것들을 하길 것으로. 이 것은 요구되지 않지만, 도움이 될 수 있습니다. 안드로이드 데이터베이스가 조화롭게 동작하도록, 안드로이드 프레임워크와

For example, this snippet defines the table name and column names for a single table:

예를 들어, 이 스네펫은 정의합니다, 테이블 이름과 컬럼 이름을요, 싱글 테이블을 위해.

public final class FeedReaderContract {
    // To prevent someone from accidentally instantiating the contract class,
    // give it an empty constructor.
    public FeedReaderContract() {}

    /* Inner class that defines the table contents */
    public static abstract class FeedEntry implements BaseColumns {
        public static final String TABLE_NAME = "entry";
        public static final String COLUMN_NAME_ENTRY_ID = "entryid";
        public static final String COLUMN_NAME_TITLE = "title";
        public static final String COLUMN_NAME_SUBTITLE = "subtitle";
        ...
    }
}

Create a Database Using a SQL Helper


Once you have defined how your database looks, you should implement methods that create and maintain the database and tables. Here are some typical statements that create and delete a table:

일단 우리가 정의했다면, 어떻게 데이터 베이스가 보이는지, 우리는 메서드를 구현해야만 합니다, 메서드는 만들고 관리합니다, 데이터베이스들과 테이블들을요. 혀이게 일부 정형적인 상태들이 있습니다, 이들은 생성하고 지우지요, 테이블을.

private static final String TEXT_TYPE = " TEXT";
private static final String COMMA_SEP = ",";
private static final String SQL_CREATE_ENTRIES =
    "CREATE TABLE " + FeedEntry.TABLE_NAME + " (" +
    FeedEntry._ID + " INTEGER PRIMARY KEY," +
    FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +
    FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
    ... // Any other options for the CREATE command
    " )";

private static final String SQL_DELETE_ENTRIES =
    "DROP TABLE IF EXISTS " + FeedEntry.TABLE_NAME;

Just like files that you save on the device’s internal storage, Android stores your database in private disk space that’s associated application. Your data is secure, because by default this area is not accessible to other applications.

파일들 (우리가 저장하는) (기기의 내부 저장소에)처럼, 안드로이드는 저장합니다, 우리의 데이터베이스를 (개별 디스크 공간(앱과 관련된)에) . 우리의 데이터는 보호됩니다, 왜냐하면 기본적으로 이 지역은 접근 가능하지 않습니다, 다른 어플리케이션에서.

A useful set of APIs is available in the SQLiteOpenHelper class. When you use this class to obtain references to your database, the system performs the potentially long-running operations of creating and updating the database only when needed and not during app startup. All you need to do is call getWritableDatabase() orgetReadableDatabase().

쓸만한 API의 세트는 사용가능합니다, SQLiteOpenHelper클래스에서. 우리가 이 클래스를 사용할 때, 참조(데이터 베이스를 가리키는)를 획득하기 위해서, 시스템은 수행합니다 잠재적으로 긴실행을하는 동작들(데이터베이스를 생성, 업데이트)을, 필요할 때만, 앱이 시작할 때가 아니라. 우리가 해야할 것은 호출하는 것입니다, getWritableDatabase() 또는 getReadableDatabase()

Note: Because they can be long-running, be sure that you call getWritableDatabase() or getReadableDatabase()in a background thread, such as with AsyncTask or IntentService.

노트: 그들이 오래 동작하기 때문에, 확실하게 하세요, 우리가 getWritableDatabase()나 getReadableDatabase() 를 호출하는 것을, 백그라운드 스레드에서, AsyncTask 나 IntentService와 함께 같은.

To use SQLiteOpenHelper, create a subclass that overrides the onCreate(), onUpgrade() and onOpen() callback methods. You may also want to implement onDowngrade(), but it’s not required.

SQLiteOpenHelper 를 사용하기 위해, 생성합니다, 서브클래스를 { onCreate()를 오버라이드하는 }

For example, here’s an implementation of SQLiteOpenHelper that uses some of the commands shown above:

예를 들어, SQLiteOpenHelper{사용합니다, 일부 공통된것들을, 위에서 보이는 것처럼}의 구현이 있습니다

public class FeedReaderDbHelper extends SQLiteOpenHelper {
    // If you change the database schema, you must increment the database version.
    public static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "FeedReader.db";

    public FeedReaderDbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL_CREATE_ENTRIES);
    }
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // This database is only a cache for online data, so its upgrade policy is
        // to simply to discard the data and start over
        db.execSQL(SQL_DELETE_ENTRIES);
        onCreate(db);
    }
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        onUpgrade(db, oldVersion, newVersion);
    }
}

To access your database, instantiate your subclass of SQLiteOpenHelper:

데이터베이스에 접근하기 위해서, SQLiteOpenHelper 의 서브클래스를 초기화합니다.

FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());

Put Information into a Database


Insert data into the database by passing a ContentValues object to the insert() method:

데이터 베이스에 데이터를 삽입하세요, ContentValues오브젝트를 넘겨줌으로써, insert()메서드로

// Gets the data repository in write mode
SQLiteDatabase db = mDbHelper.getWritableDatabase();

// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
values.put(FeedEntry.COLUMN_NAME_CONTENT, content);

// Insert the new row, returning the primary key value of the new row
long newRowId;
newRowId = db.insert(
         FeedEntry.TABLE_NAME,
         FeedEntry.COLUMN_NAME_NULLABLE,
         values);

The first argument for insert() is simply the table name. The second argument provides the name of a column in which the framework can insert NULL in the event that the ContentValues is empty (if you instead set this to"null", then the framework will not insert a row when there are no values).

첫 번째 인자 (insert()의) 는 간단하게 테이블 이름입니다. 두 번째 인자는 컬럼의 이름입니다,프레임워크가NULL 을 삽입할 수 있는 곳이지요, ContentValues가 비어있는 이벤트에서(만약 이 것을 null로 대체한다면, 프레임워크는 row를 삽입하지 않을 거에요 , 거기에 값이 없을 때)

Read Information from a Database


To read from a database, use the query() method, passing it your selection criteria and desired columns. The method combines elements of insert() and update(), except the column list defines the data you want to fetch, rather than the data to insert. The results of the query are returned to you in a Cursor object.

데이터베이스로부터 값을 읽을 때, query() 메서드를 사용합니다. 이 것을 우리의 섹션 기준과 원하는 컬럼에 넘겨주면서. 메서드는 엘리먼트들(insert() 와 update())을 조합합니다, 컬럼 리스트( 우리가 fetch하고 싶어하는 데이터를 정의하는)를 제외하고, insert하려는 데이터라기 보다는. 쿼리의 결과는 리턴됩니다, Cursor오브젝트에.

SQLiteDatabase db = mDbHelper.getReadableDatabase();

// Define a projection that specifies which columns from the database
// you will actually use after this query.
String[] projection = {
    FeedEntry._ID,
    FeedEntry.COLUMN_NAME_TITLE,
    FeedEntry.COLUMN_NAME_UPDATED,
    ...
    };

// How you want the results sorted in the resulting Cursor
String sortOrder =
    FeedEntry.COLUMN_NAME_UPDATED + " DESC";

Cursor c = db.query(
    FeedEntry.TABLE_NAME,  // The table to query
    projection,                               // The columns to return
    selection,                                // The columns for the WHERE clause
    selectionArgs,                            // The values for the WHERE clause
    null,                                     // don't group the rows
    null,                                     // don't filter by row groups
    sortOrder                                 // The sort order
    );

To look at a row in the cursor, use one of the Cursor move methods, which you must always call before you begin reading values. Generally, you should start by calling moveToFirst(), which places the “read position” on the first entry in the results. For each row, you can read a column’s value by calling one of the Cursor get methods, such as getString() or getLong(). For each of the get methods, you must pass the index position of the column you desire, which you can get by calling getColumnIndex() or getColumnIndexOrThrow(). For example:

커서의 열을 보면, Cursor move 메서드중 하나를 사용하는데, 우리가 값을 읽기 시작하기 이전에  반드시 언제나 불러야 하는 것입니다. 일반적으로, moveToFirst()를 호출함으로써 시작해야 하는데요, “read position”을 시작지점에 위치시키는 것입니다, 각각의 열에서, 우리는 컬럼 값을 읽을 수 있습니다, Cursor get 메서드중 하나를 호출해서요, 예를 들어 getString() 이나getLong(). 각각의 get메서드들, 우리가 반드시 우리가 원하는 인덱스 포지션을 넘겨줘야 하는,  우리가 getColumnIndex()나 getColumnIndexOrThrow()랄호출함으로써 획득할 수 있는.

cursor.moveToFirst();
long itemId = cursor.getLong(
    cursor.getColumnIndexOrThrow(FeedEntry._ID)
);

Delete Information from a Database


To delete rows from a table, you need to provide selection criteria that identify the rows. The database API provides a mechanism for creating selection criteria that protects against SQL injection. The mechanism divides the selection specification into a selection clause and selection arguments. The clause defines the columns to look at, and also allows you to combine column tests. The arguments are values to test against that are bound into the clause. Because the result isn’t handled the same as a regular SQL statement, it is immune to SQL injection.

row를 테이블로부터삭제하기 위해서는, selection criteria 를 제공해야 합니다. selection criteria 는 row 의 id라고 보시면 됩니다. 데이터베이스 API는 selection criteria 만드는데에 메커니즘을 제공합니다. selection criteria 는 SQL인젝션으로부터 보호합니다. 이 메카니즘은 selection 스펙을 selection clause 와 selection argument 로 나눕니다 . Clause는 columns의 형태를 정의합니다. 또한, 이 것은 우리가 column tests 를 조합하게 합니다. Arguments는 clause에 바운디드되는 대해 테스트하는 값입니다. 그 결과가 regular SQL 상태같이 다뤄지지 않기 때문에, SQL injection에 immune입니다 

// Define 'where' part of query.
String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";
// Specify arguments in placeholder order.
String[] selectionArgs = { String.valueOf(rowId) };
// Issue SQL statement.
db.delete(table_name, selection, selectionArgs);

Update a Database


When you need to modify a subset of your database values, use the update() method.

데이터베이스 값을 일부를 수정할 필요가 있을 때, update()메서드를 사용합니다.

Updating the table combines the content values syntax of insert() with the where syntax of delete().

 

SQLiteDatabase db = mDbHelper.getReadableDatabase();

// New value for one column
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_TITLE, title);

// Which row to update, based on the ID
String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";
String[] selectionArgs = { String.valueOf(rowId) };

int count = db.update(
    FeedReaderDbHelper.FeedEntry.TABLE_NAME,
    values,
    selection,
    selectionArgs);

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중