[Źródło: www.kotlinlang.org]
Program:
Na samym początku należy dołożyć implementację biblioteki SQLCipher w pliku build.grade.
- implementation "net.zetetic:android-database-sqlcipher:3.5.9@aar"
Dalej tworzę przykładową klasę zawierającą dane które będą dokładane do bazy:
- class User{
- var id : Int = 0
- var name : String = ""
- var surname: String = ""
- var age : Int = 0
- constructor(name:String, surname: String, age:Int){
- this.name = name
- this.surname = surname
- this.age = age
- }
- constructor(){
- }
- }
Przed zaimplementowaniem klasy należy dołożyć biblioteki dla SQLite, które muszą pochodzić z pakietów SQLCipher:
Teraz klasa odpowiedzialna za komunikację z bazą danych. Musi ona dziedziczyć po SQLiteOpenHandler, ponieważ w niej zdefiniowane są operacje na bazie:
Kolejnym krokiem jest zdefiniowanie potrzebnych danych w obiekcie companion. Dzięki temu będzie można je wywołać poza klasą:
W nim znajdują się nazwy poszczególnych kolumn czy nazwa bazy danych wraz z wersją.
Teraz tworzę kilka zmiennych przechowujących hasło, kontekst, obiekt bazy danych oraz ścieżkę do pliku.
Nadszedł czas na konstruktor:
W przypadku gdy chcemy usuwać starą bazę danych przed stworzeniem nowej to należy dodać dwie linijki przed stworzeniem:
Aby stworzyć tabelę należy nadpisać funkcję onCreate oraz onUpgrade:
Wprowadzenie danych do bazy:
Odczytanie wszystkich danych z bazy:
Usunięcie wszystkich danych z bazy:
Aktualizacja istniejących danych:
Aby utworzyć nowy obiekt klasy DataBaseHandler wystarczy wywołać następującą linię, po czym wywoływać potrzebne funkcje do zarządzania danymi:
- import net.sqlcipher.database.SQLiteDatabase
- import net.sqlcipher.database.SQLiteOpenHelper
- /*
- Tego nie importujemy, tylko zastępujemy biblioteki na
- te zdefiniowane powyżej
- import android.database.sqlite.SQLiteDatabase
- import android.database.sqlite.SQLiteOpenHelper
- */
Teraz klasa odpowiedzialna za komunikację z bazą danych. Musi ona dziedziczyć po SQLiteOpenHandler, ponieważ w niej zdefiniowane są operacje na bazie:
- class DataBaseHandler : SQLiteOpenHelper{
Kolejnym krokiem jest zdefiniowanie potrzebnych danych w obiekcie companion. Dzięki temu będzie można je wywołać poza klasą:
- companion object {
- val Tag = "DatabaseHandler"
- val DATABASE_NAME = "test7DB.db"
val TABLE_NAME = "users_table"
- val DBVersion = 1
- val COL_ID = "id"
- val COL_NAME = "name"
- val COL_SURNAME = "surname"
- val COL_AGE = "age"
- }
W nim znajdują się nazwy poszczególnych kolumn czy nazwa bazy danych wraz z wersją.
Teraz tworzę kilka zmiennych przechowujących hasło, kontekst, obiekt bazy danych oraz ścieżkę do pliku.
- val DATA_BASE_PASSWORD: String = "testPas2"
- var context: Context? = null
- var sqlObj: SQLiteDatabase
- var databaseFile: File
Nadszedł czas na konstruktor:
- constructor(context: Context) : super(context, DATABASE_NAME, null, DBVersion) {
- this.context = context
- SQLiteDatabase.loadLibs(context)
- databaseFile = context.getDatabasePath(DATABASE_NAME)
- sqlObj = SQLiteDatabase.openOrCreateDatabase(databaseFile, DATABASE_PASSWORD, null)
- }
W przypadku gdy chcemy usuwać starą bazę danych przed stworzeniem nowej to należy dodać dwie linijki przed stworzeniem:
- databaseFile.mkdirs()
- databaseFile.delete()
Aby stworzyć tabelę należy nadpisać funkcję onCreate oraz onUpgrade:
- override fun onCreate(db: SQLiteDatabase?) {
- val createTable = "CREATE TABLE if not exists " + TABLE_NAME + " (" +
- COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
- COL_NAME + " VARCHAR(20)," + COL_SURNAME + " VARCHAR(20)," + COL_AGE + " INTEGER);"
- db?.execSQL(createTable)
- }
- override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
- db!!.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME)
- onCreate(db)
- }
Wprowadzenie danych do bazy:
- fun insertData(user : User){
- val db = this.getWritableDatabase(DATA_BASE_PASSWORD)
- var cv = ContentValues()
- cv.put(COL_NAME,user.name)
- cv.put(COL_SURNAME, user.surname)
- cv.put(COL_AGE,user.age)
- var result = db.insert(TABLE_NAME, null,cv)
- if(result == -1.toLong()){
- Toast.makeText(context, "Failed",Toast.LENGTH_SHORT).show()
- }
- else{
- Toast.makeText(context, "Success",Toast.LENGTH_SHORT).show()
- }
- db.close()
- }
Odczytanie wszystkich danych z bazy:
- fun readData() : MutableList<User>{
- var list : MutableList<User> = ArrayList()
- val db = this.getReadableDatabase(DATA_BASE_PASSWORD)
- val query = "Select * from " + TABLE_NAME
- val result = db.rawQuery(query, null)
- if(result.moveToFirst()){
- do{
- var user = User()
- user.id = result.getString(result.getColumnIndex(COL_ID)).toInt()
- user.name = result.getString(result.getColumnIndex(COL_NAME))
- user.surname = result.getString(result.getColumnIndex(COL_SURNAME))
- user.age = result.getString(result.getColumnIndex(COL_AGE)).toInt()
- list.add(user)
- }while(result.moveToNext())
- }
- result.close()
- db.close()
- return list
- }
Usunięcie wszystkich danych z bazy:
- fun deleteAllData(){
- val db = this.getWritableDatabase(DATA_BASE_PASSWORD)
- db.delete(TABLE_NAME, null, null)
- db.close()
- }
Aktualizacja istniejących danych:
- fun updateData(oldUser: User, newUser: User){
- val db = this.getWritableDatabase(DATA_BASE_PASSWORD)
- var cv = ContentValues()
- cv.put(COL_NAME,newUser.name)
- cv.put(COL_SURNAME, newUser.surname)
- cv.put(COL_AGE,newUser.age)
- db.update(TABLE_NAME, cv, COL_ID + "=" + oldUser.id, null)
- }
Aby utworzyć nowy obiekt klasy DataBaseHandler wystarczy wywołać następującą linię, po czym wywoływać potrzebne funkcje do zarządzania danymi:
- val context = this
- var db = DataBaseHandler(context)