我正在寻找一种有效的方法来显示在JTable中通过Hibernate查询的SQL表。
Query q = em.createNamedQuery("Files.findAll");
List rl = q.getResultList();
最好使用由它返回的List(在这种情况下,它会生成一个Files对象列表(其中Files是一个内部类,不是 java.io.File) ),但只要它很整洁,我就不会挑剔。
我有一个答案,我在下面编写,但这不是很好。如果我继续沿着这条路走下去,我最终还是要为它编写一个TableModel。
答案 0 :(得分:4)
有很多方法可以做到这一点,但是你在寻找能够自动找出列或者什么的东西吗?如果您使用了java反射片,您可以阅读Hibernate注释以找出列名并以这种方式填充JTable ......
否则这只是一段直截了当的代码。创建一个JTable和TableModel,以及b。使用数据库数据填充显示。
编辑: 我认为这个example may cover walking the annotation tree and processing them。具体是AnnotationProcessorFactory部分iirc。
编辑2: 我还发现这个库是built to help lookup annotations at runtime。他们的一个例子是在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 :(得分:1)
您是否看过org.hibernate.metadata类。它们为您提供有关类和集合的元数据信息。您还可以调用SessionFactory.getClassMetadata(Class)来获取相关类的元数据信息。
答案 2 :(得分:1)
在下面的答案中,我希望您的HQL不返回对象列表,而是返回您希望在JTable中显示的必要属性的数组列表(即您正在使用这样调用report queries)。
在这种情况下,您可以编写简单的TableModelAdapter,它将用作JTable的TableModel。
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];
}
}
如果必须返回对象列表,我们可以通过反射而不是数组来更改示例和路径抛出属性。
答案 3 :(得分: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"
};
}
答案 4 :(得分:0)
JIDE Data Grids提供了一个HibernateTableModel,如果您愿意购买第三方库,它可以提供您正在寻找的功能。
答案 5 :(得分:0)
private void DataRetrive() {
DefaultTableModel tbl = (DefaultTableModel) jtblDataRet.getModel();
tbl.setRowCount(0);
try {
// call local method which was opensession
opensession();
if (!session.isOpen()) {
session = Hibernate_ut.getSession().openSession();
tx = session.beginTransaction();
String hQ = "From Student";
Query que = session.createQuery(hQ, Student.class);
List<Student> list = (List) que.list();
for (int i = 0; i < list.size(); i++) {
Vector vt = new Vector();
vt.add(0, list.get(i).getStudentName().toString());
vt.add(1, list.get(i).getStudentAddr().toString());
vt.add(2, list.get(i).getGrade().toString());
vt.add(3, list.get(i).getContact().toString());
tbl.addRow(vt);
}
}
} catch (HibernateException e) {
System.out.println(e);
e.printStackTrace();
tx.rollback();
}
}