SQLiteOpenHelperとSQLiteDatabaseの使用

9304 ワード

1.データ型
SQLiteのデータ型は、他のデータベースとは異なり、NULL(空のタイプ)、INTEGER(整数)、REAL(浮動小数点型)、TEXT(文字列型)、BLOB(バイナリ型)のみと簡単です.
SQLiteは動的データ型(弱参照)であり、データベースに値を挿入すると、その値のタイプがチェックされ、タイプが挿入カラムと一致しない場合、SQLiteはその値を対応するタイプに変換しようとします.
2.データベースの作成
SQLの操作が分からない場合は、まずこれを見ておくことをお勧めします:MySQL入門ノート(一)
AndroidにはSQLiteOpenHelperクラスが用意されており、データベースの作成とアップグレードを非常に容易に行うことができます.
SQLiteOpenHelperは抽象クラスであり、onCreate()とonUpgrade()を実装する必要があります.この2つのメソッドは、データベースの作成とアップグレードにそれぞれ使用され、onCreate()はデータベースが存在しない場合に呼び出されますが、onUpgrade()は、バージョン番号が既存のデータベースより高い場合に呼び出されます.
SQLiteOpenHelperコンストラクション関数の最初のパラメータはcontextであり、2番目のパラメータはデータベースの名前であり、3番目のパラメータはデータのクエリー時にカスタムCursorを返し、nullに直接転送すればよい.4番目のパラメータはデータベースバージョン番号であり、データベースの昇格操作に使用される.
getReadableDtabase()メソッドまたはgetWritableDatabase()メソッドを呼び出すと、データベースを作成または開くと同時にSQLiteDatabaseオブジェクトが返され、データベースを操作できます.ここで、SQLiteDatabaseオブジェクトには、SQL文を実行するために使用されるexexSQLメソッドとrawQueryメソッドの2つの重要なメソッドがあり、クエリー・レコードに使用されるため、後で詳しく説明します.
拡張:ContextとSQLiteDatabaseのメソッドopenOrCreateDatabaseの違い(context、SQLiteOpenHelper)
例:
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        new SQLiteOpenHelper(this, "Library.db", null, 1) {
            
            static final String CREATE_BOOK = "create table BOOK ("
                    + "id integer primary key autoincrement, "
                    + "name text, "
                    + "author text)";

            @Override
            public void onCreate(SQLiteDatabase db) {
                //      
                db.execSQL(CREATE_BOOK);
                Toast.makeText(MainActivity.this, "    !", Toast.LENGTH_SHORT).show();
            }

            //        
            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            }
        }.getWritableDatabase();
    }
}

3.データベースのアップグレード
appの反復を行う場合、データベースのアップグレードも伴うことが多いため、onUpgrade()メソッドで実現する必要があります.データベースをアップグレードする必要がある場合は、SQLiteOpenHelperをインスタンス化するときに、より高いバージョン番号を入力します.
例:
2回反復すると仮定:1.テーブルcatelogy,2を追加します.テーブルbookにcategoryを追加idフィールド.
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new SQLiteOpenHelper(this, "Library.db", null, 1) {

            static final String CREATE_BOOK = "create table BOOK ("
                    + "id integer primary key autoincrement, "
                    + "name text, "
                    + "author text,"
                    + "category_id integer)";//        

            static final String CREATE_CATEGORY = "create table CATEGORY ("
                    + "id integer primary key autoincrement, "
                    + "category_name text,"
                    + "category_code integer)";

            static final String CHANGE_COLUMN = "alter table BOOK column category_id integer";

            @Override
            public void onCreate(SQLiteDatabase db) {
                //               ,        ,        
                db.execSQL(CREATE_BOOK);
                db.execSQL(CREATE_CATEGORY);
                Toast.makeText(MainActivity.this, "    !", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                switch (oldVersion) {
                    //    break
                    case 1:
                        db.execSQL(CREATE_CATEGORY);
                    case 2:
                        db.execSQL(CHANGE_COLUMN);
                    default:
                }
            }
        }.getWritableDatabase();
    }
}

ここでは詳細に注意してください.onUpgrade()メソッドのswitch文にはbreakが使用されていません.これは、バージョン間のアップグレード時に中間のすべてのアップグレードが順調に順次完了することを保証するためです.
4.データ操作
4.1 execSQL()とrawQuery()
前述したように、getReadableDatabase()メソッドまたはgetWritableDatabase()メソッドを呼び出すと、SQLiteDatabaseオブジェクトが返されます.データを操作するには、このオブジェクトを使用します.
上記の例によれば、SQLiteDatabaseは、クエリ文以外のSQL文を呼び出す方法execSQL()を提供し、SQLiteDatabaseクラスは、クエリデータに使用されるrawQuery()メソッドを提供する.
(1)execSQL()
execSQL(String sql)
execSQL(String sql, Object[] bingArgs)

EXecSQL()メソッドを使用してパラメータを入力するには、2つの方法があります.1つ目はSQL文に直接入力し、パラメータがあれば直接接続します.たとえば、次のようにします.
String delete_sql = "delete from test where _id = " + idString;
db.execSQL(sql);

