0. Tworzymy projekt typu Android App (Xamarin) o nazwie BazaDanychSQLite z szablonem Blank App. 1. Modyfikujemy plik activity_main.xml dodając kontrolkę TextView: 2. Do projektu dodajemy plik klasy BazaDanychOsob.cs. Klasa powinna dziedziczyć z klasy Android.Database.Sqlite.SQLiteOpenHelper. Wykorzystujemy pozycję menu kontekstowego "Implement Abstract Class". Powstaną metody OnCreate i OnUpdate. Dodatkowo nadpisujemy konstruktor: using Android.Content; using Android.Database.Sqlite; namespace BazaDanychSQLite { public class BazaDanychOsob : SQLiteOpenHelper { public BazaDanychOsob(Context context) : base(context, "osoby.db", null, 1) { } public override void OnCreate(SQLiteDatabase db) { //tworzenie bazy danych } public override void OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //zmiana wersji } } } version - numer struktury bazy danych (rekordu i tabel), należy go zwiększać przy zmianach w strukturze bazy OnCreate - wywoływana przy tworzeniu pliku (po pierwszym uruchomieniu) OnUpgrade - aktualizacja wersji bazy danych 3. Definiujemy klasę opisującą rekord w tabeli (klasa encji, osobny plik Osoba.cs) namespace BazaDanychSQLite { public class Osoba { public const string NazwaTabeli = "osoby"; public static readonly string[] NazwyKolumnTabeli = { "Id", "Imię", "Nazwisko", "Wiek", "NumerTelefonu" }; public static readonly string[] WłasnościKolumnTabeli = { "INTEGER PRIMARY KEY", "TEXT", "TEXT", "INTEGER", "INTEGER" }; public const string NazwaBazyDanych = NazwaTabeli + ".db"; public int Id; public string Imię; public string Nazwisko; public int Wiek; public int NumerTelefonu; public Osoba(int id, string imię, string nazwisko, int wiek, int numerTelefonu) { this.Id = id; this.Imię = imię; this.Nazwisko = nazwisko; this.Wiek = wiek; this.NumerTelefonu = numerTelefonu; } public override string ToString() { return "" + Id + ") " + Imię + " " + Nazwisko + " (" + Wiek + "), tel. " + NumerTelefonu; } } } 5. Przygotowujemy polecenia tworzące tabelę w bazie danych: using Android.Content; using Android.Database.Sqlite; namespace BazaDanychSQLite { public class BazaDanychOsob : SQLiteOpenHelper { public BazaDanychOsob(Context context) : base(context, "osoby.db", null, 1) { } public override void OnCreate(SQLiteDatabase db) { string createCommand = "create table " + Osoba.NazwaTabeli + "("; <--------------------------------------- for (int numerKolumny = 0; numerKolumny < Osoba.NazwyKolumnTabeli.Length; ++numerKolumny) { string nazwaKolumny = Osoba.NazwyKolumnTabeli[numerKolumny]; string własnościKolumny = Osoba.WłasnościKolumnTabeli[numerKolumny]; createCommand += nazwaKolumny + " " + własnościKolumny + ","; } createCommand = createCommand.Substring(0, createCommand.Length - 1); createCommand += ")"; db.ExecSQL(createCommand); } public override void OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //zmiana wersji } } } 6. W klasie BazaDanychOsób definiujemy metody pozwalającą na dodanie rekordu do tabeli: private ContentValues wartościZOsoby(Osoba osoba) { ContentValues wartości = new ContentValues(); wartości.Put(Osoba.NazwyKolumnTabeli[0], osoba.Id); wartości.Put(Osoba.NazwyKolumnTabeli[1], osoba.Imię); wartości.Put(Osoba.NazwyKolumnTabeli[2], osoba.Nazwisko); wartości.Put(Osoba.NazwyKolumnTabeli[3], osoba.Wiek); wartości.Put(Osoba.NazwyKolumnTabeli[4], osoba.NumerTelefonu); return wartości; } public void DodajRekord(Osoba osoba) { SQLiteDatabase db = this.WritableDatabase; ContentValues wartości = wartościZOsoby(osoba); db.InsertOrThrow(Osoba.NazwaTabeli, null, wartości); } 7. ... i pobranie wszystkich rekordów private Osoba osobaZKaretki(ICursor karetka) { Osoba osoba = new Osoba( karetka.GetInt(0), //Id karetka.GetString(1), //Imię karetka.GetString(2), //Nazwisko karetka.GetInt(3), //Wiek karetka.GetInt(4)); //NumerTelefonu return osoba; } public Osoba[] PobierzWszystkieRekordy(string orderBy) { SQLiteDatabase db = this.ReadableDatabase; ICursor karetka = db.Query(Osoba.NazwaTabeli, Osoba.NazwyKolumnTabeli, null, null, null, null, orderBy); List lista = new List(); while (karetka.MoveToNext()) { lista.Add(osobaZKaretki(karetka)); } karetka.Close(); Osoba[] tablica = lista.ToArray(); return tablica; } public Osoba[] PobierzWszystkieRekordy() { return PobierzWszystkieRekordy(null); } 8. Testujemy w klasie MainActivity: using Android.App; using Android.OS; using Android.Support.V7.App; using Android.Widget; namespace BazaDanychSQLite { [Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)] public class MainActivity : AppCompatActivity { protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Set our view from the "main" layout resource SetContentView(Resource.Layout.activity_main); //usuwam bazę danych - ma sens tylko do nauki bool wynik = this.DeleteDatabase(Osoba.NazwaBazyDanych); Toast.MakeText(ApplicationContext, "Usunięcie bazy danych: " + wynik.ToString(), ToastLength.Short).Show(); //tworzę bazę danych i dodaję rekordy BazaDanychOsob dbm = new BazaDanychOsob(this); dbm.DodajRekord(new Osoba(0, "Jacek", "Matulewski", 45, 123456789)); dbm.DodajRekord(new Osoba(1, "Jan", "Kowalski", 46, 987654321)); dbm.DodajRekord(new Osoba(2, "John", "Smith", 20, 987654321)); dbm.DodajRekord(new Osoba(3, "Hans", "Muller", 32, 564738219)); //dbm.dodajRekord(new Osoba(0, "Jacek2", "Matulewski2", 32, 564738219)); //czytam zawartość bazy danych Osoba[] osoby = dbm.PobierzWszystkieRekordy("Imię"); pokażOsoby(osoby); } private void pokażOsoby(Osoba[] osoby) { TextView tv = FindViewById(Resource.Id.textView); //tv.setText(Integer.toString(osoby.length)); string sRekordy = "Rekordy:"; foreach (Osoba osoba in osoby) sRekordy += "\n" + osoba.ToString(); tv.Text = sRekordy; } } } 8. [Zadanie dla studentów!!] Implementacja metody pozwalającej na pobranie rekordu po identyfikatorze (pole Id) public Osoba pobierzRekord(int id) 9. Implementujemy w klasie BazaDanychOsób resztę operacji CRUD dla rekordów public bool UsuńRekord(int id) { SQLiteDatabase db = WritableDatabase; string[] whereArgs = { id.ToString() }; return db.Delete(Osoba.NazwaTabeli, "Id=?", whereArgs) > 0; } public bool ZmieńRekord(int id, Osoba osoba) { SQLiteDatabase db = WritableDatabase; ContentValues wartości = wartościZOsoby(osoba); string[] whereArgs = { id.ToString() }; return db.Update(Osoba.NazwaTabeli, wartości, "Id=?", whereArgs) > 0; } 10. Testy w klasie MainActivity: protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Set our view from the "main" layout resource SetContentView(Resource.Layout.activity_main); //usuwam bazę danych - ma sens tylko do nauki bool wynik = this.DeleteDatabase(Osoba.NazwaBazyDanych); Toast.MakeText(ApplicationContext, "Usunięcie bazy danych: " + wynik.ToString(), ToastLength.Short).Show(); //tworzę bazę danych i dodaję rekordy BazaDanychOsob dbm = new BazaDanychOsob(this); dbm.DodajRekord(new Osoba(0, "Jacek", "Matulewski", 45, 123456789)); dbm.DodajRekord(new Osoba(1, "Jan", "Kowalski", 46, 987654321)); dbm.DodajRekord(new Osoba(2, "John", "Smith", 20, 987654321)); dbm.DodajRekord(new Osoba(3, "Hans", "Muller", 32, 564738219)); //dbm.dodajRekord(new Osoba(0, "Jacek2", "Matulewski2", 32, 564738219)); //czytam zawartość bazy danych Osoba[] osoby = dbm.PobierzWszystkieRekordy("Imię"); pokażOsoby(osoby); dbm.UsuńRekord(1); <---------------------------- osoby = dbm.PobierzWszystkieRekordy(null); pokażOsoby(osoby); dbm.ZmieńRekord(0, new Osoba(4, "Jean", "Dupont", 50, 1230198318)); osoby = dbm.PobierzWszystkieRekordy("Imię"); pokażOsoby(osoby); //dbm.Close(); } 11. [Zadanie dla studentów] - przygotować klasę BazaDanych - odseparować funkcje obsługi bazy danych i klasy encji