データのストレージとアクセス - SQLite データベースとの出会い


このセクションの概要:

このセクションでは、Android データの保存とアクセスの 3 番目の方法である SQLite データベースについて学び続けます。これは、他の SQL データベースとは異なります。 Android システムにはこのデータベースが統合されているため、携帯電話に別のデータベース ソフトウェアをインストールする必要はありません。 他のデータベース ソフトウェア (Oracle、MSSQL、MySql など) を使用する場合は、それをインストールし、関連する構成を完了し、ポートを変更する必要があります。 紹介はこれで終わりです。次はこれについて学びましょう~


1. 基本概念

1) SQLite とは何ですか? SQLite を使用する理由SQLiteの特徴は何ですか?

回答: 以下の Xiaozhu の説明を聞いてください:

①SQLite は、高速な計算速度と低いリソース使用量を備えた軽量のリレーショナル データベースであり、モバイル デバイスでの使用に非常に適しています。 標準の SQL 構文をサポートするだけでなく、ACID (データベース トランザクション) の原則にも準拠しており、アカウントは必要なく、非常に便利です。

② 先ほど、ファイルと SharedPreference を使用してデータを保存する方法を学びましたが、多くの場合、 ファイルは必ずしも有効であるとは限りません。たとえば、複数のスレッドによる同時アクセスが関係します。アプリは変更される可能性のある複雑なデータ構造を処理する必要があります。 銀行への入出金など!最初の 2 つを使用するのは非常に無力または面倒に思われるでしょうが、データベースの出現によってこの問題は解決されます。 Android はこのような軽量の SQLite を提供しているので、それを使用しない手はありません。

③SQLite は 5 つのデータ型をサポートしています: NULL、INTEGER、REAL (浮動小数点数)、TEXT (文字列テキスト)、および BLOB (バイナリ オブジェクト) 5 種類しかありませんが、varchar や char などの他のデータ型も保存できます。これは、SQLite の最大の特徴である フィールドで宣言されたデータ型を気にせずに、さまざまなデータ型のデータを任意のフィールドに保存できるためです。なんだ、君みたいに もちろん、文字列を主キーとして宣言する場合を除いて、整数型フィールドに格納できます。 INTEGER PRIMARY KEY フィールドには 64 ビット整数のみを保存できます! さらに、SQLite が CREATE TABLE ステートメントを解析するときに、 CREATE TABLE ステートメントのフィールド名に続くデータ型情報は無視されます。たとえば、次のステートメントは name フィールドの型情報を無視します。 CREATE TABLE person (personid integer Primary key autoincrement, name varchar(20))

機能の概要:

SQlite は

files

を通じてデータベースを保存します。ファイルは データベース であり、データベースには複数の テーブル が含まれています。 複数のレコード。各レコードは複数のフィールドで構成され、各フィールドは対応するを持ち、各値に対してタイプを指定できるかどうかを指定できます。 型(主キーを除く)

PS

: ちなみに、Android の組み込み SQLite は SQLite 3 バージョンです~2) いくつかの関連クラス:

ねえ、私は学習するときにそれが一番好きではありません新しい用語に出会うことほど良いことはありません。まずいくつかの用語について話しましょう。 データベースを使用するときに使用する 3 つのクラス:
  • SQLiteOpenHelper: 抽象クラス。このクラスを継承し、データベースの作成メソッドと更新メソッドをオーバーライドします。 このクラスのオブジェクトを通じてデータベース インスタンスを取得したり、データベースを閉じることもできます。
  • SQLiteDatabase: データベース アクセス クラス: このクラスのオブジェクトを使用して、データベースに対して追加、削除、変更、クエリ操作を実行できます。
  • Cursor: カーソル。JDBC の結果セット、結果セットに似ています。これは、データベース内の特定の点を指すものとして単純に理解できます。 レコードポインタです!

2. SQLiteOpenHelper クラスを使用してデータベースとバージョン管理を作成します

データベースを含むアプリの場合、データベース ファイルを手動で作成することは不可能であるため、アプリを初めて有効にする必要があります データベース テーブルは、アプリケーションをアップグレードする必要があり、今回はデータベース テーブルの構造を変更する必要があるときに作成されます。 データベース テーブルが更新されました。これら 2 つの操作のために、Android は メソッド分析を実装するための SQLiteOpenHelper

onCreate

( ) および onUpgrade( ) を提供します。 (database)

