Отображение данных из столбцов таблицы SQLite, один из которых содержит массив - PullRequest
1 голос
/ 05 июня 2019

Мне удалось получить таблицу SQLite только с первым элементом массива и поместить его в TextView пользовательского интерфейса. Не удалось получить все элементы массива. Из каждого из остальных столбцов возвращается одно значение.

JSON анализируется и передается в виде пригодного для обработки ArrayList во фрагмент, где он представлен в списке. Нажатие на элемент списка направляет к другому фрагменту, где представлены все детали элемента.

Я пытался написать цикл for, который возвращает строки в массиве в TextView, но условие i < genresList.size() всегда ложно. Я попытался использовать цикл while, но он возвращает только первый элемент списка. Различные способы, которые я нашел в интернете, не сработали.

Спасибо.

Парсинг и вставка в SQLite

private void parseJsonAndInsertToSQLIte(SQLiteDatabase db) throws JSONException {
        // parsing the json
        String jsonString = getJsonFileData();
        JSONArray moviesArray = new JSONArray(jsonString);
        ContentValues insertValues;

        for (int i = 0; i < moviesArray.length(); i++) {

            JSONObject jsonObject = moviesArray.getJSONObject(i);

            String title = jsonObject.getString("title");
            String imageUrl = jsonObject.getString("image");
            String rating = jsonObject.getString("rating");
            String releaseYear = jsonObject.getString("releaseYear");

            JSONArray genresArray = jsonObject.getJSONArray("genre");
            List<String> genres = new ArrayList<>();
            for (int k = 0; k < genresArray.length(); k++) {
                genres.add(genresArray.getString(k));
            }

            insertValues = new ContentValues();

            insertValues.put(Movie.TITLE, title);
            insertValues.put(Movie.IMAGE_URL, imageUrl);
            insertValues.put(Movie.RATING, rating);
            insertValues.put(Movie.RELEASE_YEAR, releaseYear);
            for (int k = 0; k < genresArray.length(); k++) {
                insertValues.put(Movie.GENRE, genres.get(k));
            }
            Log.i(TAG, "insertValues: " + genresArray);

            long res = db.insert(TABLE_NAME, null, insertValues);

            Log.i(TAG, "parsed and inserted to sql - row: " + res);
        }
    }

Информация о товаре Фрагмент

public class MovieDetailsFragment extends Fragment{

... variables declarations come here...

    @Nullable
    @Override
    public View onCreateView(@NotNull LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_details_movie, container, false);

        Context context = getActivity();

        Bundle idBundle = getArguments();
        if (idBundle != null) {
            movieId = getArguments().getInt("id");
        }

        getDatabase = new GetDatabase(context);
        getDatabase.open();
        Cursor cursor = getDatabase.getMovieDetails(movieId);

... more irelevant code comes here...

        titleView = rootView.findViewById(R.id.movieTtlId);
        ratingView = rootView.findViewById(R.id.ratingId);
        releaseYearView = rootView.findViewById(R.id.releaseYearId);
        genreView = rootView.findViewById(R.id.genreID);

        String titleFromSQLite = cursor.getString(cursor.getColumnIndex(Movie.TITLE));
        String ratingFromSQLite = cursor.getString(cursor.getColumnIndex(Movie.RATING));
        String releaseYearFromSQLite = cursor.getString(cursor.getColumnIndex(Movie.RELEASE_YEAR));

        String genreFromSQLite;
        if(cursor.moveToFirst()) {
            do {
                genreFromSQLite = cursor.getString(cursor.getColumnIndex(Movie.GENRE));
                genres.add(genreFromSQLite);
            } while (cursor.moveToNext());
        }
        else{
            genreFromSQLite = cursor.getString(cursor.getColumnIndex(Movie.RELEASE_YEAR));
        }
        getDatabase.close();

//more irelevant code comes here

        genreView.setText(genreFromSQLite);
        genreView.setFocusable(false);
        genreView.setClickable(false);

        return rootView;
    }
}

Метод, который возвращает таблицу из SQLite:

    public ArrayList<Movie> getMovies() {
        String[] columns = {
                Movie.ID,
                Movie.TITLE,
                Movie.IMAGE_URL,
                Movie.RATING,
                Movie.RELEASE_YEAR,
                Movie.GENRE
        };

        // sorting orders
        String sortOrder =
                Movie.RELEASE_YEAR + " ASC";
        ArrayList<Movie> moviesList = new ArrayList<>();

        Cursor cursor = db.query(TABLE_NAME, //Table to query
                columns,
                null,
                null,
                null,
                null,
                sortOrder);

        if (cursor.moveToFirst()) {
            do {
                Movie movie = new Movie();
                movie.setMovieId(Integer.parseInt(cursor.getString(cursor.getColumnIndex(Movie.ID))));
                movie.setTitle(cursor.getString(cursor.getColumnIndex(Movie.TITLE)));
                movie.setImageUrl(cursor.getString(cursor.getColumnIndex(Movie.IMAGE_URL)));
                movie.setRating(cursor.getDouble(cursor.getColumnIndex(Movie.RATING)));
                movie.setReleaseYear(cursor.getInt(cursor.getColumnIndex(Movie.RELEASE_YEAR)));

                List<String> genreArray = new ArrayList<>();
                while(cursor.moveToNext()){
                    String genre = cursor.getString(cursor.getColumnIndex(Movie.GENRE));
                    genreArray.add(genre);
                }

                movie.setGenre(Collections.singletonList(String.valueOf(genreArray)));

                // Adding a movie to the list
                moviesList.add(movie);

            } while (cursor.moveToNext());
        }
        Log.d(TAG, "The movies list from sqlite: " + moviesList);
        cursor.close();
        db.close();

        return moviesList;
    }

