如何使用JTable显示&编辑从实体,属性,值(EAV)存储(关系DBMS)检索的实体的属性属性?
我知道这是一个有很多可能答案的问题,所以请在回答之前先查看下面的要求。
我保证将你的阅读和答案投票给答案了解整个事情(只要它们不是完全愚蠢的)。
用户需要能够:
按属性过滤/搜索实体
选择要显示的属性(作为列)
按所选属性对实体进行排序
修改属性值
对所选实体执行操作
(可选)能够保存视图供以后使用。
系统要求:
实体数量:需要扩展到100K +唯一实体
属性:用户可以添加和定义新属性,系统应该能够处理这个
底层存储:H2数据库(已设计),通过JDBC进行通信
内存:并非一切都适合,所以不知何故需要从DBMS查询中提取
性能:应该最小化DBMS所需的查询数量(每个属性一个查询OK,我有一个表格,每个表视图有1个查询,但很糟糕)。
查询:应该需要一个查询来生成与搜索/过滤器匹配的实体列表。否则大规模的表现太糟糕了。
重用数据:添加列时,不必重新查询或重新排序整个列表。
我看过的事情:
Glazed Lists library
优点:
缺点:
扩展AbstractTableModel以将数据从JDBC ResultSet映射到行,列
ORM
我错过了一个更好的选择,还是有一些聪明的方法可以让Glazed Lists或自定义表模型更容易?
我已经完全放弃了ORM作为选项,因为它与EAV存储有多么匹配。
答案 0 :(得分:1)
我认为你最好的选择是'使用来自JDBC ResultSet的表单映射数据扩展AbstractTableModel',因为
编辑:我会做一件疯狂的事情来创建一个自定义组件并自行渲染并使用放置良好的JTextField和JComboBox执行编辑操作。
编辑2:根据您的评论。 在执行fire ...()调用之前保存所选项目的位置。顺便说一句,我认为这个调用不会重置排序或选择 - 没有问题。
如果添加列,则只能获取关键字段和新列的值。在列中显示它们。然后在后台执行隐藏的完全重新加载,并在完成时将模型交换到该模型。这实际上是在一个表中同时从多个ResultSet中工作。
删除非常简单,因为您不显示该列的值。
<强> EDIT3:强>
DefaultRowSorter不是那么深。它为您的记录维护一个重建索引表。因此,当JTable请求第10行时,rowsorter检查索引表的第10个条目,并从实际模型中检索该indexth元素。
此外,如果模型中有许多相同的字符串,则在查询数据库中的数据时,请使用简单的字符串Map to String缓存。这样,大量的冗余String对象就可以立即生成GC-d。
<强> Edit4:强>
我会将新字段查询到值的键映射,并让我的主模型包含键值映射列表。然后我将使用getValue()实现,该实现根据需要从这些附加映射的主数据源返回值。我会从主模型中查找行的键,并使用它来从其他映射中检索实际值。 (顺便说一下,从已接受的答案中获得的声望不受每日限制的限制。)