问题
I am learning RxJava2 in android. Can Anyone explain me how can we insert Data into SQLiteDatabase using RxJava2. Here a code sample i am trying to use, but it inserts the data Six Times into the Database;
//OnClick
getCompletableObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getCompletableObserver());
//Observable
private Completable getCompletableObservable(){
return Completable.create(new CompletableOnSubscribe() {
@Override
public void subscribe(CompletableEmitter emitter) throws Exception {
addData();
if(!emitter.isDisposed())
emitter.onComplete();
}
});
}
//Observer
CompletableObserver getCompletableObserver(){
return new CompletableObserver() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onComplete() {
showMessage("Student Added Sucessfully");
}
@Override
public void onError(Throwable e) {
showMessage(e.getMessage()+"");
}
};
}
//Add Method
try {
DatabaseHelper db = new DatabaseHelper(DemoRxJava.this);
db.open();
String c = db.AddData(new Student(random.nextInt(1000)+"",SName.getText().toString(),SContact.getText().toString(),SEmail.getText().toString()));
Log.d("StudentData",c);
db.close();
}catch (Exception e){
}
回答1:
Use Room Persistence library. It is created to simplify interaction with database. It supports wrapping data with RxJava as well as LiveData.
Check the Documentation to get started
Basically you want to create the Entity class that will abstract your table and will represent a single row object. For example this shows user Entity for table named users
and uid as PK.
@Entity(tableName="users")
public class User {
@PrimaryKey
private int uid;
@ColumnInfo(name = "first_name")
private String firstName;
@ColumnInfo(name = "last_name")
private String lastName;
// Getters and setters are ignored for brevity,
// but they're required for Room to work.
}
Then you define your DAO class that will contain your query definitions. You will use object of this interface to make actual queries. Room will make concrete class for you
@Dao
public interface UserDao {
@Query("SELECT * FROM user")
List<User> getAll();
@Query("SELECT * FROM user WHERE uid IN (:userIds)")
List<User> loadAllByIds(int[] userIds);
@Query("SELECT * FROM user WHERE first_name LIKE :first AND "
+ "last_name LIKE :last LIMIT 1")
User findByName(String first, String last);
@Insert
void insertAll(User... users);
@Delete
void delete(User user);
}
Finally you created your database object that you will use to actually query the database. The class is abstract and Room will also create the concrete class for you. It contains methods for creating DAOs and you can name methods anything you want.
@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract UserDao userDao();
}
Now suppose I
AppDatabase db = Room.databaseBuilder(getApplicationContext(),
AppDatabase.class, "databaseName.db").build(); //Most of the time I have used this, it is a Singleton.
List<User> users = db.userDao().getAll();
for(User u : users)
{
Log.d("SQLITE_ROOM_DATA", u.firstName);
}
Here we returned simple List<User>
but Room allows you to wrap them with RxJava Observables like Flowable<List<User>>
or Architecture component livedata LiveData<List<User>>
To use Room you need to add the dependencies to your gradle as follows:
dependencies {
def room_version = "1.1.0" // or, for latest rc, use "1.1.1-rc1"
implementation "android.arch.persistence.room:runtime:$room_version"
annotationProcessor "android.arch.persistence.room:compiler:$room_version"
// optional - RxJava support for Room
implementation "android.arch.persistence.room:rxjava2:$room_version"
// Test helpers
testImplementation "android.arch.persistence.room:testing:$room_version"
}
来源:https://stackoverflow.com/questions/50910101/insert-into-sqlitedatabase-using-rxjava2-in-android