在Android中使用Snappy的键值数据库

SnappyDB-Android的NoSQL键值数据库。这是很容易使用,是一个很好的选择,如果你想在你的项目(更多的细节,使用的数据库NoSQL的版本在这里)。
根据开发人员的说法,在读写操作中,Snappy比SQLite更快:

图片

所以,让我们开始吧。首先,您需要向build.gradle添加依赖项: 现在,让我们直接开始使用数据库本身。 首先,让我们弄清楚如何使用SnappyDB处理原始类型和数组,并保存并获取它们。 为了清楚起见,请创建一个小的标记:

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>

假设我们将电影数据存储在数据库中。

在MainActivity中,我们将创建PutValues方法:
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);
        //       
}

请注意,我们使用SnappyDB的方法应引发SnappydbException。

现在我们编写setValues方法从数据库中获取数据并输出:
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]);
        }
}


在onCreate中调用创建的方法(请确保将它们用try / catch块包围):
@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();
        }
}


我们开始,发现一切都正常工作:
图片

现在让我们弄清楚如何使用我们自己的类和其他复杂类型。
创建一个具有3个字段的Film类:
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;
    }
}

删除onCreate中的setValues和putValues方法调用。在其中创建Film类的新对象,并将其添加到数据库中:
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();
}


我们重做setValues方法:
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]);
        }
}

再次在onCreate中调用setValues
try {
        DB snappyDB = DBFactory.open(this, "NewFilmDB");
        setValues(snappyDB);
} catch (SnappydbException e) {
        e.printStackTrace();
}

我们开始,发现一切正常:
图片

现在让我们看一些更有趣的SnappyDB函数:
1)通过前缀搜索密钥的能力:
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();
 }

图片
日志输出

2)DB迭代:
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();
}

如果不使用byBatch,则只会有一个未实现Iterator或Iterable的KeyIterator,因此无法在循环中使用它。
byBatch(n)创建一个BatchIterable,它是Iterable和Iterator。本质上,当您为其调用next()时,它只是为KeyIterator调用next(n)。
但是byBatch应该仅用于大量数据。否则,值得使用findKeys / findKeysBetween。

3)通过按键删除项目:
snappyDB.del("FilmObj: Gentlemen");

图片
元素已删除
4)关闭和删除数据库:
snappyDB.close();
snappyDB.destroy();


5)找出数据库中是否存在密钥:
snappyDB.put("FilmObj: Gentlemen",new Film());
boolean isExist = snappyDB.exists("FilmObj: Gentlemen");// true
snappyDB.del("FilmObj: Gentlemen");
isExist = snappyDB.exists("FilmObj: Gentlemen");//false



这就是全部。您决定是否在项目中使用此数据库。它足够快且易于使用,但选择是您的。这不是Android的唯一数据库。也许另一个数据库更适合您的项目(Room,SQLite,Realm等)。有很多选择。

PS:GitHub上的SnappyDB(那里的官方文档)。
SQL和NoSQL之间的区别:12
SQL VS键值DB

All Articles