: ソフトウェアを初めて使用するときにデータベーステーブルを生成します
  • onUpgrade(database, oldVersion, newVersion): データベースのバージョンが変更されたときに呼び出されます。 一般に、バージョン番号を変更する必要があるのはソフトウェアをアップグレードする場合だけであり、データベースのバージョンはプログラマによって制御されているとします。 バージョンは 1 です。業務の変更により、データベースのテーブル構造が変更されました。ソフトウェアをアップグレードする場合は、ソフトウェアをアップグレードする必要があります。 ユーザーの携帯電話のデータベース テーブル構造を更新する この目的を達成するには、元のデータベースのバージョンを 2 に設定します。 または、古いバージョン番号とは異なるその他の番号。
  • コード例
  • :
public class MyDBOpenHelper extends SQLiteOpenHelper {
    public MyDBOpenHelper(Context context, String name, CursorFactory factory,
            int version) {super(context, "my.db", null, 1); }
    @Override
    //数据库第一次创建时被调用
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE person(personid INTEGER PRIMARY KEY AUTOINCREMENT,name VARCHAR(20))");
        
    }
    //软件版本号发生改变时调用
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("ALTER TABLE person ADD phone VARCHAR(12) NULL");
    }
}

コード分析:

上記のコードがアプリケーションを初めて起動するとき、この my.db ファイルを作成し、onCreate() のメソッドを実行します。 主キーの personId フィールドと name フィールドの 2 つのフィールドを持つ Person テーブルを作成し、データベースのバージョンを変更します。 番号が指定されている場合、次回起動時に onUpgrade() のメソッドが呼び出され、別のフィールドがテーブルに挿入されます。さらに、挿入部分はこちら フィールドなので、テーブルが再構築されても、テーブル内のすべてのデータは失われます。 この問題を解決する方法を教えましょう!

プロセスの概要

:

  • ステップ 1: SQLiteOpenHelper クラスを継承するようにクラスをカスタマイズします
  • ステップ 2: クラスのコンストラクター メソッドのスーパーに作成するデータベース名とバージョン番号を設定します
  • ステップ 3:書き換え onCreate() メソッドはテーブル構造を作成します
  • ステップ 4: onUpgrade() メソッドを書き換えて、バージョン番号の変更後に実行される操作を定義します

3. 生成した db ファイルを表示する方法

上記を呼び出すと、MyDBOpenhelper オブジェクトの getWritableDatabase() によって次のディレクトリにデータベースが作成されます データベース ファイル:

8.png

2 つのデータベースがあることがわかりました。前者は私たちが作成したデータベースであり、後者はデータベースがトランザクションをサポートできるようにするために生成されました。 一時ログファイル!一般的なサイズは 0 バイトです。 しかし、ファイル エクスプローラー では、.db はおろか、txt さえもファイルを開くことができません。 ここでは 2 つのオプションを示します:

  • 1. まずエクスポートし、SQLite のグラフィカル ツールを使用して表示します
  • 2. adb 環境変数を構成した後、adb シェルを介して表示します (コマンド ライン、コンパイラーをインストールします) )!

それでは、上記の 2 つの方法を紹介します。お好きな方を選んでください~~


方法 1: SQLite グラフィカル ツールを使用して db ファイルを表示します

そのようなソフトウェアはたくさんありますが、著者が使用しているのは 1 つですSQLite Expert Professional です。もちろん他のツールも使用できます 必要な場合は、ダウンロードできます: SQLiteExpert.zip

db ファイルをコンピュータのデスクトップにエクスポートし、SQLiteExpert を開きます。インターフェースは次のとおりです:

1.png

プレイ方法は聞かずに、インポートしてください。 dbをダウンロードして、自分でゆっくりプレイしてください。使い方はとても良いです。シンプルで、Baiduがわかりません~


2番目の方法については、最初は試してみたかったのですが、後でsqliteコマンドが見つからないことがわかりました, なので、何度か試しては忘れてしまいました。 後で細かいボタンで使用します。興味がある場合は、Guo Lin の「コードの最初の行 - Android」を見つけて、フローチャートに従って試してみてください。 ここには最初の部分のみが掲載されています。コマンド部分は自分で読んでください。

方法 2: adb シェル コマンド ラインは、ふりをして飛行するのに役立ちます

1. SDK 環境変数を構成します:

コンピューターを右クリックします ——> 詳細なシステム設定 ->変数 -> 新しいシステム変数を作成します -> SDK のプラットフォーム ツール パスをコピーします。 たとえば、作成者のもの: C:SoftwareCodingandroid-sdks-asplatform-tools

