2010년 7월 6일 화요일

Database

Database
1. openOrCreateDatabase <--쉽게 database를 만들기 위한 함수

/ data / data/<>/ databases/<> <-- database가 저장되는 위치

예) / data / data / com. androidbook. FullDatabase / databases / my_sqlite_database.db

2. Configuring the SQLite Database Properties
mDatabase. setLocale( Locale. getDefault());
mDatabase. setLockingEnabled( true ); <- thread-safe (??)

mDatabase. setVersion( 1 );

3. Creating Tables and Other SQLite Schema Objects
CREATE TABLE tbl_authors( id INTEGER PRIMARY KEY AUTOINCREMENT,
firstname TEXT,
lastname TEXT );

mDatabase. execSQL( CREATE_AUTHOR_TABLE ); <-- CREATE_AUTHOR_TABLE = CREATE TABLE로서 해당 명령으로 table만들어짐

아래와 같이 sql 명령어를 쓸 수 있다.
private static final String CREATE_TRIGGER_ADD =
" CREATE TRIGGER fk_insert_book BEFORE INSERT ON tbl_books
FOR EACH ROW
BEGIN
SELECT RAISE( ROLLBACK,'insert on table \" tbl_books \" violates foreign key constraint \" fk_authorid \"')
WHERE( SELECT id FROM tbl_authors WHERE id = NEW. authorid) IS NULL ;
END ;";
mDatabase. execSQL( CREATE_TRIGGER_ADD );
**SQLite에는 foreign key 제약을 강제하지 않아, 위와 같은 방법으로 두개의 table을 연결하려 함. ** 그냥 이렇게
sql문을 쓸수 있다는 정도만 알자.

4. Creating, Updating, and Deleting Database Records
4.1 Inserting Records
import android. content. ContentValues ;
ContentValues values = new ContentValues();
values. put(" firstname ", " J. K .");
values. put(" lastname ", " Rowling ");
long newAuthorID = mDatabase. insert(" tbl_authors ", null, values ); <-- Table tbl_authors에 값을 넣는

** insertOrThrow()라는 함수는 insert와 같은 기능을 하지만 fail날때 exception을 받을수 있도록 하여 fail원인
파악을 할 수 있도록 한다
4.2 Update
public void updateBookTitle( Integer bookId, String newtitle){
ContentValues values = new ContentValues();
values. put(" title ", newtitle );
mDatabase. update(" tbl_books ", values, " id =?", new String[]{ bookId. toString() };)
}
SQLiteDatabase.update(테이블,ContentValues 값, Where, where의 값)으로 구성됨.
* Delete는 Update와 유사하여 생략

5. Working with Transactions
여러 datebase를 처리할때 관련.
mDatabase. beginTransaction(); <-- transaction은 beginTransaction과 함께 시작한다.

try{
// Insert some records, updated others, delete a few
// Do whatever you need to do as a unit, then commit it
mDatabase. setTransactionSuccessful(); <--transaction이 성공하였다면, 호출하고 commit됨

} catch( Exception e){
// Transaction failed. Failed! Do something here. <-- 실패하게되면 roll back됨

//It's up to you.
} finally{
mDatabase. endTransaction(); <-- transaction끝

}

6. Querying SQLite Database.
6.1 Working with Cursors
Cursor는 sql query 질의에 대한 return값으로 query문에서 찾고자 하는 data를 가리키는 pointer이다.
// SIMPLE QUERY: select * from tbl_books
Cursor c = mDatabase. query(" tbl_books ", null, null, null, null, null, null ); == SELECT * FROM tbl_books
// Do something quick with the Cursor here ...
c. close(); <-- cursor를 다쓰고 나서는 반드시 close해야 한다.

query는 아래와 같은 변수값을 인자로 한다
- [String]: table 이름
- [String array] : column이름들 (null인경우 all을 의미)
- [String] : WHERE (예, id)
- [String Array] : WHERE의 인자값들
- [string] : Group
- [String] : Group에 대한 인자값?
- [String] : Order
-[String] : Limit
예) 테이블 tbl_books에서 id 9인 값을을 얻는 code
Cursor c = mDatabase.query("tbl_books",null,"id=?", new String[]{"9"}, null, null, null);
= SELECT * tbl_books WHERE id=9;
6.2 Executing More Complex Queries like Joins Using SQLiteQueryBuilder
한번에 여러 table들을 다룰때에는 SQLiteQueryBuilder라는 class를 이용하여 복잡한 query문을 만들수 있다.
import android. database. sqlite.SQLiteQueryBuilder ;
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder. setTables(" tbl_books, tbl_authors ");
queryBuilder. appendWhere(" tbl_books. authorid = tbl_authors. id "); <- JOIN