2つ目の方法は、パラメータの位置にプレースホルダを挿入することです.次に、execSQL()メソッドの2番目のパラメータに具体的なパラメータを渡します.複数のパラメータがある場合は、次のようにします.
String delete_sql = "delete from test where _id = ?, name = ?";
db.execSQL(sql, new String[] {idString, nameString});

(2)rawQuery()
rawQuery(String sql, String[] selectionArgs)

rawQuery()メソッドの使用はexecSQL()の2番目の使用法とほぼ一致している.
4.2アンドロイドが提供するAPI
AndroidはexecSQL()メソッドとrawQuery()メソッドのほか、データベースのCRUDオペレーションにAPIをカプセル化し、より操作しやすい.
(1)insert()
insert(String table, String nullColumnHack, ContentValues values)
table:表名.nullColumnHack:空に許可されているカラムに値が割り当てられていない場合は、自動的にnullに値が割り当てられ、nullに入力されます.values:ContentValueオブジェクトは、コンテナの役割に相当します.各ローのデータをput(key,values)メソッド(keyはカラム名、valuesはカラムの値)で1つずつ追加し、データベースに転送できます.複数のレコードを挿入する場合は、次のレコードを挿入する前にclear()メソッドを呼び出して空にします.
レコードのidを挿入するid値を返します.
例:
    //  SQLiteDatabase  
    db = mHelper.getWritableDatabase();
    
    //   ContentValues         
    ContentValues values = new ContentValues();
    values.put("name", "A");
    values.put("author", "aa");
    
    //    
    db.insert("BOOK", null, values);
    
    //         ,         values clear()         
    values.clear();
    
    values.put("name", "B");
    values.put("author", "bb");
    db.insert("BOOK", null, values);

(2)delete()
delete(String table, String whereClause, String[] whereArgs)
whereClauseおよびwhereArgs:削除条件を指定し、指定しない場合はテーブル内のすべてのデータを削除します.すなわち、SQLのwhere文セクションでは、プレースホルダがexecSQL()とrawQuery()を使用しています.たとえば、age>30のレコードを削除すると、2番目のパラメータはage>?です.3番目のパラメータはnew String[{"30"}です.
例:
    //    ,?      ,  、           id > 2   
    db.delete("BOOK", "id > ?", new String[] {"2"});

(3)update()
update(String table, ContentValues values, String whereClause, String[] whereArgs)

valuesはInsert()メソッドと同じで、更新されたデータをContentValueオブジェクトでアセンブリし、whereClauseとwhereArgsはdelete()メソッドと同じで、更新するレコードを指定します.
例:
    ContentValues values = new ContentValues();
    values.put("name", "D");
    db.update("BOOK", values, "id < ?", new String[] {"3"});

(4)query()
query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)

SQL言語を学んだことがあれば、上の長い列のパラメータは比較的理解しやすいと信じられ、基本的にSQLのselect文の構造に対応することができます.query()メソッドを呼び出すと、すべてのクエリー結果を含むCursorオブジェクトが返されます.table:SQLのfrom table_nameに対応し、クエリーのテーブル名を指定します.columns:select column1, column2, ...に対応し、クエリーのカラム名を指定します.selection:where column = valueに対応して、クエリのローの制約を指定します.selectionArgs:selectionのプレースホルダ(?)具体的な値を指定します.groupBy:group by columnに対応し、どの列をグループ化するかを指定します.having:having column = valueに対応し、さらにパケット化された結果を制約する.orderBy:order by column1, column2, ...に対応し、クエリー結果のソート方法を指定します.
例:
    db = mHelper.getWritableDatabase();
    //  BOOK     
    Cursor cursor = db.query("BOOK", null, null, null, null, null, null);
    if (cursor.moveToFirst()) {
        do {
            //  cursor,    
            int id = cursor.getInt(cursor.getColumnIndex("id"));
            String name = cursor.getString(cursor.getColumnIndex("name"));
            String author = cursor.getString(cursor.getColumnIndex("author"));
            //    
            Log.d("MySQLiteData", id + ". 《" + name + "》  " + author);
        }while (cursor.moveToNext());
        //  Cursor  
        cursor.close();
    }

5.取引
SQLiteはトランザクションをサポートしていますが、トランザクションとは何ですか?大量のデータを更新する必要がある場合は、古いデータを削除してから新しいデータを挿入します.しかし、プロセス中に異常が発生し、古いデータが削除された後、新しいデータが正常に挿入されなかった場合、このデータテーブルの情報はすべて失われます.
トランザクションの特性は、一連の操作を保証したり、すべて完了したり、すべて完了しなかったりすることです.トランザクションに置換データを配置すると、データの置換に成功したか、テーブル内のすべてが新しいデータに変換されたか、失敗したか、古いデータを保持し、古いデータが削除されたが、新しいデータが挿入されなかった場合があります.
トランザクションの使用方法は非常に簡単です.
//   SQLiteDatabase      
db.beginTransaction();
try {
    //                  
    //                 
    db.setTransactionSuccessful();
} catch (Exception e) {
    e.printStackTrace();
} finally (
    //     
    db.endTransaction();
)