Как из репозитория сделать insert в бд room
в репозитории выполняю запрос ретрофитом, не могу разобраться как сделать запись в бд room
класс репозитория
public class UserRepository {
final String TAG ="myLog";
private String Name;
private String LastName;
private String Birthday;
private String Avatr_url;
private int number;
private UserDao mUserDao;
private LiveData<User> AllUser;
private RetrofitApi retrofitApi;
private UserRepository userRepository;
public UserRepository getInstance(){
if(userRepository == null){
userRepository = new UserRepository();
}
return userRepository;
}
public UserRepository(){
retrofitApi = RetrofitService.cteateService(RetrofitApi.class);
}
public UserRepository(Application application){
Database65 db = Database65.getDatabase65(application);
mUserDao = db.userDao();
AllUser = mUserDao.getAll();
retrofitApi = RetrofitService.cteateService(RetrofitApi.class);
}
public LiveData<User> getAllUser(){
return AllUser;
}
public MutableLiveData<Response> getNews(){
MutableLiveData<Response> newsData = new MutableLiveData<>();
retrofitApi.example()
.enqueue(new Callback<Example>() {
@Override
public void onResponse(Call<Example> call, retrofit2.Response<Example> response) {
Example example = response.body();
int num = example.response.size();
for (int i =0; i< num; i++){
number = i;
// Log.d(TAG, String.valueOf(number));
Name = example.response.get(i).fName;
LastName = example.response.get(i).lName;
Birthday = example.response.get(i).birthday;
Avatr_url = example.response.get(i).avatrUrl;
/* int siz = example.response.get(i).specialty.size();
for (int j = 0; j < siz; j++){
Specialty[i] = example.response.get(i).specialty.get(j).name;
SpecialtyId[i] = String.valueOf(example.response.get(i).specialty.get(j).specialtyId);
}*/
}
}
@Override
public void onFailure(Call<Example> call, Throwable t) {
}
});
return newsData;
}
}
класс базы данных
@Database(entities = {User.class},version = 1,exportSchema = false)
public abstract class Database65 extends RoomDatabase {
public abstract UserDao userDao();
private static volatile Database65 INSTANCE;
private static final int NUMBER_OF_THREADS = 4;
public static final ExecutorService databaseWrieExecutor =
Executors.newFixedThreadPool(NUMBER_OF_THREADS);
public static Database65 getDatabase65(final Context context){
if(INSTANCE == null) {
synchronized (Database65.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
Database65.class,"database")
.addCallback(sRoomDatabaseCallback)
.build();
}
}
}
return INSTANCE;
}
private static RoomDatabase.Callback sRoomDatabaseCallback = new
RoomDatabase.Callback() {
@Override
public void onOpen(@NonNull SupportSQLiteDatabase db){
super.onOpen(db);
databaseWrieExecutor.execute(()->{
/* UserDao dao = INSTANCE.userDao();
User user = new User(1,"Вася", "петров",
"12.03.2019", "fsfds");
dao.insertAll(user);*/
});
}
};
}
класс вьюмодель
public class UserViewModel extends AndroidViewModel {
private MutableLiveData<Response> mutableLiveData;
private Response response;
private UserRepository userRepository;
private LiveData<User> AllUser;
public UserViewModel(Application application){
super(application);
userRepository = new UserRepository(application);
AllUser = userRepository.getAllUser();
}
public void init(){
if (mutableLiveData != null){
return;
}
userRepository = userRepository.getInstance();
mutableLiveData = userRepository.getNews();
}
public LiveData<User> getAllUser(){
return AllUser;
}
}
класс Dao
@Dao
public interface UserDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAll(User user);
@Update
void updateAll(User user);
@Delete
void deleteAll(User user);
@Query("SELECT * FROM user")
LiveData<User> getAll();
@Query("SELECT*FROM user WHERE id = :id")
LiveData<User> getNam(int id);
}
Ответы (2 шт):
Вам приходит класс Example
Example example = response.body();
А вам нужно воткнуть User
Вы просто делаете что то типа
User user = new User(example.Id, example.name )
И дальше инсертите как обычно
А если это список , то проходите по нему циклом
что то вроде
for (i in example.indices) {
val id = example[i].id
val name = example[i].name
val item = Item (
id, name
)
database.insert(item)
}
Под рукой был пример на котлине но тут все понятно и
Вообще это делается очень просто. Есть репозиторий который знает о существовании БД и Сущности, отвечающей за сеть (могут быть и другие если таковые имеются в вашем приложении). Репозиторий получает данные из сети, отдает их вашей ViewModel и сам сохраняет их в БД.
У вас есть некая ошибка в том как вы пытаетесь получить данные из сети. Она заключается в том, что вы хотите вернуть результат синхронно, но сама по себе операция сетевого запроса должна быть асинхронной. Скорее всего в вашем случае вам всегда будет возвращаться пустой список.
Почему? Потому что вы отправляете запрос в сеть и не дожидаясь его возвращаете значение. Т.к. програма не будет ждать вашего колбека. Обрабатывать результат вы должны внутри onResponse() или onFailure(), а значит вы не можете вернуть просто так список ваших данных.
Решение:
Самый простой вариант - Вы можете возвращать из вашего
getNews()не список, а колбек и обрабатывать его в вашей VM. И оттуда же вonResponse()сохранять их в БД. Из минусов вам в репозитории придется иметь какой-то метод для сохранения в БД (Если он будет где-то юзаться отдельно, то норм, если же нет, то получится что будет немного теряться смысл репозитория.Второй вариант это подписать вашу VM на репозиторий используюя паттерн Observer. Так VM ничего не нужно будет знать о каких-то сохранениях и вся логика останется в репо. Флоу такой:
- При создании VM вы подписываетесь на репо.
- Отправляете в репо ваш запрос
getNews(). - Репо получает ответ и в
onResponse()он сохраняет в БД ваши данные и оповещает подписчиков (в вашем случае VM) о том что данные получены. - VM получает уведомление и обрабатывает эти данные.
Ну и последний вариант использовать RX Java, там вы можете всю эту логику вынести в цепочку запросов. Если же вы решите использовать Kotlin, стоит посмотреть в сторону корутин.