2009-06-08 2 views
1

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

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

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

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

ответ

4

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

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

EDIT: I описание товара это example may cover walking the annotation tree and processing them. Специфика - это часть AnnotationProcessorFactory iirc.

EDIT 2: Я также нашел эту библиотеку, которая является built to help lookup annotations at runtime. Один из их примеров - это поиск классов Entity в hibernate для создания списка ресурсов. Я полагаю, вы могли бы сделать что-то похожее, чтобы найти классы, которые реализуют @column или @basic и т. Д. Это должно позволить вам через отражение довольно легко сделать это, но, как я уже сказал, стандартная библиотека java уже предоставляет возможность ходить по дереву аннотаций, чтобы узнать имена столбцов - в этот момент создание JTable из этого должно быть очень легко сделать программным способом.

EDIT 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); 
} 
+0

Было бы неплохо, если бы он автоматически определял столбцы. Я заметил, что я могу выполнить List.toArray(), а затем присоединить toArray() к классу Files. Кажется беспорядочным. Настройка отражения может быть разумной. –

0

Ну, вот что я в конечном итоге делает сейчас:

//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" 
    }; 
} 
1

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

1

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

В этом случае вы можете написать простой 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]; 
    } 
} 

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

+0

Вкратце, все прямо сейчас возвращается как объект. Я решительно избегала размышлений до сих пор, я спрашиваю, как вы это сделаете. –

+0

Секрет в запросе отчета Hibernate. Он работает только с HQL и создает для вас не целый объект, а массив запрашиваемых свойств. И если вы спросите их .list(), вы получите список , который использовался в примере. – FoxyBOA

0

JIDE Data Grids содержит HibernateTableModel, который может обеспечить функциональность, которую вы ищете, если вы с удовольствием покупаете стороннюю библиотеку.

Смежные вопросы