2015年10月20日火曜日

SQLite使い方 --01 導入編

Android端末内で情報を保存する際に、
以前紹介した

http://androidgamepark.blogspot.jp/2013/01/preferencemanager-sharedpreferences.html

もありますが、今回はSQLiteを使ったデータ管理方法を記します。

また、SQLの事を深く掘り下げはしないので、SQLが何かよくわからない人はこの先は見てもいいことないです。。。

とりあえずの今回はSQLite導入方法を紹介します。

使うのは
SQLiteDatabase
SQLiteOpenHelperをextendしたクラスです。

■DBコネクト

public class SQliteOpenHelperClass extends SQLiteOpenHelper {

    public SQliteOpenHelperClass(Context c) {
        super(c, DB, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        db.execSQL(CREATE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(DROP_TABLE);
        onCreate(db);
    }
}

これを通して、DBに接続したり、クエリーを発行します。

SQliteOpenHelperClass oSQLhlpr = new SQliteOpenHelperClass( getApplicationContext());

SQLiteDatabase oDB = oSQLhlpr.getWritableDatabase();

こんな感じで生成します。引数にContextですね。
getWritableDatabase()でデータベースにコネクトします。

コネクト時にOnCreateを読んで、
テーブルが存在しなかったら、テーブルを作成します。

onUpgradeは引数のDBバージョンがテーブル作成時より大きかったら呼ばれます。



■クエリー

・select系
Cursor型 = rawQuery(String sql文, String[] selectionArgs)

Cursor型 = query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)

・insert専用
long型 = insert(String table, String nullColumnHack, ContentValues values)

・引数がいらない場合(insert系)
execSQL(文字列鋳型(SQL文))

クエリーの取得するメソッドはいろいろあります。

■サンプルソース
・メインアクティビティー
package jp.co.appli.sqlitetest;

import android.app.Activity;

import android.app.ActionBar;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;

public class MainActivity extends Activity implements View.OnClickListener {

    static final String DB           = "sqlite_sample.db";
    static final int DB_VERSION      = 1;
    static final String TABLE_NAME   = "sample_table";
    static final String CREATE_TABLE = "create table " + TABLE_NAME +" ( sample_id integer primary key autoincrement, test_id integer not null, memo text not null );";
    static final String DROP_TABLE   = "drop table "+ TABLE_NAME +";";
    static SQLiteDatabase oDB;
    private SampleAdapter sampleAdapter;

    //レイアウトパラメータ
    private final int WC = ViewGroup.LayoutParams.WRAP_CONTENT;
    private final int MP = ViewGroup.LayoutParams.MATCH_PARENT;
    private ListView listView;

    private CharSequence mTitle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //メイン画面の作成
        LinearLayout oLayout =new LinearLayout( getApplicationContext());
        oLayout.setOrientation(LinearLayout.VERTICAL);
        setContentView(oLayout);

        //リストビューの作成
        listView      = new ListView(getApplicationContext());

        //リストビューのアダプターを作成
        sampleAdapter = new SampleAdapter(getApplicationContext());

        //SQLiteとの橋渡しするクラス
        SQliteOpenHelperClass oSQLhlpr = new SQliteOpenHelperClass( getApplicationContext());
        //DBに接続する
        oDB = oSQLhlpr.getWritableDatabase();

        //セレクト分の実行結果を取得
        Cursor cursor = oDB.query( TABLE_NAME, new String[] {"sample_id", "test_id", "memo"}, null, null, null, null, "sample_id DESC");

        //アダプターの作成
        makeAdapter(cursor);
        cursor.close();

        //リストビューにアダブターを設定
        listView.setAdapter( sampleAdapter );
        listView.setLayoutParams( new ActionBar.LayoutParams( WC, MP ) );