2.png

確認し、Path 環境変数を見つけて編集し、最後に次を追加します:

%SDK_HOME%;

3.png

次に、コマンドラインを開き、adbと入力し、たくさんのことを実行すると、構成が成功したことを意味します。

——————キーポイント——————: 後続のコマンド ライン命令を実行する前に、テスト用のマシンが複数存在する場合があります。 1.ネイティブ シミュレーター: OK、ここをスキップして続行します 2.Genymotion エミュレーター: 問題ありません。Genymotion シェルは次のコマンドを実行できません。 3.実マシン (root化): 次に、ファイル エクスプローラーを開いて、data/data/ ディレクトリに何かがあるかどうかを確認します。いいえ? ここでは、まず RE ファイル マネージャー をインストールし、次に RE Root 権限 を付与してから、ルート ディレクトリに移動する方法を示します。 次に、データ ディレクトリを長押しすると、次のようなダイアログ ボックスが表示されます:

4.png10.png

5.png

その後、変更が完了したら、DDMS の ファイル エクスプローラー を開きます。もう一度見ると、次のことがわかります:

6.png

OK、データ/データで物事を見ることができます! ————————————————————

2. adb シェルに入り、次のコマンドを入力してアプリのデータベース ディレクトリに移動します:

7.png

次に、次のコマンドを順番に入力します:

  • sqlite3 my.db: データベース ファイル
  • .table を開いて、データベース内にどのテーブルがあるかを確認します。 次に、クエリなどのデータベース ステートメントを直接入力できます。 Select * from person
  • .schema: テーブル作成ステートメントを表示します
  • .quit: データベース編集を終了します
  • .exit: デバイスを終了しますconsole

... system/bin/sh sqlite3: not found のため、この問題は後続の Sqlite コマンドが使用できないことを意味します。 レンダリングを見たい場合は、Guo Daxia の本を自分で調べてください~ ただし、以下では、最初に db ファイルをエクスポートしてから、グラフィカルなファイルを使用します。 閲覧できるデータベースツール!


4. Android が提供する API を使用して SQLite を操作します

データベース関連の構文を学習していない場合、またはデータベース構文を書きたくない場合は、Android を使用できます。 データベースを操作するためのいくつかの API メソッドを提供します。これらの API の使用法を説明する簡単な例を書いてみましょう。

コード例:

レンダリングの実行:

8.gif

実装コード:

