База данных не заполняется или заполняется не правильно в android
была следующая задача.Получить json данные с сервера и записать их в локальную бд. Данные пришли,создаю List с пришедшими объектами(фильмами), все хорошо.Как только пытаюсь записать их в бд, они записываются , но объектов становится больше,чем нужно(у меня 6 фильмов) + везде только значения последнего фильма( на всех строках и ячейках бд)
Код
FragmentFilm
public class FragmentFilm extends Fragment {
private View rootView;
private RecyclerView recyclerView;
private List<FilmItem> filmItemList;
private FilmAdapter filmAdapter;
private DBHelper dbHelper ;
SQLiteDatabase database;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_main, container, false);
initUi();
return rootView;
}
private void initUi() {
filmItemList = new ArrayList<>();
dbHelper = new DBHelper(getContext());
database = dbHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
RecyclerView recyclerView = rootView.findViewById(R.id.recyclerViewFilm);
recyclerView.setLayoutManager( new LinearLayoutManager(getContext()));
recyclerView.setAdapter(new FilmAdapter(getContext(),filmItemList, (FilmAdapter.FilmAdapterEvents) getActivity()));
MovieApp.getInstance().movieService.getMovies().enqueue(new Callback<List<FilmJson>>() {
@Override
public void onResponse(Call<List<FilmJson>> call, Response<List<FilmJson>> response) {
if(response.isSuccessful()){
List<FilmJson> filmJsonList = response.body();
filmItemList.clear();
for(FilmJson filmJson: filmJsonList){
filmItemList.add(new FilmItem(filmJson));
}
for(int i = 0; i < filmItemList.size();i++){
contentValues.put(DBHelper.FILM_TITLE,filmItemList.get(i).getTitle());
contentValues.put(DBHelper.FILM_FAV_STATUS,filmItemList.get(i).getFav_status());
contentValues.put(DBHelper.FILM_DESCRIPTION,filmItemList.get(i).getDescription());
contentValues.put(DBHelper.FILM_IMG,filmItemList.get(i).getImg());
Log.d("FilmList",filmItemList.get(i).getTitle());
}
recyclerView.getAdapter().notifyDataSetChanged();
database.insert(DBHelper.DATABASE_NAME,null,contentValues);
Cursor cursor = database.query(DBHelper.DATABASE_NAME,null,null,null,null,null,null);
if(cursor.moveToFirst()){
int titleID = cursor.getColumnIndex(DBHelper.FILM_TITLE);
do{
Log.d("Cursor","title" + cursor.getString(titleID));
} while (cursor.moveToNext());
} else {
cursor.close();
}
dbHelper.close();
}
}
@Override
public void onFailure(Call<List<FilmJson>> call, Throwable t) {
t.printStackTrace();
}
});
}
}
DbHelper
public class DBHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "FilmBD";
public static final String KEY_ID = "_id";
public static final String FILM_TITLE = "title";
public static final String FILM_FAV_STATUS = "favStatus";
public static final String FILM_DESCRIPTION = "description";
public static final String FILM_IMG = "img";
public DBHelper(@Nullable Context context) {
super(context, DATABASE_NAME, null , DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + DATABASE_NAME + " (" +
KEY_ID + " integer primary key," + FILM_TITLE + " text,"
+ FILM_FAV_STATUS + " integer," + FILM_DESCRIPTION + " text," +
FILM_IMG + " text" + ")");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists " + DATABASE_NAME);
onCreate(db);
}
}
Логи на примере получения title
В массиве объектов FilmItem,куда были записаны пришедшие данные
08-04 18:11:15.016 4381-4381/com.example.filmapp D/film: Alice's Adventures in Wonderland
08-04 18:11:15.016 4381-4381/com.example.filmapp D/film: Iron Man 2
08-04 18:11:15.016 4381-4381/com.example.filmapp D/film: Avengers
08-04 18:11:15.016 4381-4381/com.example.filmapp D/film: Avatar
08-04 18:11:15.016 4381-4381/com.example.filmapp D/film: Shawshank redemption
08-04 18:11:15.016 4381-4381/com.example.filmapp D/film: The Green Mile
Когда пытаюсь из этого массива добавить в бд
08-04 18:23:25.652 4646-4646/com.example.filmapp D/Cursor: titleThe Green Mile
08-04 18:23:25.652 4646-4646/com.example.filmapp D/Cursor: titleThe Green Mile
08-04 18:23:25.652 4646-4646/com.example.filmapp D/Cursor: titleThe Green Mile
08-04 18:23:25.652 4646-4646/com.example.filmapp D/Cursor: titleThe Green Mile
08-04 18:23:25.652 4646-4646/com.example.filmapp D/Cursor: titleThe Green Mile
08-04 18:23:25.652 4646-4646/com.example.filmapp D/Cursor: titleThe Green Mile
08-04 18:23:25.652 4646-4646/com.example.filmapp D/Cursor: titleThe Green Mile
08-04 18:23:25.652 4646-4646/com.example.filmapp D/Cursor: titleThe Green Mile
08-04 18:23:25.652 4646-4646/com.example.filmapp D/Cursor: titleThe Green Mile
08-04 18:23:25.652 4646-4646/com.example.filmapp D/Cursor: titleThe Green Mile
08-04 18:23:25.652 4646-4646/com.example.filmapp D/Cursor: titleThe Green Mile
08-04 18:23:25.653 4646-4646/com.example.filmapp D/Cursor: titleThe Green Mile
08-04 18:23:25.653 4646-4646/com.example.filmapp D/Cursor: titleThe Green Mile
08-04 18:23:25.653 4646-4646/com.example.filmapp D/Cursor: titleThe Green Mile
08-04 18:23:25.653 4646-4646/com.example.filmapp D/Cursor: titleThe Green Mile
По хорошему, нужно сразу пришедшие данные записать в бд из filmJsonList, но ситуация там в точности такая же.Ошибок никаких не вылетает в логах.
Ответы (2 шт):
ContentValues - это по сути обычная ArrayMap, то есть коллекция ключ - значение (не список). Вы в цикле постоянно перезаписываете по одним и тем же ключам разные значения, пока в конце не остаются последние значения списка (Green Mile), которые вы и помещаете в базу данных. Попробуйте помещать в базу данных значение contentValues в конце каждой итерации цикла.
for(int i = 0; i < filmItemList.size();i++){
contentValues.put(DBHelper.FILM_TITLE,filmItemList.get(i).getTitle());
contentValues.put(DBHelper.FILM_FAV_STATUS,filmItemList.get(i).getFav_status());
contentValues.put(DBHelper.FILM_DESCRIPTION,filmItemList.get(i).getDescription());
contentValues.put(DBHelper.FILM_IMG,filmItemList.get(i).getImg());
Log.d("FilmList",filmItemList.get(i).getTitle());
database.insert(DBHelper.DATABASE_NAME,null,contentValues);
}
Используйте Room
dependencies {
def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
}
В вашей сущности задайте полю аннотацию
@PrimaryKey(autoGenerate = true)
private Long id = 0
В dao классе задайте
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Data data);
OnConflictStrategy используется для выбора действия при конфликте записи в таблицу. Room вам очень поможет, удачи!