select
データベースをオープンしたclsDatabaseOpenを継承して作ったクラスです。
一つのクラスとしてまとめても構いませんが、長かったので継承をして分離させました。
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.content.Context;
import android.util.Log;
import java.util.ArrayList;
public class clsDatabaseSelect extends clsDatabaseOpen {
//エラーの戻り値に使用
private int mError = 0;
clsDatabaseSelect(Context context)
{
super(context);
//初期化処理
mError = 0;
}
//エラーを返す
public int getmError()
{
return mError;
}
//テーブルデータイメージ
/*
C:\test>C:\test\sqlite3.exe test.db
SQLite version x.x.x
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables
tbl1 tbl2
sqlite> .schema tbl1
CREATE TABLE tbl1(
fld1 integer,
fld2 double,
fld3 text,
primary key(fld1)
);
sqlite> .schema tbl2
CREATE TABLE tbl2(
fld1 integer,
fld2 double,
fld3 text,
primary key(fld1)
);
sqlite> select * from tbl1;
1|1.5|aaa
2|2.5|bbb
3|3.5|ccc
sqlite> select * from tbl2;
1|1.5|aaa
3|3.5|ccc
4|4.5|ccc
sqlite> .exit
C:\test>
*/
//通常のSQL
public void selectTest1()
{
ArrayList<Integer> array = new ArrayList<>();
StringBuilder sSQL = new StringBuilder();
sSQL.append(" select fld1 from tbl1");
sSQL.append(" where");
sSQL.append(" fld1 > 0");
Log.d("selectTest1 sql",sSQL.toString());
array = selectNum(sSQL.toString());
for(int i=0; i<array.size(); i++)
{
Log.d("i", String.valueOf(array.get(i)));
}
return;
}
//SQLパラメータがあるケース
public void selectTest2()
{
ArrayList<Integer> array = new ArrayList<>();
StringBuilder sSQL = new StringBuilder();
sSQL.append(" select");
sSQL.append(" tbl1.fld1");
sSQL.append(" from tbl1");
sSQL.append(" left join tbl2");
sSQL.append(" on");
sSQL.append(" tbl1.fld1 = tbl2.fld1");
sSQL.append(" where");
sSQL.append(" tbl2.fld1 is not null");
sSQL.append(" and tbl1.fld1 > ?");
Log.d("selectTest2 sql",sSQL.toString());
//SQL内の「?」に使用するデータをString[]配列に設定します
//例えば「?」(すべて数字の場合)が3個なら次のように設定します
//String[] arrayData = {"1", "4", "5"};
String[] arrayData = {"1"};
array = selectNum(sSQL.toString(), arrayData);
for(int i=0; i<array.size(); i++)
{
Log.d("i", String.valueOf(array.get(i)));
}
return;
}
private ArrayList<Integer> selectNum(String sSQL)
{
//SQLパラメータの「?」を使用しないのでnullを設定します
String[] arrayData = null;
return selectNum(sSQL, arrayData);
}
private ArrayList<Integer> selectNum(String sSQL, String[] arrayData)
{
ArrayList<Integer> array = new ArrayList<>();
//このクラスはclsDatabaseOpenを継承しており、継承したクラスでは
//SQLiteOpenHelperを継承しているためSQLiteDatabaseの宣言は不要となり
//superを用いることによりSQLiteDatabaseのオブジェクトを使用できます。
//このため次のような宣言をこのサンプルではしておりません。
//SQLiteDatabase db = super.getReadableDatabase();
Cursor cursor = null;
try
{
//SQLの実行
cursor = super.db.rawQuery(sSQL, arrayData);
Log.d("selectNum","SQLの実行しました");
//カーソル位置を先頭にします
cursor.moveToFirst();
Log.d("selectNum","カーソル位置を先頭にしました");
Log.d(" cursor.getCount()", String.valueOf( cursor.getCount()));
for (int i = 0; i < cursor.getCount(); i++)
{
//このサンプルでは使用しているカラムが1個です
//そのため取得している添え字が0となっています
//※添え字が0から始まるため
//カラムが3個あれば(すべて数字の場合)次のように取得します。
//(例)
//1個目:cursor.getInt(0)
//2個目:cursor.getInt(1)
//3個目:cursor.getInt(2)
//取得方法は次の方法があります
array.add(cursor.getInt(0));
//getColumnIndexを使用する場合は次のようにカーソルでキャストしてください
//array.add(cursor.getInt(cursor.getColumnIndex("fld1")));
//カーソルを進める
cursor.moveToNext();
}
//次のように実装してもデータを取得できます。
/*
boolean result = false;
while (true){
//カーソルのデータを取得します
array.add(cursor.getInt(0));
//カーソルを進める
result = cursor.moveToNext();
Log.d("selectNum","カーソルを進めました");
if(result == false)break;
}
*/
//次のように実装してもデータを取得できます。
/*
boolean result = false;
do
{
//カーソルのデータを取得します
array.add(cursor.getInt(0));
result = cursor.moveToNext();
}while (result);
*/
cursor.close();
Log.d("selectNum","カーソルを閉じました");
}
catch (Exception e)
{
mError = 1;
Log.d("error", e.getMessage().toString());
return array;
}
finally
{
cursor = null;
}
return array;
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
|
このサンプルではsqlを使用したデータの取得をするため「rawQuery」メソッドを使用しています。
カーソルにデータを格納後、「moveToFirst」でカーソルの先頭に移動させて
データの最初から順次、moveToNextメソッドでカーソルを次のデータに移動させながら
次のデータを取得します。
「moveToNext」メソッドは戻り値をboolean型で返すため
doやwhileを使用した場合は、その戻り値を用いた判定をすることで
終了条件を作ることができます。
サンプルでは数字のみの例を紹介しました。
(例)
cursor.getInt(0)
文字列はcursor.getString(0)のようにすればいいだけなので
通常の配列データの扱いと同じになっていますので、問題はないかと思います。
プログラム中にも記述した通り、カラムは添え字0(ゼロ)から1、2、…、nのようにインクリメントした
値を使用することになります。
添え字を使用しない方法として「getColumnIndex」があります。
これを使用する場合はキャストをするのを忘れないでください。
忘れると数字であれば0になってしまうはずです。(テストしてみた結果による)
(例)
cursor.getInt(cursor.getColumnIndex("fld1"))
カーソルは使い終わったら閉じることをお勧めします。
(例)
cursor.close();
whileやdo文を使用する場合は0件のときに実装によってはエラーが発生することがあるので
0件のときは呼び出さないようにif文などで制御をした方がいいと思います。
(例)
if(cursor.getCount()>0)
{
//処理
}
データベースの接続・切断を継承しているクラスは次のページを参考にしてください。
URL [http://abc3.me/computer/android/4/android-7-1.php] (クリックをすると開きます)
クラスの呼び出し側です。
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
databaseSelect();
//databaseOpenClose();
//readFile();
}
private void databaseSelect()
{
int iResult = 0;
clsDatabaseSelect cls = new clsDatabaseSelect(this);
if (cls.DatabaseOpen() > 0)
{
cls = null;
Log.d("databaseOpenClose", "データ接続エラーが発生しました。");
return;
}
//通常のSQL
cls.selectTest1();
if (cls.getmError() > 0)
{
cls.DatabaseClose();
cls = null;
Log.d("databaseOpenClose", "データ取得エラーが発生しました。");
return;
}
//SQLパラメータがあるケース
cls.selectTest2();
if (cls.getmError() > 0)
{
cls.DatabaseClose();
cls = null;
Log.d("databaseOpenClose", "データ取得エラーが発生しました。");
return;
}
if (cls.DatabaseClose() > 0)
{
Log.d("databaseOpenClose", "データ切断エラーが発生しました。");
return;
}
}
}
|
|
|