        //リスト選択時の処理を記述
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            //選択されたリストを消去する処理
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id)
            {

                //アダプタから、アイテムを取得
                ItemClass item = sampleAdapter.getItem(position);
                //デリートメソッドを発行
                oDB.delete( TABLE_NAME, "sample_id = ?", new String[]{ String.valueOf(item.getPrimary()) } );

                //テーブル情報を取得
                Cursor cursor = oDB.query( TABLE_NAME, new String[] {"sample_id", "test_id", "memo"}, null, null, null, null, "sample_id DESC");

                //リストビュー内のアダプターを作成
                makeAdapter(cursor);
                cursor.close();

                //Adapteの中身を更新
                sampleAdapter.notifyDataSetChanged();
                //リストビューの再描画
                listView.invalidateViews();
            }
        });

        //追加ボタンの作成
        Button AddBtn = new Button( getApplicationContext() );
        AddBtn.setOnClickListener( this );
        AddBtn.setId( 1 );
        AddBtn.setText( "追加" );
        AddBtn.setLayoutParams( new ActionBar.LayoutParams( WC,WC ) );

        //削除ボタンの作成
        Button DelBtn = new Button( getApplicationContext() );
        DelBtn.setOnClickListener( this );
        DelBtn.setId( 2 );
        DelBtn.setText( "全削除" );
        DelBtn.setLayoutParams( new ActionBar.LayoutParams( WC,WC ) );

        oLayout.addView( AddBtn );
        oLayout.addView( DelBtn );
        oLayout.addView( listView );

    }



    private void makeAdapter( Cursor cursor )
    {
        sampleAdapter.truncateItemList();
        for (boolean next = cursor.moveToFirst(); next; next = cursor.moveToNext())
        {
            ItemClass item = new ItemClass();
            item.setPrimary( cursor.getInt( 0 ) );
            item.setMemo( cursor.getString( 2 ) );
            sampleAdapter.addItem(item);
        }
    }


    @Override
    public void onClick(View view)
    {
        if (view.getId() == 1)
        {
            ContentValues values = new ContentValues();
            values.put( "test_id", 4 );
            values.put( "memo", "こんなところに来てしまったあ" );
            oDB.insert( "sample_table", null, values );

            Cursor cursor = oDB.query( TABLE_NAME, new String[] {"sample_id", "test_id", "memo"}, null, null, null, null, "sample_id DESC");
            makeAdapter(cursor);
            cursor.close();

        }
        else if (view.getId() == 2)
        {
            //全件削除
            oDB.delete("sample_table", "test_id like '%'", null);

            //全件取得メソッド
            Cursor cursor = oDB.query("sample_table", new String[] {"sample_id", "test_id", "memo"}, null, null, null, null, "sample_id DESC");
            makeAdapter(cursor);
            cursor.close();
        }

        //Adapteの中身を更新
        sampleAdapter.notifyDataSetChanged();
        listView.invalidateViews();
    }

    public class SQliteOpenHelperClass extends SQLiteOpenHelper
    {

        public SQliteOpenHelperClass(Context c) {
            super(c, DB, null, DB_VERSION);
        }

        @Override
        public void onCreate( SQLiteDatabase db )
        {

            db.execSQL( CREATE_TABLE );
        }

        @Override
        public void onUpgrade( SQLiteDatabase db, int oldVersion, int newVersion )
        {
            db.execSQL( DROP_TABLE );
            onCreate(db);
        }
    }
}




・アダプタクラス
package jp.co.appli.sqlitetest;
import android.content.Context;
import android.graphics.Color;
import android.view.ViewGroup;
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.List;
import java.util.ArrayList;


public class SampleAdapter extends BaseAdapter
{
    //コンテキストを取得
    private Context mContext;
    //リスト情報を格納している配列
    private List<ItemClass> dataList = new ArrayList<ItemClass>();
    //レイアウトパラムの定数
    private final int MP = ViewGroup.LayoutParams.MATCH_PARENT;

    //コンストラクターで生成時に呼ばれる
    public SampleAdapter( Context context )
    {
        //生成時のコンストラクターでコンテクストを取得
        mContext = context;
    }

