Показать Hibernate Query в JTable - PullRequest
1 голос
/ 09 июня 2009

Я ищу эффективный способ отображения таблицы SQL, запрошенной через Hibernate, в JTable.

    Query q = em.createNamedQuery("Files.findAll");
    List rl = q.getResultList();

Вероятно, было бы предпочтительнее использовать Список, возвращаемый этим (В этом случае это создаст список объектов Файлов (где Файлы - это внутренний класс, не java.io.File)) , но я не буду разборчивым, пока он аккуратен.

У меня есть один ответ, который я разработал ниже, но он не очень хорошо работает. В конечном итоге мне придется написать TableModel, если я буду продолжать идти по этому пути.

Ответы [ 5 ]

4 голосов
/ 09 июня 2009

Есть много и много способов сделать это, но вы ищете что-то, что автоматически определит столбцы или что? Если вы использовали части отражения java, вы можете прочитать аннотации Hibernate, чтобы узнать имена столбцов и заполнить JTable таким образом ...

В противном случае это просто кусок кода, который a. создает JTable и TableModel, и б. заполняет дисплей данными базы данных.

EDIT: Я думаю этот пример может охватить обход дерева аннотаций и их обработку . Специфика - это часть iirc AnnotationProcessorFactory.

РЕДАКТИРОВАТЬ 2: Я также обнаружил, что эта библиотека создана для поиска аннотаций во время выполнения . Один из их примеров - поиск классов Entity в hibernate для создания списка ресурсов - я полагаю, вы могли бы сделать что-то похожее, чтобы найти классы, которые реализуют @column или @basic и т. Д. Это должно позволить вам с помощью отражения довольно легко сделать это, но, как я уже говорил, стандартная библиотека java уже предоставляет возможность обходить дерево аннотаций, чтобы узнать имена столбцов - в этот момент создание JTable из этого должно быть очень простым программным способом.

РЕДАКТИРОВАТЬ 3: Этот код - все это и мешок чипсов! Отсюда вы легко сможете просматривать список карт и извлекать все нужной вам информации, значение, тип его класса, имя поля для заголовков столбцов ... Обратите внимание, что это не так. не особенно безопасно .. Я пропустил весь код ошибки, который я сделал во время тестирования, чтобы он был коротким ...

List<Map> createTable(List queryResults) {
    List<Map> r = new LinkedList<Map>();
    for (Object o : queryResults) {
         r.add(entityMap(o));
    }
    return r;
}

Map entityMap(Object obj) throws Throwable {
    Map m = new HashMap();
    for (Field field : getFields(obj.getClass())) {
        Method method = getMethod(field);
        Object value = method.invoke(obj);
        m.put(field, value);
    }
    return m;
}

List<Field> getFields(Class<?> clazz) {
    List<Field> fields = new LinkedList<Field>();

    for (Field field : clazz.getDeclaredFields()) {
        Column col = field.getAnnotation(Column.class);
        if (col != null)
            fields.add(field);
    }
    return fields;
}

Method getMethod(Field field) throws NoSuchMethodException {
    Class<?> clazz = field.getDeclaringClass();
    String name = "get" + uppercase(field.getName());
    Method method = clazz.getMethod(name);
    return method;
}

String uppercase(String str) {
    return str.substring(0,1).toUpperCase() + str.substring(1);
}
1 голос
/ 15 июня 2009

В ответе ниже я ожидаю, что ваш HQL возвращает не список объектов, а список массивов необходимых свойств, которые вы хотите показать в JTable (то есть, если вы используете так называемые report query ).

В этом случае вы можете написать простой TableModelAdapter, который будет использоваться в качестве TableModel для JTable.

public class TableModelAdapter extends AbstractTableModel{

    private List<Object[]> list;

    public TableModelAdapter(List<Object[]> aList){
        list = aList;
    }
    public int getColumnCount() {
        if (list == null){
            return 0;
        }
        if (list.size() == 0){
            return 0;
        }
        return list.get(0).length;
    }

    public int getRowCount() {
        if (list == null){
            return 0;
        }
        return list.size();
    }

    public Object getValueAt(int row, int column) {
        if (list == null){
            return null;
        }
        return list.get(row)[column];
    }
}

Если вам нужно вернуть список объектов, мы можем изменить свойства примера и пути к пути с помощью отражения вместо массива.

1 голос
/ 15 июня 2009

Вы смотрели на классы org.hibernate.metadata. Они предоставляют вам метаданные о классах и коллекциях. Вы также можете вызвать SessionFactory.getClassMetadata (Class), чтобы получить информацию метаданных для рассматриваемого класса.

0 голосов
/ 19 июня 2009

Сетка данных JIDE предоставляет HibernateTableModel, которая может обеспечить требуемую функциональность, если вы готовы приобрести стороннюю библиотеку.

0 голосов
/ 09 июня 2009

Ну, вот что я сейчас сделал:

//client-side class
public String[][] getFilesArray() {
    List<Files> files = remote.getFiles();
    String[][] x = new String[files.size()][];
    for (int i = 0; i < files.size(); i++) {
        x[i] = files.get(i).getStringArray();
    }
    return x;
}

//DAO class
public String[] getStringArray() {
    return new String[] {
        fileid.toString(),
        name,
        DateFormat.getInstance().format(timestamp),
        status,
        hash
    };
}

public static String[] getColumnNames() {
    return new String[] {
        "Id",
        "Name",
        "Timestamp",
        "Status",
        "Hash"
    };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...