1 Ответ

1 голос
/ 05 июня 2019

Я считаю, что ваша проблема с: -

        for (int k = 0; k < genresArray.length(); k++) {
            insertValues.put(Movie.GENRE, genres.get(k));
        }

Это приведет к тому, что будет вставлено только последнее значение в цикле, поскольку имя ключа / столбца (первый параметр позиции) не изменится (и, вероятно, не сможет, поскольку у вас есть только один столбец).

Вы можете использовать: -

        StringBuilder sb = new StringBuilder();
        for (int k = 0; k < genresArray.length(); k++) {
            if (k > 0) {
                sb.append(",");
            }
            sb.append(genres.get(k));
        }
        insertValues.put(Movie.GENRE, sb.toString());
  • Обратите внимание, что приведенный выше код является принципиальным кодом. Он не был протестирован или запущен и поэтому может содержать ошибки.

Это вставит все данные в виде CSV в столбец GENRE.

НО это не очень хороший способ использования баз данных. Было бы намного лучше, если бы жанр был отдельной таблицей и, вероятно, использовалась таблица сопоставления (но это должен быть другой вопрос).

Это также вызовет у вас проблемы: -

if (cursor.moveToFirst()) {
            do {
                Movie movie = new Movie();
                movie.setMovieId(Integer.parseInt(cursor.getString(cursor.getColumnIndex(Movie.ID))));
                movie.setTitle(cursor.getString(cursor.getColumnIndex(Movie.TITLE)));
                movie.setImageUrl(cursor.getString(cursor.getColumnIndex(Movie.IMAGE_URL)));
                movie.setRating(cursor.getDouble(cursor.getColumnIndex(Movie.RATING)));
                movie.setReleaseYear(cursor.getInt(cursor.getColumnIndex(Movie.RELEASE_YEAR)));

                List<String> genreArray = new ArrayList<>();
                while(cursor.moveToNext()){
                    String genre = cursor.getString(cursor.getColumnIndex(Movie.GENRE));
                    genreArray.add(genre);
                }

                movie.setGenre(Collections.singletonList(String.valueOf(genreArray)));

                // Adding a movie to the list
                moviesList.add(movie);

        } while (cursor.moveToNext());

То есть вы перемещаетесь в первую строку курсора, извлекаете некоторые данные MoveieId, Title ... ReleaseYear.

Тогда

a) если есть какие-либо другие строки, которые вы перемещаете к следующей (что будет для другого фильма) и к следующей, пока вы, наконец, не достигнете последней строки, добавляя элементы в genreArray.

или

b) Если в Cursor есть только одна строка, то в GenreArray массив пуст.

Затем вы добавляете единственный фильм в список movieList и возвращаетесь.

1 ход (строка) в Курсоре будет существовать для каждого фильма, и в каждом фильме будет только 1 столбец ЖАНР. Вы должны извлечь данные из этого столбца, а затем разбить данные в genreArray без перемещения (см. Предыдущее исправление, которое создаст CSV (обратите внимание, что это может привести к ошибкам, если данные содержат запятые)).

ЕСЛИ вы использовали предыдущее исправление и сохранили несколько жанров в формате CSV, то вы можете использовать: -

if (cursor.moveToFirst()) {
            do {
                Movie movie = new Movie();
                movie.setMovieId(Integer.parseInt(cursor.getString(cursor.getColumnIndex(Movie.ID))));
                movie.setTitle(cursor.getString(cursor.getColumnIndex(Movie.TITLE)));
                movie.setImageUrl(cursor.getString(cursor.getColumnIndex(Movie.IMAGE_URL)));
                movie.setRating(cursor.getDouble(cursor.getColumnIndex(Movie.RATING)));
                movie.setReleaseYear(cursor.getInt(cursor.getColumnIndex(Movie.RELEASE_YEAR)));
                List<String> genreArray = new List<>(Arrays.asList((cursor.getString(cursor.getColumnIndex(Movie.GENRE))).split(",",0)));

                movie.setGenre(Collections.singletonList(String.valueOf(genreArray)));

                // Adding a movie to the list
                moviesList.add(movie);

        } while (cursor.moveToNext());
  • Обратите внимание, что приведенный выше код является принципиальным кодом. Он не был протестирован или запущен и поэтому может содержать ошибки.
...