Отображение данных значения атрибута сущности в JTable?

StackOverflow https://stackoverflow.com/questions/1039694

  •  22-07-2019
  •  | 
  •  

Вопрос

Как я могу использовать JTable для отображения и редактирования свойств атрибутов для сущностей, полученных из хранилища сущностей, атрибутов, значений (EAV) (реляционная СУБД)?

Я знаю, что это вопрос с множеством возможных ответов, поэтому ПОЖАЛУЙСТА прежде чем ответить, ознакомьтесь с требованиями, которые у меня есть ниже.

Я обещаю голосовать за ответы, которые покажут, что вы прочитали и поняли все (при условии, что они не совсем глупы).


Пользователь должен иметь возможность:

  1. Фильтрация/поиск объектов по их атрибутам

  2. Выберите, какие атрибуты отображать (в виде столбцов)

  3. Сортировка объектов по выбранным атрибутам

  4. Редактировать значения атрибутов

  5. Выполнять операции с выбранными объектами

  6. (Необязательный) Возможность сохранить вид для последующего использования.


Системные Требования:

  1. Количество объектов:необходимо масштабировать до 100 000+ уникальных объектов

  2. Атрибуты:пользователь может добавлять и определять новые атрибуты, система должна иметь возможность справиться с этим

  3. Базовое хранилище:База данных H2 (уже разработана), общающаяся через JDBC.

  4. Объем памяти:не всё поместится, поэтому как-то надо тянуть из СУБД запросы

  5. Производительность:следует минимизировать количество запросов, необходимых для СУБД (один запрос на атрибут — ОК, и у меня есть форма с 1 запросом на представление таблицы, но это отстой).

  6. Запросы:Для создания списка объектов, соответствующих запросу/фильтру, должен потребоваться ОДИН запрос.В противном случае огромная производительность — отстой.

  7. Повторное использование данных:не нужно повторно запрашивать или пересортировать весь список при добавлении столбца.


Вещи, которые я посмотрел:

  1. Библиотека глазурованных списков

    • Плюсы:

      • Гибкая обработка столбцов
      • Легко реализовать сортировку/фильтрацию объектов
      • Гибкий формат отображения и редактирования столбцов
    • Минусы:

      • Один объект на сущность (если объекты сложные, излишек памяти становится серьезной проблемой с памятью!)
      • Объект, отвечающий за всю функциональность...но объекты должны быть простыми из соображений памяти
      • Как поддерживать выбираемые пользователем столбцы без HashMap для КАЖДОГО объекта сущности?
  2. Расширение AbstractTableModel для сопоставления данных из набора результатов JDBC со строками и столбцами.

    • Плюсы:
      • Разбиение результатов на страницы позволяет избежать проблем с памятью
      • Поиск/фильтрация осуществляется непосредственно в SQL.
      • Удобен для памяти, не нужно создавать объект для каждой строки
    • Минусы:
      • Реализация пользовательских столбцов и сортировки — это головная боль (рендеринг заголовков таблиц, управление столбцами и порядком сортировки и т. д.)!
      • Вероятно, придется также написать собственную JTableColumnModel, и это становится грязным!
      • Приходится много манипулировать SQL, поэтому, если схема БД изменится, придется переписать несколько фрагментов кода!
      • Трудно сохранить информацию об идентификаторе объекта.
  3. ОРМ

    • Плюсы:
      • Предназначен для сопоставления строк БД с объектами.
      • Обеспечивает управление объектами
    • Минусы:
      • НАИЛУЧШЕЕ ВОЗМОЖНОЕ решение для модели сущности-атрибута-значения
      • Придется изучать и писать код ORM в дополнение к коду СУБД и Java!
      • Сущности могут иметь любой количество атрибутов, ORM хорош только со статическими, ограниченными атрибутами объекта.
      • Потерять гибкость/скорость пользовательского SQL.

Есть ли лучший вариант, который я пропустил, или какой-нибудь умный способ упростить глазурованные списки или пользовательскую модель таблицы?

Я уже полностью отказался от ORM как от варианта из-за того, насколько он плохо сочетается с хранилищем EAV.

Это было полезно?

Решение

Я думаю, что лучше всего использовать «Расширение AbstractTableModel с данными карты формы из набора результатов JDBC», потому что

  • Java 6 JTable имеет встроенную поддержку сортировки, поэтому вам не нужно ее реализовывать.
  • Если вы тщательно спроектируете свою модель, вы сможете пережить некоторые изменения в схеме.Четкий код, позволяющий вам легче вносить изменения, если вам нужно.
  • В любом случае вам придется записать изменения.Используйте кнопку «Сохранить», и пакетное обновление может даже улучшить вашу производительность.
  • Вы можете переопределить TableCellEditor, чтобы он предоставлял поле со списком вместо текстового редактора по умолчанию.
  • Не пытайтесь внести все изменения в одну таблицу.Иметь отдельные средства для создания записей и т. д.
  • Вы можете добавлять/удалять столбцы в JTable во время выполнения.Просто fireTableModelChanged() и новый столбец станет видимым.

Редактировать: Я бы сделал одну сумасшедшую вещь: создал собственный компонент, сам выполнил всю отрисовку и выполнил операции редактирования с помощью хорошо расположенных JTextField и JComboBox.

Редактировать2: Судя по вашему комментарию.Сохраните положение выбранного элемента перед вызовом fire...().Кстати, я не думаю, что вызов сбрасывает сортировку или выбор — с этим проблем не было.

Если вы добавите столбец, вы можете просто получить ключевое поле и значения только для нового столбца.Отобразите их в столбце.Затем выполните скрытую полную перезагрузку в фоновом режиме и замените модель на нее, когда она будет завершена.Практически это работает с несколькими наборами результатов одновременно в одной таблице.

Удалить легко, поскольку вы не показываете значения для этого столбца.

Редактировать3:

DefaultRowSorter не так уж и глубок.Он поддерживает таблицу переиндексации ваших записей.Поэтому, когда JTable запрашивает 10-ю строку, сортировщик строк проверяет свою 10-ю запись индексной таблицы и извлекает этот индексный элемент из вашей фактической модели.

Кроме того, если в вашей модели много одинаковых строк, используйте простую карту кэша строк в строки при запросе данных из базы данных.Таким образом, тонны избыточных объектов String можно сразу же GC-d.

Редактировать4:

Я бы запросил новое поле в карте ключа к значению, и моя основная модель содержала бы список карт ключа к значению.Затем я бы использовал реализацию getValue(), которая по запросу возвращает значение либо из основного источника данных, либо из этих дополнительных карт.Я бы искал ключ строки в основной модели и использовал его для получения фактического значения из дополнительных карт.(Кстати.Репутация, полученная за принятые ответы, не подлежит дневному лимиту.)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top