Verwenden der Schlüsselwertdatenbank von Snappy in Android

SnappyDB - NoSQL-Schlüsselwertdatenbank für Android. Es ist recht einfach zu bedienen und eine gute Option, wenn Sie die NoSQL-Version der Datenbank in Ihrem Projekt verwenden möchten (weitere Details hier ).
Laut den Entwicklern ist Snappy beim Schreiben und Lesen schneller als SQLite:

Bild

Also fangen wir an. Zuerst müssen Sie Abhängigkeiten zu build.gradle hinzufügen: Beginnen wir nun direkt mit der Arbeit mit der Datenbank selbst. Lassen Sie uns zunächst herausfinden, wie Sie mit SnappyDB mit primitiven Typen und Arrays arbeiten, diese speichern und abrufen können. Erstellen Sie aus Gründen der Übersichtlichkeit ein kleines Markup:

implementation 'com.snappydb:snappydb-lib:0.5.2'
implementation 'com.esotericsoftware.kryo:kryo:2.24.0'





<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/filmNameTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:layout_centerInParent="true"
        android:layout_margin="8dp"
        />

    <TextView
        android:id="@+id/filmBudgetTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textSize="25sp"
        android:layout_below="@+id/filmNameTextView"
        android:layout_margin="8dp"
        />

    <TextView
        android:id="@+id/genreTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textSize="25sp"
        android:layout_below="@id/filmBudgetTextView"
        android:layout_margin="8dp"
        />

    <TextView
        android:id="@+id/isAdult"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/genreTextView"
        android:textSize="25sp"
        android:layout_centerInParent="true"
        />
</RelativeLayout>



Angenommen , wir speichern Filmdaten in unserer Datenbank. In MainActivity erstellen wir die PutValues-Methode:
private void putValues(String name, int budget, boolean isAdult, String[] genres) throws SnappydbException {
        DB snappyDB = DBFactory.open(this,"Film");
        //     Film (      open)

        snappyDB.put("Name", name);
        snappyDB.putInt("budget", budget);
        snappyDB.putBoolean("isAdult", isAdult);
        snappyDB.put("genres", genres);
        //       
}

Beachten Sie, dass die Methode, mit der wir mit SnappyDB arbeiten, eine SnappydbException auslösen sollte.

Jetzt schreiben wir die setValues-Methode, um Daten aus der Datenbank abzurufen und auszugeben:
private void setValues(DB snappyDB) throws SnappydbException {
        TextView filmNameTextView = findViewById(R.id.filmNameTextView),
                 filmBudgetTextView = findViewById(R.id.filmBudgetTextView),
                 genresTextView = findViewById(R.id.genreTextView),
                 isAdultTextView = findViewById(R.id.isAdult); //    

        String name = snappyDB.get("Name");
        int budget = snappyDB.getInt("budget");
        boolean isAdult = snappyDB.getBoolean("isAdult");
        String[] genres = snappyDB.getObjectArray("genres", String.class);//2  =  
        //  get...     

        filmNameTextView.setText(name);
        filmBudgetTextView.setText(String.valueOf(budget));
        isAdultTextView.setText(String.valueOf(isAdult));

        for(int i = 0;i < genres.length;i++) {
            genresTextView.setText(genresTextView.getText() + " " + genres[i]);
        }
}


Rufen Sie die erstellten Methoden in onCreate auf (stellen Sie sicher, dass Sie sie mit einem try / catch-Block umgeben):
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            putValues("Forrest Gump", 677000000,false, new String[] {"Drama","Melodrama"});
        } catch (SnappydbException e) {
            e.printStackTrace();
        }
        
        try {
            DB snappyDB = DBFactory.open(this, "Film");
            setValues(snappyDB);
        } catch (SnappydbException e) {
            e.printStackTrace();
        }
}


Wir beginnen und sehen, dass alles richtig funktioniert:
Bild

Lassen Sie uns nun herausfinden, wie wir mit unseren eigenen Klassen und anderen komplexen Typen arbeiten können.
Erstellen Sie eine Filmklasse mit 3 Feldern:
public class Film {
    private String name;
    private int budget;
    private String[] genres;

    public Film() {}