    @Override
    public int getCount()
    {
        //リストの行数
        return dataList.size();
    }

    @Override
    public ItemClass getItem(int posion)
    {
        //配列の中身を返す
        return dataList.get(posion);
    }

    @Override
    public long getItemId(int posion) {
        //現在の配列の場所
        return posion;
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {

        View v = view;
        if( v == null ){

            //グリットビューの1マス内のレイアウトを作成
            LinearLayout oListLayout = new LinearLayout(mContext);
            //左から右にアイテムを追加
            oListLayout.setOrientation(LinearLayout.HORIZONTAL);
            //テキストビューを生成
            TextView primaryText  = new TextView(mContext);
            //文字大きさの指定
            primaryText.setTextSize(10);
            //文字の色も指定
            primaryText.setTextColor(Color.BLACK);
            //判別用にタグをつける
            primaryText.setTag( "primary" );

            //テキストビューを生成
            TextView memoText  = new TextView(mContext);
            //文字大きさの指定
            memoText.setTextSize(15);
            //文字の色も指定
            memoText.setTextColor(Color.BLACK);
            //判別用にタグをつける
            memoText.setTag("memo");

            oListLayout.addView( primaryText );
            oListLayout.addView( memoText );
            v = oListLayout;
        }

        ItemClass item = getItem( position );

        //配列から、アイテムを取得
        if( dataList != null)
        {
            //タグからテキストビューを取得
            TextView primaryText = (TextView)v.findViewWithTag( "primary" );
            //取得したテキストビューに文字列を設定
            primaryText.setText( String.valueOf( item.getPrimary() ) );

            TextView memoText = (TextView)v.findViewWithTag( "memo" );
            //取得したテキストビューに文字列を設定
            memoText.setText( String.valueOf( item.getMemo() ) );
        }

        return v;
    }

    //データリストの追加
    public void addItem(ItemClass item)
    {
        dataList.add( item );
    }

    //データリストの削除
    public void deleateItem(int iPos){
        dataList.remove(iPos);
    }

    public void truncateItemList(){
        dataList.clear();
    }
}

class ItemClass
{
    private String memo;
    private int    primary;

    public void setMemo( String _memo )
    {
        memo = _memo;
    }

    public void setPrimary( int _primary )
    {
        primary = _primary;
    }


    public String getMemo()
    {
        return memo;
    }

    public int getPrimary()
    {
        return primary;
    }

}


■実行結果
1.初期表示

2.追加ボタンを押す

3.行を選択すると消える(途中の数字が抜けてる)


4.全削除を押すと全部消える

5.また、追加できる(auto incrementなので数字は受け継がれる)


こんな感じになります。

■select

//全件取得メソッド
Cursor cursor = oDB.query( TABLE_NAME, new String[] {"sample_id", "test_id", "memo"}, null, null, null, null, "sample_id DESC");

クエリーのところはPDOのノリで大丈夫です。

第3引数にWHERE句、第4引数にパラメータをわたします。

//sample_idの18と20のみを取得する
Cursor cursor = oDB.query( TABLE_NAME, new String[] {"sample_id", "test_id", "memo"}, "sample_id = ? or sample_id = ?", new String[]{"18", "20" }, null, null, "sample_id DESC");

? の場所にパラメータを代入させます。型は文字列で。

■cursor
makeAdapterの
            item.setPrimary( cursor.getInt( 0 ) );
            item.setMemo( cursor.getString( 2 ) );

ここで、メソッドの取得結果を格納しています。
指定したフィールドから、配列で値が返ってきます。


 今回はサンプルソースなので、いろいろな場所から、クエリーを発行していますが、
実際にリリースするアプリでは、クエリーの作成する場所や発行する場所は決めておいた方がいいと思います。

このソース内のSQliteがどのようにデータを持っているか確認するには、
http://androidgamepark.blogspot.jp/2015/10/androidsqlite-sqlite.html

を参照して下さい。

0 件のコメント:

コメントを投稿