Baza implementacja – SQLiteOpenHelper – #04

Zacznijmy standardowo i powoli. Na początek potrzebujemy czegoś małego żeby w ogóle zacząć. Tabelka Meals ma u mnie tylko jedną kolumnę, którą muszę obsłużyć samodzielnie, kolumna z ID obsłuży się automagicznie po tym jak ustawię ją jako Primary Key. Dobry kandydat 🙂

Po zapoznaniu się z tutorialem i przeszukaniem niezastąpionego stackOverflow wstępnie stworzyłam klasę CoNaObiadDbHelper, która rozszerza androidową klasę do obsługi bazy SQLite.


public class CoNaObiadDbHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 2;
public static final String DATABASE_NAME = "CoNaObiad.db";
public static final String TABLE_NAME = "meal";
public static final String COLUMN_NAME_NAME = "name";
public static final String COLUMN_NAME_ID = "_id";
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + TABLE_NAME + " (" +
COLUMN_NAME_ID + " INTEGER PRIMARY KEY," +
COLUMN_NAME_NAME + " TEXT)";
private static final String SQL_DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
private static final String SQL_DELETE_ENTRIES = "DELETE FROM " + TABLE_NAME;
public CoNaObiadDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(SQL_DROP_TABLE);
onCreate(db);
}
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(SQL_DROP_TABLE);
onCreate(db);
}
public void cleanData() {
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL(SQL_DELETE_ENTRIES);
}
}

Możemy w niej znaleźć nazwę bazy danych, tabelki, nazwy kolumn. Kilka query do tworzenia, czyszczenia (na początek dość przydatne 😉 ) i usuwania tabelki. Nadpisujemy metody z klasy bazowej: onCreate, onUpgrade, onDowngrade żeby wykonywały query, które podamy. To o czym musimy pamiętać w tym miejscu to to, że sami dbamy o zmianę struktury bazy (in|de)krementując stałą DATABASE_VERSION przed odpaleniem aplikacji.

Do metod, których potrzebuję na wejściu należy taka, która wypisze mi wszystkie posiłki, które mam zapisane w bazie. Do osiągnięcia tej metody użyję kursora i prostego query… prostego jak select * from table.


public ArrayList<String> getAllMeals() {
ArrayList<String> array_list = new ArrayList<String>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery("select * from " + TABLE_NAME, null);
res.moveToFirst();
do {
String mealName = res.getString(res.getColumnIndex(COLUMN_NAME_NAME));
array_list.add(mealName);
} while (res.moveToNext());
return array_list;
}

Przyda nam się też metoda, która wstawia dane do tabelki:


public boolean insertMeal(String name) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("name", name);
db.insert(TABLE_NAME, null, contentValues);
return true;
}

Otwieramy bazę w trybie do zapisu. Tworzymy obiekt ContentValues, który jest bardziej rozbudowaną tablicą haszującą i SQLiteDatabase zadba o odpowiednich insertów.

Tej metody możemy użyć od razu wstawiając przykładowe potrawy prosto do tabelki:


public void initializeMealTable() {
List<String> meals = Arrays.asList("bigos", "rosół", "zapiekanka", "pierogi", "pomidorowa", "pesto", "meksykański ryż czerwony");
for (int i = 0; i < meals.size(); i++) {
insertMeal(meals.get(i));
}
}

Czyli teraz nasza główna klasa wzbogaciła się o odczyt z bazy i wygląda tak:


private CoNaObiadDbHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new CoNaObiadDbHelper(this);
dbHelper.cleanData();
dbHelper.initializeMealTable();
List<String> preparedRows = DinnerListHelper.getPreparedRows(new Date(), dbHelper.getAllMeals());
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, preparedRows);
ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);
}

Przy tworzeniu głównej aktywności tworzę bazę, czyszczę ją i inicjalizuję wartościami, które miałam w liście. Docelowo to czyszczenie i inicjalizacja pójdzie precz, ale na ten moment potrzebuję danych do wyświetlenia.

Póki co jest dobrze, ale za moment chcę stworzyć drugą tabelkę, w przyszłości trzecią. A w kodzie takie coś:  TABLE_NAME, COLUMN_NAME_NAME… Tak nie może zostać! Kolejnym krokiem jest zrefaktorowanie klasy CoNaObiadDbHelper tak żeby wyjąć z niej wszystko co dotyczy tabelki Meal i wstawić do osobnej klasy, tak żeby przy kolejnych modyfikacjach obszar zmian był jak najmniejszy.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

This site uses Akismet to reduce spam. Learn how your comment data is processed.