String asColumnsToReturn[] ={ " tbl_books. title ", " tbl_books. id ",
" tbl_authors. firstname ", " tbl_authors. lastname ",
" tbl_books. authorid " };
String strSortOrder = " title ASC ";
Cursor c = queryBuilder. query( mDatabase, asColumnsToReturn, null, null, null, null, strSortOrder );
위 code는 아래의 Sql query문과 동일하다
SELECT tbl_books. title,
tbl_books. id,
tbl_authors. firstname,
tbl_authors. lastname,
tbl_books. authorid
FROM tbl_books INNER JOIN tbl_authors on tbl_books. authorid = tbl_authors. id ORDER BY title ASC
6.3 Executing Raw Queries ;Executing Without Bothering with Builders and Column-Mapping
SELECT title AS Name,
'tbl_books' AS OriginalTable
FROM tbl_books
WHERE Name LIKE' % ow %'
UNION SELECT( firstname ||'' || lastname) AS Name,
'tbl_authors' AS OriginalTable
FROM tbl_authors
WHERE Name LIKE' % ow %'
ORDER BY Name ASC ;
위와 같은 raw query문을 실행시키기 위해서는 rawQuery()함수를 이용한다.
String sqlUnionExample = " SELECT title AS Name,'tbl_books' AS
OriginalTable from tbl_books WHERE Name LIKE? UNION SELECT
( firstname ||'' || lastname) AS Name,
'tbl_authors' AS OriginalTable
from tbl_authors WHERE Name LIKE? ORDER BY Name ASC ;";
Cursor c = mDatabase. rawQuery( sqlUnionExample, new String[]{ "% ow %", "% ow %"});
(ow)-> ?값을 나타내게 된다.
7. Making Database - PetTracker
7.1 table 구성
import android. provider. BaseColumns ;
public final class PetDatabase {
private PetDatabase(){}
public static final class Pets implements BaseColumns{
private Pets(){}
public static final String PETS_TABLE_NAME =" table_pets ";
public static final String PET_NAME =" pet_name ";
public static final String PET_TYPE_ID =" pet_type_id ";
public static final String DEFAULT_SORT_ORDER =" pet_name ASC ";
}
public static final class PetType implements BaseColumns{
private PetType(){}
public static final String PETTYPE_TABLE_NAME =" table_pettypes ";
public static final String PET_TYPE_NAME =" pet_type ";
public static final String DEFAULT_SORT_ORDER =" pet_type ASC ";
}
7.2 SQLiteOpenHelper class를 이용하여 database 생성한다. SQLiteOpenHelper 클래스를 이용하는 이유는
database 관리하기위한 여러 함수를 사용할 수 있기 때문이다.
import android. content. Context ;
import android. database. sqlite. SQLiteDatabase ;
import android. database. sqlite. SQLiteOpenHelper ;
import com. androidbook. PetTracker. PetDatabase. PetType ;
import com. androidbook. PetTracker. PetDatabase. Pets ;
class PetTrackerDatabaseHelper extends SQLiteOpenHelper{
private static final String DATABASE_NAME = " pet_tracker. db ";
private static final int DATABASE_VERSION = 1 ;
PetTrackerDatabaseHelper( Context context){
super( context, DATABASE_NAME, null, DATABASE_VERSION );
}
@Override
public void onCreate( SQLiteDatabase db){
db. execSQL(" CREATE TABLE " + PetType. PETTYPE_TABLE_NAME +"("
+ PetType. _ID + " INTEGER PRIMARY KEY AUTOINCREMENT ," +
PetType. PET_TYPE_NAME + " TEXT " + ");");
db. execSQL(" CREATE TABLE " + Pets. PETS_TABLE_NAME + "(" + Pets. _ID +
" INTEGER PRIMARY KEY AUTOINCREMENT ," + Pets. PET_NAME + " TEXT ," +
Pets. PET_TYPE_ID + " INTEGER " // FK to pet type table + ");");
}
@Override
public void onUpgrade( SQLiteDatabase db, int oldVersion, int newVersion){
// Housekeeping here.
// Implement how " move " your application data
// during an upgrade of schema versions
// Move or delete data as required. Your call.
}
@Override
public void onOpen( SQLiteDatabase db){
super. onOpen( db );
}
}
생성하고자 하는 database 변수는 아래와 같이 만든다.
PetTrackerDatabaseHelper mDatabase = new PetTrackerDatabaseHelper( this. getApplicationContext());