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