gpt4 book ai didi

java - 从数据库填充 DefaultMutableTreeNode

转载 作者:行者123 更新时间:2023-11-29 05:58:17 24 4
gpt4 key购买 nike

我是 Java 的新手,我想创建一个包含 Map 对象的 DefaultMutableTreeNode 类。

我写了一个 TreeNodeMap 类,它继承自更通用的 TreeNode 类,而后者又继承自 DefaultMutableTreeNode。

TreeNodeMap 类包含populate 方法,该方法采用相当长的参数列表。我计划通过将其中一些参数转换为单个对象并重载方法来提高方法的可读性,这样我就不必在第一次调用时传递一组空值(递归)。

注意:如果您不喜欢我对方法的详细解释,请直接从这里跳到代码

最初我创建了一个只包含子节点但不包含数据的空节点,这是 ROOT。这个想法是有一个方法允许调用者传递任何带有“field_id”、“field_label”、“parent_id”列的查询。在初始调用时,查询通过 Where 子句传递,其中“parent_id 为空”,因此获得没有父节点的所有节点。所有这些节点都添加到 ROOT 节点。在遍历结果集时,调用每个节点的 populate 方法,现在传递一个“Where 子句”,其中 parent_id = [当前节点 id] 因此获得该节点的所有子节点。这将递归发生,直到创建了具有层次结构的所有节点。

代码(请记住,我是 JAVA 的新手,因此欢迎任何反馈)

public void populate( boolean isRoot, String parentFieldId, String parentFieldLabel, String childFieldId, String childFieldLabel, 
int parentId, String tableName, String whereClause, String orderByClause, String additionalColumns, List<Map<String, String>> queryParams) throws SQLException, Exception{
ResultSet rs = null;
Connection con = null;
PreparedStatement ps = null;
try{

DBConnection dbConnection = new DBConnection("localhost", 3306, "root", "password", "test", DBDrivers.DBTYPE_MYSQL);
con = dbConnection.getConnection();

String treeNodeSql = "Select " + parentFieldId + ", " + parentFieldLabel +
", " + childFieldId + ", " + childFieldLabel;
if(additionalColumns != null && additionalColumns.trim().length() > 0)
treeNodeSql += " ," + additionalColumns;

treeNodeSql += " From " + tableName + " WHERE 1=1";

if(whereClause != null && whereClause.trim().length() > 0 ){
treeNodeSql += " AND " + whereClause;
}

if(isRoot){
treeNodeSql += " AND " + parentFieldId + " is null";
}else{
if(parentFieldId == null || parentFieldId.trim().length() == 0)
throw new Exception(" The populate() method requires a parentId when isRoot is false.");
treeNodeSql += " AND " + parentFieldId + " = ?";
}
//order clause append
if(orderByClause != null && orderByClause.trim().length() > 0)
treeNodeSql += " " + orderByClause;

//prepare statement
ps = con.prepareStatement(treeNodeSql);
int ixParam = 0;

for(Map qParam : queryParams){
if(qParam.get("datatype") == "int"){
ps.setInt(++ixParam, Integer.parseInt((String) qParam.get("value")));
}else if(qParam.get("datatype") == "string"){
ps.setString(++ixParam, (String) qParam.get("value"));
}
}

out.println(treeNodeSql);
if(parentId > 0){
ps.setInt(queryParams.size()+1, parentId);
}
rs = ps.executeQuery();

while(rs.next()){
HashMap<String, Object> childNodeData = new HashMap<String, Object>(4);
childNodeData.put("parentFieldId", parentFieldId);
childNodeData.put("parentFieldIdValue", Integer.toString(rs.getInt(parentFieldId)));
childNodeData.put("parentFieldLabel", parentFieldLabel);
childNodeData.put("parentFieldLabelValue", rs.getString(parentFieldLabel));
childNodeData.put("childFieldId", childFieldId);
childNodeData.put("childFieldIdValue", Integer.toString(rs.getInt(childFieldId)));
childNodeData.put("childFieldLabel", childFieldLabel);
childNodeData.put("childFieldLabelValue", rs.getString(childFieldLabel));

out.println("parentId: " + rs.getInt(parentFieldId)
+ ", parentLabel: " + rs.getString(parentFieldLabel)
+ ", childId: " + rs.getInt(childFieldId)
+ ", childLabel: " + rs.getString(childFieldLabel));
TreeNodeMap childNode = new TreeNodeMap(childNodeData);
this.add(childNode);
childNode.populate(false, parentFieldId, parentFieldLabel, childFieldId, childFieldLabel, rs.getInt(childFieldId), tableName, whereClause, orderByClause, additionalColumns, queryParams);
}
}catch(SQLException e){
throw e;

} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
out.println(e.getCause());
out.println(e.getMessage());
e.printStackTrace();
throw e;
}finally {
try { rs.close(); } catch (Exception e) { }
try { ps.close(); } catch (Exception e) { }
try { con.close(); } catch (Exception e) { }
}
}

对该方法的初始调用如下所示:

treeNode.populate(true, "supervisor_id", "supervisor", "employee_id", "employee", 0, "vw_employee", null, null, null, queryParams);

我看到这种方法的问题是数据库将被查询 X 次,并且对于大数据集,我认为这会导致一些问题。我也为每个查询打开一个连接!因此,我考虑过在方法创建后将其传递给方法(在递归调用中),但我不确定如何适本地关闭它。我可以写一个条件来检查节点是否是 ROOT,然后关闭连接,但是如果代码在这期间失败了会发生什么。

最后是我的问题:1-解决这个问题的最佳方法是什么?2-我是否应该传递连接以便在树的填充期间只有一个连接保持打开状态?如果是,那么我该如何正确关闭它。3- 我是否应该将结果集缓存到 ArrayList 中并改用它?

最佳答案

您对性能的担忧可能是有道理的。相反,

  1. 实现 TreeModel ,如图所示 FileTreeModel .这样,只需要查询可见的节点。有一个相关的例子 here .

  2. 通过 javax.sql.DataSource , 而不是 Connection .

  3. 你的类(class)implements TreeModel可以封装任何缓存的数据,但也提供一些方法来更新陈旧的条目。显示缓存值后,考虑使用 SwingWorker刷新模型,如图所示here .而不是 List<Record> , 你可能想看看 Map<PrimaryKey, Record> .

关于java - 从数据库填充 DefaultMutableTreeNode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11175233/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com