レイアウトはボタンが4つだけでシンプルすぎるため、投稿せず、MainActivity.java:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Context mContext;
    private Button btn_insert;
    private Button btn_query;
    private Button btn_update;
    private Button btn_delete;
    private SQLiteDatabase db;
    private MyDBOpenHelper myDBHelper;
    private StringBuilder sb;
    private int i = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = MainActivity.this;
        myDBHelper = new MyDBOpenHelper(mContext, "my.db", null, 1);
        bindViews();
    }

    private void bindViews() {
        btn_insert = (Button) findViewById(R.id.btn_insert);
        btn_query = (Button) findViewById(R.id.btn_query);
        btn_update = (Button) findViewById(R.id.btn_update);
        btn_delete = (Button) findViewById(R.id.btn_delete);

        btn_query.setOnClickListener(this);
        btn_insert.setOnClickListener(this);
        btn_update.setOnClickListener(this);
        btn_delete.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        db = myDBHelper.getWritableDatabase();
        switch (v.getId()) {
            case R.id.btn_insert:
                ContentValues values1 = new ContentValues();
                values1.put("name", "呵呵~" + i);
                i++;
                //参数依次是:表名,强行插入null值得数据列的列名,一行记录的数据
                db.insert("person", null, values1);
                Toast.makeText(mContext, "插入完毕~", Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_query:
                sb = new StringBuilder();
                //参数依次是:表名,列名,where约束条件,where中占位符提供具体的值,指定group by的列,进一步约束
                //指定查询结果的排序方式
                Cursor cursor = db.query("person", null, null, null, null, null, null);
                if (cursor.moveToFirst()) {
                    do {
                        int pid = cursor.getInt(cursor.getColumnIndex("personid"));
                        String name = cursor.getString(cursor.getColumnIndex("name"));
                        sb.append("id:" + pid + ":" + name + "\n");
                    } while (cursor.moveToNext());
                }
                cursor.close();
                Toast.makeText(mContext, sb.toString(), Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_update:
                ContentValues values2 = new ContentValues();
                values2.put("name", "嘻嘻~");
                //参数依次是表名,修改后的值,where条件,以及约束,如果不指定三四两个参数,会更改所有行
                db.update("person", values2, "name = ?", new String[]{"呵呵~2"});
                break;
            case R.id.btn_delete:
                //参数依次是表名,以及where条件与约束
                db.delete("person", "personid = ?", new String[]{"3"});
                break;
        }
    }
}
のコードを直接貼り付けます。

5. SQL ステートメントを使用してデータベースを操作します

もちろん、すでに SQL を学習し、関連する SQL ステートメントを作成できる場合でも、Android が提供するこれらの API を使用したくない場合もあります。 SQLiteDatabase が提供する関連メソッドを直接使用できます。

  • execSQL(SQL, Object[]): プレースホルダーを含む SQL ステートメントを使用します。これは、データベースの内容を変更する SQL ステートメントを実行するために使用されます。
  • (SQL,Object[]): プレースホルダーを使用した SQL クエリ操作を使用します。 さらに、先ほど Curosr と関連する属性を紹介するのを忘れていましたので、ここに追加します。 ——
  • Cursor オブジェクトは、JDBC の ResultSet に似ており、使用方法も似ています。クエリ結果のレコード ポインターを移動するメソッドは次のとおりです。 move
  • (offset): を指定します。上または下に移動する行数、整数。負の数は上に移動することを意味します。
  • moveToFirst
  • (): ポインタは最初の行に移動し、正常に true を返します。これは、データがあることも示します。
  • moveToLast
  • (): ポインタは最後の行に移動し、正常に true を返します。
  • moveToNext
  • (): ポインター 次の行に移動し、正常に true を返し、まだ要素があることを示します。
  • moveToPrevious
  • (): 前のレコードに移動します
  • getCount
  • (): データの総数を取得します
  • isFirst
  • (): 最初のレコードかどうか
  • isLast
  • (): かどうか最後の 1 つの項目です
  • moveToPosition
  • (int): 指定された行に移動します
  • 使用例:
1. データを挿入します:

public void save(Person p)
{
    SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
    db.execSQL("INSERT INTO person(name,phone) values(?,?)",
                new String[]{p.getName(),p.getPhone()});
}

2. データを削除します:

public void delete(Integer id)
{
    SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
    db.execSQL("DELETE FROM person WHERE personid = ?",
                new String[]{id});
}

3. :

public void update(Person p)
{
    SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
    db.execSQL("UPDATE person SET name = ?,phone = ? WHERE personid = ?",
        new String[]{p.getName(),p.getPhone(),p.getId()});
}

4. クエリデータ:

public Person find(Integer id)
{
    SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
    Cursor cursor =  db.rawQuery("SELECT * FROM person WHERE personid = ?",
            new String[]{id.toString()});
    //存在数据才返回true
    if(cursor.moveToFirst())
    {
        int personid = cursor.getInt(cursor.getColumnIndex("personid"));
        String name = cursor.getString(cursor.getColumnIndex("name"));
        String phone = cursor.getString(cursor.getColumnIndex("phone"));
        return new Person(personid,name,phone);
    }
    cursor.close();
    return null;
}

5. データページング:

public List<Person> getScrollData(int offset,int maxResult)
{
    List<Person> person = new ArrayList<Person>();
    SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
    Cursor cursor =  db.rawQuery("SELECT * FROM person ORDER BY personid ASC LIMIT= ?,?",
        new String[]{String.valueOf(offset),String.valueOf(maxResult)});
    while(cursor.moveToNext())
    {
        int personid = cursor.getInt(cursor.getColumnIndex("personid"));
        String name = cursor.getString(cursor.getColumnIndex("name"));
        String phone = cursor.getString(cursor.getColumnIndex("phone"));
        person.add(new Person(personid,name,phone)) ;
    }
    cursor.close();
    return person;
}

6. レコード数を取得する上記の方法に加えて、次の方法も使用できます。データレコードの数を取得するcursor.getCount()メソッド、 ただし、SQL ステートメントを変更する必要があります。たとえば、

SELECT * FROM person;

このセクションの概要: このセクションでは、Android の組み込み SQLite の基本的な使用法を紹介します。これは、次のセクションでもう少し詳しく説明します。 。 より高度なこと、SQLite トランザクション、アプリケーションがデータベースを更新するときにデータベース内のデータを処理する方法、およびデータベースに大きなバイナリ ファイルを保存する方法 メソッド!さて、このセクションはここまでです~