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());