    public Film(String name, int budget, String[] genres) {
        this.name = name;
        this.budget = budget;
        this.genres = genres;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getBudget() {
        return budget;
    }

    public void setBudget(int budget) {
        this.budget = budget;
    }

    public String[] getGenres() {
        return genres;
    }

    public void setGenres(String[] genres) {
        this.genres = genres;
    }
}

Entfernen Sie die Methodenaufrufe setValues ​​und putValues ​​in onCreate. Erstellen Sie ein neues Objekt der Filmklasse darin und fügen Sie es der Datenbank hinzu:
Film film = new Film("Shawshank redemption",28000000, new String[] {"Drama"});
try {
       DB snappyDB = DBFactory.open(this, "NewFilmDB");
       snappyDB.put("FilmObj",film);
} catch (SnappydbException e) {
       e.printStackTrace();
}


Wir überarbeiten die setValues-Methode:
private void setValues(DB snappyDB) throws SnappydbException {
        TextView filmNameTextView = findViewById(R.id.filmNameTextView),
                 filmBudgetTextView = findViewById(R.id.filmBudgetTextView),
                 genresTextView = findViewById(R.id.genreTextView);

        Film film = snappyDB.getObject("FilmObj", Film.class);
        
        String name = film.getName();
        int budget = film.getBudget();
        String[] genres = film.getGenres();

        filmNameTextView.setText(name);
        filmBudgetTextView.setText(String.valueOf(budget));

        for(int i = 0;i < genres.length;i++) {
            genresTextView.setText(genresTextView.getText() + " " + genres[i]);
        }
}

Rufen Sie setValues ​​in onCreate erneut auf:
try {
        DB snappyDB = DBFactory.open(this, "NewFilmDB");
        setValues(snappyDB);
} catch (SnappydbException e) {
        e.printStackTrace();
}

Wir beginnen und sehen, dass alles funktioniert:
Bild

Schauen wir uns nun einige interessantere SnappyDB-Funktionen an:
1) Die Möglichkeit, nach Schlüsseln nach Präfix zu suchen:
Film film1 = new Film("Green mile",60000000,new String[] {"Drama", "Fantasy"}),
  film2 = new Film("Gentlemen",22000000,new String[] {"Comedy", "Crime"}),
  film3 = new Film("In Bruges",15000000,new String[] {"Comedy", "Crime", "Thriller"});

        try {
            DB snappyDB = DBFactory.open(this, "NewFilmDB");
            snappyDB.put("FilmObj: Green Mile",film1);
            snappyDB.put("FilmObj: Gentlemen",film2);
            snappyDB.put("FilmObj: In Bruges",film3);
            String[] filmKeys = snappyDB.findKeys("FilmObj:");
            //   filmKeys    "FilmObj:"
            //      ,   
            for(int i = 0;i < filmKeys.length;i++) {
                Log.d("film_key: ",  filmKeys[i] + "\n");
            }

            Log.d("film_name: ",  snappyDB.getObject(filmKeys[2],Film.class).getName() + "\n");
            // -  ,    filmKeys

        } catch (SnappydbException e) {
            e.printStackTrace();
 }

Bild
Protokollausgabe

2) DB-Iteration:
try {

            DB snappyDB = DBFactory.open(this, "NewFilmDB");

            for (String[] batch : snappyDB.allKeysIterator().byBatch(1)) {
                //    (batch),     
                for (String key : batch) {
                    Log.d("film",snappyDB.getObject(key,Film.class).getName());
                }
            }
        } catch (SnappydbException e) {
            e.printStackTrace();
}

Ohne die Verwendung von byBatch verfügen Sie nur über einen KeyIterator, der weder Iterator noch Iterable implementiert, sodass Sie ihn nicht in einer Schleife verwenden können.
byBatch (n) erstellt eine BatchIterable, die Iterable und Iterator ist. Im Wesentlichen ruft es nur next (n) für KeyIterator auf, wenn Sie next () dafür aufrufen.
ByBatch sollte jedoch nur mit einer großen Datenmenge verwendet werden. Andernfalls lohnt es sich, findKeys / findKeysBetween zu verwenden.

3) Entfernen eines Elements per Schlüssel:
snappyDB.del("FilmObj: Gentlemen");

Bild
Element gelöscht
4) Schließen und Löschen der Datenbank:
snappyDB.close();
snappyDB.destroy();


5) Finden Sie heraus, ob ein Schlüssel in der Datenbank vorhanden ist:
snappyDB.put("FilmObj: Gentlemen",new Film());
boolean isExist = snappyDB.exists("FilmObj: Gentlemen");// true
snappyDB.del("FilmObj: Gentlemen");
isExist = snappyDB.exists("FilmObj: Gentlemen");//false



Das ist also alles. Sie entscheiden, ob Sie diese Datenbank in Ihren Projekten verwenden möchten. Es ist schnell genug und einfach zu bedienen, aber Sie haben die Wahl. Dies ist nicht die einzige Datenbank für Android. Vielleicht ist eine andere Datenbank besser für Ihr Projekt (Room, SQLite, Realm usw.). Viele Möglichkeiten.

PS: SnappyDB auf GitHub (offizielle Dokumentation dort).
Unterschiede zwischen SQL und NoSQL: 1 , 2
SQL vs Key-Value DB

All Articles