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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.